argv, Zeigerarrays und andere Widrigkeiten ;o)
-
Nur mal ne kurze Verständnisfrage...
Also, Zeiger-Zeiger, Zeigerarrays und Zeiger auf Arrays habe ich mittlerweile recht gut verstanden, nur ein paar kleine Frägchen habe ich noch:
1. Ist meine Annahme richtig, dass ein 2-dim-Array ein Array aus Zeigern ist, welche wiederum Zeiger auf Arrays sind?
2. Kann ich ein sagen wir 5-dim-Array anstatt mit array[10][10][10][10][10] auch mit *****array deklarieren, wenn ich letzterem dann mit malloc Speicher reserviere? Ist ein 5-dim-Array ein Zeigerarray, dessen Elemente Zeiger auf Zeigerarrays sind, deren Elemente Zeiger auf Zeigerarrays sind, deren Elemente wiederum Zeiger auf Zeigerarrays sind, deren Elemente dann Zeiger auf "Werte"-Arrays sind?
3. Thema **argv: es heißt doch, dass der Arrayname ein konstanter Zeiger ist. Wieso kann ich den konstanten Zeiger des 2-dim-Arrays **argv, dessen Name dann ja argv ist (hier das **argv, welches als Parameter im Funktionskopf von main() angegeben wird) dann z.B. mit argv++ verändern?!
4. Ich brauche noch ein wenig Praxis mit Zeigern. Hat jemand brauchbare Aufgaben/Übungen zu der Problematik Zeigerarrays, Arrays auf Zeiger oder Zeiger-Zeiger?!Nu bin ich total verwirrt :p
Schönes Wochenende Euch allen...
-
Original erstellt von RTC:
**1. Ist meine Annahme richtig, dass ein 2-dim-Array ein Array aus Zeigern ist, welche wiederum Zeiger auf Arrays sind?
**Nein.
**
2. Kann ich ein sagen wir 5-dim-Array anstatt mit array[10][10][10][10][10] auch mit ***array deklarieren, wenn ich letzterem dann mit malloc Speicher reserviere? Ist ein 5-dim-Array ein Zeigerarray, dessen Elemente Zeiger auf Zeigerarrays sind, deren Elemente Zeiger auf Zeigerarrays sind, deren Elemente wiederum Zeiger auf Zeigerarrays sind, deren Elemente dann Zeiger auf "Werte"-Arrays sind?Siehe 1.
[QUOTE]**
3. Thema **argv: es heißt doch, dass der Arrayname ein konstanter Zeiger ist. Wieso kann ich den konstanten Zeiger des 2-dim-Arrays **argv, dessen Name dann ja argv ist (hier das **argv, welches als Parameter im Funktionskopf von main() angegeben wird) dann z.B. mit argv++ verändern?!
**[QUOTEWeil Array an Funktionen als Zeiger übergeben werden.
die beiden Deklarationen sind identisch:
int foo(char array[]); int foo(char *array);
hier würde es nicht funktionieren:
char array[10]; array ++; /* MÖÖP! */
-
Original erstellt von Bashar:
**Nein.
**Damit kann ich wenig anfangen!
Warum nicht?![ Dieser Beitrag wurde am 16.05.2003 um 23:10 Uhr von RTC editiert. ]
-
Original erstellt von RTC:
1. Ist meine Annahme richtig, dass ein 2-dim-Array ein Array aus Zeigern ist, welche wiederum Zeiger auf Arrays sind?nein.
es ist ein array von arrays.beispiele:
int a[3];
ist ein array mit 3 ints.
sizeof(a)==12.int b[4];
ist ein arry mit 4 ints.
sizeof(b)==16.int c[3][4];
ist ein array mit 3 arrays mit je 4 ints.
sizeof(c)==48.was ist sizeof(a[0])?
was ist sizeof(b[0])?
was ist sizeof(c[0])?
-
sizeof(a)==12.
Auf 32Bit System.
Beim 16Bit System siehts wieder anders aus.
was ist sizeof(a[0])?
4 bzw 2 Byte
-
b und c noch beantworten. laß uns dabei von 32-bittern ausgehen.
-
Hey, ich habe keine Vertreter! :p
Original erstellt von volkard:
**nein.
es ist ein array von arrays.
**Kommt das nicht auf dasselbe heraus, da man ja Arrays auch mit Zeigern abbilden kann (array[i]=i[array]=*(array+i))?
Original erstellt von volkard:
**
was ist sizeof(a[0])?
was ist sizeof(b[0])?
was ist sizeof(c[0])?**Bei b die Byteanzahl einer int-Variablen, in deinem Beispiel also 4. Mit sizeof(a)/sizeof(a[0]) lässt sich ja z.B. auch die Anzahl der Array-Elemente ermitteln...
Bei c die Byteanzahl von 4 ints, also 16 Bytes...[ Dieser Beitrag wurde am 16.05.2003 um 23:34 Uhr von RTC editiert. ]
-
Mit sizeof(a)/aizeof(a[0]) lässt sich ja z.B. auch die Anzahl der Array-Elemente ermitteln...
oder sizeof(a)/sizeof(int) kannst du die grösse des arrays rausfinden.
mensch bin ich heute wieder ein klugscheisser
-
Original erstellt von RTC:
Kommt das nicht auf dasselbe heraus, da man ja Arrays auch mit Zeigern abbilden kann (array[i]=i[array]=*(array+i))?Aber nein!
sizeof(3 arrays mit 4 ints drin)==3sizeof(array mit 4 ints drin)==48
aber
sizeof(3 arrays mit zeigern drin)==3sizeof(zeiger)==12außerdem zweifle ich an der rechtigkeit deiner antwort zu c. was sagt der compiler?
edit: aha, hast c korrigiert.
also haste da nen echten unterschied zwischen nem array voller arrays und nem array voller zeiger.[ Dieser Beitrag wurde am 16.05.2003 um 23:28 Uhr von volkard editiert. ]
-
Original erstellt von <ffffffff>:
mensch bin ich heute wieder ein klugscheisserWohl wahr
-
das letzte is 16 byte gross
-
Original erstellt von <fff>:
das letzte is 16 byte grossBrrr, natürlich. Muss jetzt mal ins Bett, ich nehme schon für int 2 Bytes an *ggg*.
@volkard: der Unterschied zwischen Zeigerarrays und richtigen Arrays, die Arrays enthalten ist mir schon klar, aber es lassen sich doch Arrays trotzdem mit Zeigern abbilden...
Hm, ich denke morgen früh noch einmal drüber nach, heute bringt das nix mehr.
-
Naja also wenn du mit alten Windows-Versionene arbeitest, sind 2Byte schon richtig
-
Original erstellt von RTC:
@volkard: der Unterschied zwischen Zeigerarrays und richtigen Arrays, die Arrays enthalten ist mir schon klar, aber es lassen sich doch Arrays trotzdem mit Zeigern abbilden...es ist eher so, daß bezeichner, die arrays bezeichnen, automatisch in einen zeiger aufs erste element ausgewertet werden, wenn der bezeichner nicht direkt als array verwendet werdne kann, was höchst selten ist. z.B. in sizeof. die operatoren * und [] arbeiten schlicht auf zeigern.
mal wieder was spielen:
int a[3][4];//a ist array von 3 arrays von je 4 ints.
beachte, daß a[1] um 16 bytes weiter hinten liegt als a[0].und jetzt lege ich ein zeigerarray an, was auf die drei sub-arrays zeigt.
int *b[3]={a[0],a[1],a[2]};//b ist array von 3 zeigern auf int.
normalerweise hätte ich die drei subarrays mit malloc angelegt.
beachte, daß b[1] nur um 4 bytes weiter hinten liegt, als b[0].und jetzt lege ich einen zeiger an, der das auch kann.
int (*c)[4]=a;//c ist zeiger auf arrays von je 4 int.
beachte, daß a[1] um 16 bytes weiter hinten liegt als a[0].wenn ich also hart aus nem int a[3][4] ein int **a machen würde, gäbe es mit den arrayzugriffen nur fehler.
das einzige, was die gemein haben ist, daß man auf beide mit x=a[2][1] zugreifen kann. sie fühlen sich beide wie 2-dimensionale arrays an (und meiner philosophischen grundhaltung nach sind sie daher wenigstens teilweise 2-dimensionale arrays).
-
Also ist Zeiger auf Zeiger eigentlich schwachsinn oder?
-
Original erstellt von <fff>:
Also ist Zeiger auf Zeiger eigentlich schwachsinn oder?nee. ist nur anderes speicherlayout.
int** mach2darray(int sx,int sy) { int i; int** oberarray=malloc(sx*sizeof(int*)); for(i=0;i<sx;++i) oberarray[i]=malloc(sy*sizeof(int)); return oberarray; }
vorteil von das hier ist, daß der ganze speicher nicht an einem stück sein muß, was bei dos manchmal schwer war. und daß der benutzer dieses 2d-arrays nix über dessen dimensionen wissen muß. die beiden dereferenzierungen bei zweimaligem [] machen das schon.
int (*mach2darraymitsyist4(int sx))[4] { int (*array)[4]=malloc(sx*sizeof(int[4])); return array; }
vorteil von das hier ist, daß nicht zwei dereferenzierunge nötig sind, sondern ein [] mit adresberechnung gemacht wird. und ein wenig speicherplatzsparender ist es, weil kein oberarray gebaurcht wird. und natürlich nur ein malloc-aufruf. nachteil ist, daß nur eine dimension frei wählbar ist. alle anderen müssen fest sein.
-
Wielange hast Du den gebraucht, um das mit den "Zeiger auf Zeiger" zu verstehen?
-
Original erstellt von <fff>:
Wielange hast Du den gebraucht, um das mit den "Zeiger auf Zeiger" zu verstehen?jahre.
-
Das ist häftig.
Auf jeden Fall danke, für deine Hilfe.
-
Original erstellt von fff**
Naja also wenn du mit alten Windows-Versionene arbeitest, sind 2Byte schon richtig**Nix altes Windows, sondern neues Linux
Aber ist schon klar, das mit den 16Bit. 32Bits sind natürlich 4 Bytes...Original erstellt von volkard**
jahre.**Ich sehe mich auch in ein paar Jahren noch dahängen und darüber grübeln, ob es nun ein Zeigerarray oder sonst was anderes ist *kotz*. Mal im Ernst: ich habe noch keine Anleitung gesehen, in der das einfach verständlich erklärt wird. Aber es kann bestimmt nicht deshalb einfach erklärt werden, weil es nicht einfach ist - ganz einfach
Ok, ich resümiere mal für mich: Zeigerarrays, deren Elemente wieder auf Arrays zeigen, sind natürlich keine 2-dim-Arrays, da 2-dim-Arrays als Elemente wiederum Arrays enthalten und ihr Speicherplatz hintereinander reserviert ist. Die Arrays, auf die die Elemente eines Zeigerarrays zeigen, können hingegen dynamisch verändert werden, das ganze Array von Zeigern kann natürlich auch dynamisch verändert werden, wenn man eine Dimensionierung unterlässt und malloc zunächst auf das Zeigerarray und dann noch auf jedes Array, auf welches ein Zeiger des Zeigerarrays zeigt, ausführt.
Aber: Zeigerarrays, deren Elemente auf Zeiger zeigen UND 2-dim-Arrays können auf dieselbe Art und Weise angesprochen werden, oder?Letzter Hint hierzu nochmal: wieso darf ich argv++ ausführen, wenn doch argv ein konstanter Zeiger ist? Bashar hatte eine kleine Lösung angegeben, doch damit kann ich wenig anfangen: "Weil Array an Funktionen als Zeiger übergeben werden."
Kann mir das jemand nochmal kurz erklären?
-
Kennst Du schon das Tutorial auf www.pronix.de ?
Da wird das und noch viel mehr, verständlich und leicht erklärt
Nix altes Windows, sondern neues Linux
dito