Forum: Mikrocontroller und Digitale Elektronik Pointer auf Array


von Ingo (Gast)


Lesenswert?

Hallo,

ich habe eine Frage:

Ich habe ein Array.
1
#define SIZE_OF_ARRAY 256
2
Array[SIZE_OF_ARRAY];

Dieses befülle ich Testweise:
1
for (unsigned int i = 0; i < SIZE_OF_ARRAY; i++){
2
 Array[y] = y+1;    // Letzte Stelle läuft über, gewollt
3
}
Jetzt möchte ich einer Funktion, dieses Array übergebem:
1
void Fkt (int* pArray)
2
{
3
  /* Hier wird einmal der Arrayindex gebraucht und der Inhalt des Feldes*/
4
5
}
6
7
Fkt (&Array[x]);


Ich bin aber zu blöde und mein C-Buch hilft nicht weiter.
1
printf ("\n%2d", *pArray%256);
liefert den Wert, aber warum zur Hölle %256 (durch probieren gefunden)!
1
printf ("\n%2d", (int)pArray);
liefert die Speicheradresse des Arrays
1
printf ("\n%2d", (int)&pArray);
liefert die Speicheradresse des Pointers

Wie komme ich auf den Array Index und wie auf den Inhalt?
Warum %256?


Ich blick grad nicht durch, wäre schön wenn mir jemand helfen könnte.



Ingo

von Peter II (Gast)


Lesenswert?

Ingo schrieb:
> Wie komme ich auf den Array Index und wie auf den Inhalt?

geht gar nicht, du musst ihn mit übergeben

void Fkt (int* pArray, int index )
{
   pArray[index] = 2;
}


#define SIZE_OF_ARRAY 256
int Array[SIZE_OF_ARRAY];

Fkt( Array, 2 );

von Ingo (Gast)


Lesenswert?

Aber der Pointer steht doch stellvertretend für den Index oder nicht!?

von Daniel (Gast)


Lesenswert?

Geht schon, wenn Array global ist:

#define SIZE_OF_ARRAY 256
int Array[SIZE_OF_ARRAY];

void Fkt(int* pArray)
{
   index = pArray - Array;
}

Fkt(&Array[index]);

von Peter II (Gast)


Lesenswert?

Ingo schrieb:
> Aber der Pointer steht doch stellvertretend für den Index oder nicht!?

nein macht er nicht. Wenn du nur einen Wert vom Array braucht dann geht 
es.

void Fkt (int* wert )
{
   *wert = 2;
}


#define SIZE_OF_ARRAY 256
int Array[SIZE_OF_ARRAY];

Fkt( &Array[2] );


aber dann kennst du den index nicht.

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:


> Wie komme ich auf den Array Index und wie auf den Inhalt?

Die Frage ist eigentlich: Wozu brauchst du dieses konkret?

Denn ...

> Jetzt möchte ich einer Funktion, dieses Array übergebem:
> void Fkt (int* pArray)
> {
>   /* Hier wird einmal der Arrayindex gebraucht und der Inhalt des Feldes*/
>
> }
>
> Fkt (&Array[x]);

...
die Funktion hat keine Möglichkeit festzustellen, was mit diesem 
Pointer, den sie bekommt, los ist. Alles was sie weiß, ist:
Ich kriege einen Pointer auf einen int
1
void Fkt( int* pIntWert )
2
{
3
  ...
4
}

Ob dieser Pointer jetzt auf einen einsamen int zeigt ...
1
int main()
2
{
3
  int i;
4
5
  Fkt( &i );
6
}

... oder ob dieser int Teil einer Struktur ist ...
1
struct check
2
{
3
  int a;
4
  int b;
5
}
6
7
int main()
8
{
9
  struct check myVar;
10
11
  Fkt( &(myVar.b) );
12
}

... ob dieser int durch eine Speicherallokierung entstanden ist ...
1
int main()
2
{
3
  int * pAlloc = malloc( 1 * sizeof(int) );
4
5
  Fkt( pAlloc );
6
}

ob dieser int Teil eines Arrays ist
1
int main()
2
{
3
  int Werte[5];
4
5
  Fkt( &Werte[3] );
6
}

