Forum: PC-Programmierung übergabe von arrays an Funktion


von Alex (Gast)


Lesenswert?

Guten Tag,
ich habe eine Frage zu übergabe von arrays an Funktionen
1
#include <stdint.h>
2
#include <stdio.h>
3
4
static void writeAddress(uint8_t array[], uint8_t array2[]);
5
6
int main(int argc, char *argv[])
7
{
8
  uint8_t array[4] = {0x01, 0x02, 0x03, 0x04};
9
  writeAddress(array, &array[0]);
10
}
11
12
static void writeAddress(uint8_t array[], uint8_t array2[])
13
{
14
  printf("address: %zu\n", &array);
15
  printf("address: %zu\n", &array2);
16
  printf("value: 0x%X\n", array[0]);
17
  printf("value: 0x%X\n", array2[0]);
18
}

ausgabe ist:
address: 3200107940
address: 3200107936
value 0x1
value 0x1

Wie ich sehe, ist der array in beiden weisen komplett übergeben. Der 
erste Wert von beiden ist 0x01.
Die Adresse ist unterschiedlich. Wobei ich davon ausgegangen wäre, dass 
die adresse von array2 höher ist, als die von array, da der Aufbau ja 
eigentlich wie folgt aussieht oder?

array        -> adresse array
 - array[0]  -> adresse array[0]
 - array[1]  -> adresse array[1]
 - array[2]
 - array[3]

Wann übergibt man normalerweise einen Array einfach nur den Array und 
wann als pointer?

Alex

von devzero (Gast)


Lesenswert?

Du gibst die Adresse der Pointer aus, nicht die Adresse worauf sie 
zeigen. Und ja, es sind bei beidem Schreibweisen Pointer.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Du übergibst 2x exakt das Gleiche, nämlich einen Zeiger auf das 0. 
Element von "array". Zwei Kopien dieses Zeigers werden in zwei 
Parametern abgelegt, welche selbst wiederum an zwei verschiedenen 
Speicherstellen landen, die somit zwei unterschiedliche Adressen haben, 
aber den selben Zeiger enthalten.

Diese zwei unterschiedlichen Adressen gibst du mit dem ersten printf 
aus. Das zweite printf gibt die Daten am Ziel der beiden identischen 
Zeiger aus, welche natürlich auch gleich sind.

Zeiger gibt man übrigens mit %p aus, denn %u erwartet den Typ "unsigned 
int", was ggf. die falsche Größe hat - z.B. auf AMD64 hat "unsigned int" 
meist 32bit, aber Zeiger sind dort 64bit. %p macht es automatisch 
richtig.

von GEKU (Gast)


Lesenswert?

Alex schrieb:
> printf("address: %zu\n", &array);
> printf("address: %zu\n", &array2);

Liegt da ein Fehler im Code vor: %zu sollte %x sein, oder?

array liefert einen Zeiger auf den Anfang des Arrays.

&array[0] liefert einen Zeiger auf den ersten Eintrag des Arrays, und 
dieser steht am Anfang des Arrays, somit sollten die gleichen Adressen 
ausgegeben werden, wenn nicht %zu verwendet worden wäre.

von Rolf M. (rmagnus)


Lesenswert?

Alex schrieb:
> Wie ich sehe, ist der array in beiden weisen komplett übergeben.

Falsche Schlussfolgerung.

> Wann übergibt man normalerweise einen Array einfach nur den Array und
> wann als pointer?

Arrays werden als Parameter niemals per Kopie übergeben, sondern immer 
als Zeiger.

GEKU schrieb:
> Alex schrieb:
>> printf("address: %zu\n", &array);
>> printf("address: %zu\n", &array2);
>
> Liegt da ein Fehler im Code vor: %zu sollte %x sein, oder?

Beides ist falsch. Es müsste %p sein, für (void-)Pointer. %zu wäre ein 
size_t in dezimal, %x ein unsigned int in hexadezimal.

> array liefert einen Zeiger auf den Anfang des Arrays.
> &array[0] liefert einen Zeiger auf den ersten Eintrag des Arrays, und
> dieser steht am Anfang des Arrays, somit sollten die gleichen Adressen
> ausgegeben werden, wenn nicht %zu verwendet worden wäre.

array und &array[0] liefern beide exakt den gleichen Zeiger - einen auf 
das erste Element. Mit %zu hat das überhaupt nichts zu tun.
Dass die Werte unterschiedlich sind, liegt daran, dass
1
  printf("address: %zu\n", &array);
2
  printf("address: %zu\n", &array2);
die Adressen der beiden Zeiger selbst ausgibt, nicht die Adresse des 
Arrays bzw. die des ersten Elements, wie deine beiden Vorredner schon 
richtig erklärt haben. Es hätte richtig heißen müssen:
1
  printf("address: %p\n", (void*)array);
2
  printf("address: %p\n", (void*)array2);

Da sollte dann der gleiche Wert angezeigt werden.

Alex schrieb:
> writeAddress(array, &array[0]);

wird beim ersten Parameter automatisch die Adresse des ersten Elements 
übergeben. Man sagt, dass das Array in einen Zeiger auf sein erstes 
Element "zerfällt". Das erste Argument ist also exakt das gleiche wie 
&array[0], entspricht also zu 100% dem zweiten. Man darf sich auch nicht 
von dem [] im Parameter täuschen lassen. uint8_t array[] ist als 
Parameter (und nur dort) exakt das gleiche wie uint8_t * array.

: Bearbeitet durch User
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.