mikrocontroller.net

Forum: PC-Programmierung übergabe von arrays an Funktion


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag,
ich habe eine Frage zu übergabe von arrays an Funktionen
#include <stdint.h>
#include <stdio.h>

static void writeAddress(uint8_t array[], uint8_t array2[]);

int main(int argc, char *argv[])
{
  uint8_t array[4] = {0x01, 0x02, 0x03, 0x04};
  writeAddress(array, &array[0]);
}

static void writeAddress(uint8_t array[], uint8_t array2[])
{
  printf("address: %zu\n", &array);
  printf("address: %zu\n", &array2);
  printf("value: 0x%X\n", array[0]);
  printf("value: 0x%X\n", array2[0]);
}

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

Autor: devzero (Gast)
Datum:

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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GEKU (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht 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
  printf("address: %zu\n", &array);
  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:
  printf("address: %p\n", (void*)array);
  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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.