... oder ob dieser Pointer eventuell sogar auf den ersten int eines 
Arrays zeigt und so stellvertretend für das ganze Array steht ...
1
int main()
2
{
3
  int Werte[5];
4
5
  Fkt( Werte );
6
}

... all das weiß die Funktion nicht und sie kann es auch nicht 
feststellen. Alles was die Funktion weiß ist: da ist ein Pointer und der 
zeigt auf einen Speicherbereich, an dem ein int angesiedelt ist.

Nicht mehr und nicht weniger. Die Funktion hat keine Möglichkeit anhand 
des Pointers festzustellen, wie und woher und in welchem Zusammenhang 
dieser Pointer entstanden ist. Für sie ist das einfach nur eine Adresse 
im Speicher, an der sie die Bytes vorfindet, die einen int bilden.

Der Fall 'ein Array wird übergeben, in dem man die Startadresse des 
Arrays übergibt', ist ein Sonderfall, der auf einer Konvention, einer 
Vereinbarung zwischen Funktion und Aufrufer, beruht, für die der 
Programmierer verantwortlich ist. Die Funktion tut so, als ob die 
Adresse die Startadresse eines Arrays wäre. Sie tut das deswegen, weil 
du als Progammierer weißt, dass du die Funktion so benutzen willst und 
du daher (als Programmierer) sicherstellst, dass alle Aufrufe auch in 
dieser Form erfolgen. Aber das ist nur eine Konvention, für deren 
Einhaltung der Programmierer verantwortlich ist. Weder beim Aufruf noch 
in der Funktion gibt es eine Möglichkeit, diesen Sachverhalt zu 
forcieren oder zu überprüfen oder abzutesten. Die Funktion bekommt 
lediglich einen Pointer. Nicht mehr.

von Walter S. (avatar)


Lesenswert?

Daniel schrieb:
> Geht schon, wenn Array global ist:
>
> #define SIZE_OF_ARRAY 256
> int Array[SIZE_OF_ARRAY];
>
> void Fkt(int* pArray)
> {
>    index = pArray - Array;
> }

das ist schlicht und einfach falsch
(könnte man solche Beiträge nicht auch einfach löschen, das verwirrt 
doch nur)

von Karl H. (kbuchegg)


Lesenswert?

Walter S. schrieb:
> Daniel schrieb:
>> Geht schon, wenn Array global ist:
>>
>> #define SIZE_OF_ARRAY 256
>> int Array[SIZE_OF_ARRAY];
>>
>> void Fkt(int* pArray)
>> {
>>    index = pArray - Array;
>> }
>
> das ist schlicht und einfach falsch

In diesem speziellen Kontext ist es nicht wirklich falsch.
Aber sinnlos. Vor allen Dingen dreht Daniel sich hier um einen 
Sonderfall, den der TO nicht hat. Denn hier muss man sich fragen: Wenn 
Array sowieso global ist und auch innerhalb der Funktion benutzt wird, 
wozu übergebe ich dann überhaupt einen Pointer und übergebe nicht gleich 
den Index

> (könnte man solche Beiträge nicht auch einfach löschen, das verwirrt
> doch nur)

von Fabian O. (xfr)


Lesenswert?

Walter S. schrieb:
> das ist schlicht und einfach falsch

Schön ist es nicht, aber was soll daran falsch sein?

von LosLEDos (Gast)


Lesenswert?

Fabian O. schrieb:
> Schön ist es nicht, aber was soll daran falsch sein?

Weil das zumindest noch durch sizeof(ArrayElement) geteilt werden muss:

Sinngemäss

   index = (pArray - Array + 1) / sizeof(int);

von Karl H. (kbuchegg)


Lesenswert?

LosLEDos schrieb:
> Fabian O. schrieb:
>> Schön ist es nicht, aber was soll daran falsch sein?
>
> Weil das zumindest noch durch sizeof(ArrayElement) geteilt werden muss:

Nö.
Das erledigt die Pointer-Arithmetik von alleine


Array Index - Pointer Dualismus:

Die Operation a[i] ist definiert als

    a[i]   <==>   *( a + i )

und die Pointer Arithmetik ist dergestalt, dass es das den sizeof von 
*ptr automatisch mit einrechnet.

von Ingo (Gast)


Lesenswert?

Danke Leute für die Aufklärung, nun geht es.




Ingo

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.