Frage zu Array und Pointerarrithmetik
-
Moin moin,
Ich spiel grad ein bisschen mit Arrays und Pointern rum.
Dabei bin ich auf eine ungereihmtheit gestoßen:
Also folgendes Beispiel:
int array[] = {1,2,3,4}; printf("%x", array); printf("%x", &array);Klar, die erste Zeile liefert die Adresse des ersten Elements von Array.
Die zweite Zeile wiederrum müsste die Adresse der Speicherzelle liefern, in welcher wiederrum die Adresse des ersten Elements von Array gespeichert ist.
Bei mir liefert &array allerdings dasselbe wie array, in Syntax: &array == array !
Analog dazu folgendes Beispiel:
int *pointer = malloc(4); *pointer = 10; printf("%x", pointer); printf("%x", &pointer);Hier stimmt es wieder, denn: Es gilt pointer == *(&pointer). Und *pointer == 10.
Warum ist das bei Arrays anders?
Und dann noch eine zweite kurze Frage:
Soweit ich das jetzt gesehen habe, ist es nicht möglich Arrays ohne Angabe der Länge zu definieren, es sei denn man macht es so wie ich oben (also definiert auch gleich den Inhalt). Der Compiler müsste dann oben halt die Angabe von int[] automatisch in int[4] interpretiert haben.
Also schonmal vielen Dank!
-
HansiDampf schrieb:
Die zweite Zeile wiederrum müsste die Adresse der Speicherzelle liefern, in welcher wiederrum die Adresse des ersten Elements von Array gespeichert ist.
...aber da es keine speicherzelle gibt, in der die adresse des ersten elements des arrays gespeichert ist...

-
HansiDampf schrieb:
Also folgendes Beispiel:
int array[] = {1,2,3,4}; printf("%x", array); printf("%x", &array);Klar, die erste Zeile liefert die Adresse des ersten Elements von Array.
Die zweite Zeile wiederrum müsste die Adresse der Speicherzelle liefern, in welcher wiederrum die Adresse des ersten Elements von Array gespeichert ist.
und damit zeigst du einen der wesentlichen Unterschiede zwischen Zeigern und Arrays. Mit
arraybekommst du implzit einen Zeiger aufs erste Element des Feldes, aus diesem Grund giltarray == &array, aber das gilt nur für Arrays
-
Und warum gibt es eine solche dann bei Pointern?!
Der Pointer muss ja auch irgendwo gespeichert werden, um genau zu sein an &pointer.
Ich habe das mit Arrays so verstanden:
int a[] = {1,2,3}Ist eine verkürzte schreibweise für:
int *a = malloc(3*sizeof(int)); *a = 1; a++; *a = 2; a++; *a = 3; a = (a-3); //für die abfrage int ina(int i) { return *(a + i); }Dann gilt: ina(2) = a[2]usw.
Wo ist der Unterschied?
-
ja, die eckigen klammern sollen den zugriff nur erleichtern.
http://www.c-howto.de/tutorial-arrays-felder-zeigerarithmetik.html
-
HansiDampf schrieb:
Und warum gibt es eine solche dann bei Pointern?!
weil Pointer keine Arrays sind und umgkehrt. Eine Kuh und eine Stute sehen sich ähnlich aus sind dennoch unterschiedliche Tiere. Hier ist es dasselbe, Zeiger und Arrays sehen sich ähnlich aus, sind aber verschieden.
Ein Zeiger ist nur eine Variable, deren Inhalt der Speicherort einer anderen Variable ist. Deswegen haben allen Zeiger immer die gleiche Größe (mal abgesehen von soft pointern und solche Geschichten), auf 32-bit x86 Systemen 4 Bytes, also genauso groß wie ein int. Worauf Zeiger zeigen ist eine andere Geschichte und woauf sie zeigen kann stets geändert werden (sofern sie nicht als const deklariert sind).
Ein Array ist eine "Sammlung" von
nElementen des gleichen Typs.int *ptr; int arr[10];Auf dem Stack der Funktion werden 4 Bytes für den Zeiger reserviert und 10*40 Bytes fürs Array.
arrist zeigt implizit auf die erste Stelle des Speichers, d.h.arrzeigt nicht auf irgendwelche beliebige Stelle wieptres machen kann. Deswegen ist die Adresse der Variablearrstets dieselbe wie die Adresse woraufarrimplizit zeigt, spricharr == &arr(obwohl diese unterschiedliche Typen sind, kompiliere das und der Compiler wird dich warnen). Aus diesem Grund kannst du nicht die Größe eines Arrays zur Öaufzeit verändern oder die Speicherstelle des Arrays nachträglich verändern (wie bei Zeigern).HansiDampf schrieb:
Ich habe das mit Arrays so verstanden:
int a[] = {1,2,3}Ist eine verkürzte schreibweise für:
int *a = malloc(3*sizeof(int));und woher hast du diesen Unsinn?
abelegt 12 Bytes im Stack und mita[i]greifst du aufs i+1. Element zu. [man: malloc(3]](http://man.cx/malloc(3]) reserviert 12 Bytes im Heap, der Speicherbereich liegt ganz wo anders und hat andere Eigenschaften wie z.b. dass man den Bereich zur Laufzeit vergrößern oder verkleinern kann.HansiDampf schrieb:
//für die abfrage int ina(int i) { return *(a + i); }Dann gilt: ina(2) = a[2]usw.
Wo ist der Unterschied?
Ein Arrays deklarier sozusagen einen impliziten Zeiger auf sich selbst. Ob du mit [] oder mit * auf die Elemente zugreifst, spielt keine Rolle. Beachte, dass arrays und zeiger ähnlich aussehen (d.h. man kann sie ähnliche behandeln) aber sie sind dennoch verschieden.
-
*bitte löschen*