PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C]Array<->Zeiger



cyneox
12-08-2003, 10:48
ich hätte da eine kleine frage an euch:

double *zeiger; //definiert einen zeiger vom typ double ..is klar :)


double array[10]; //definiert ein array mit 10 elementen ,wobei array,benutzt in einem ausdruck, ein
//zeiger auf das erste element ist:



double *zeiger,array[10];
zeiger=array;


//man kann das erste element des arrays mit *array ansprechen ...is klar :)

--->jetzt kommt meine frage aber:


Beispiele:
main(int argc,char **argv )
extern char **environ ;


-->ich weiss man könnte auch :main(int argc,char *argv[]) oder extern char *environ[] schreiben
-->ist char *argv ein zeiger auf ein array ???wenn ja warum werden die elemente mit argv[1],argv[2],.. und so
weiter angesprochen???

wraith
12-08-2003, 11:27
Original geschrieben von cyneox

-->ist char *argv ein zeiger auf ein array ???wenn ja warum werden die elemente mit argv[1],argv[2],.. und so
weiter angesprochen???
char *argv[] ist ein Array von Zeigern auf char.
Wenn wir uns jetzt das mal als Speicherlayout denken (Bsp mit drei Einträgen),hätten wir sowas
1.Zeiger auf char | 2.Zeiger auf char| 3.Zeiger auf char |
(das soll ein Array im Speicher darstellen).
Wenn wir das indizieren (zb. argv[0]) bekommen wir einen Zeiger auf char,ebend eine Zeichenkette.

Also ist ein char* argv ein Zeiger auf einen char,der natürlich auch auf ein Array zeigen könnte (siehe dein obiges Bsp),aber in diesem Fall nicht.

Alex_K
12-08-2003, 12:40
wenn wir schon bei dem thema sind hab ich auch noch eine frage dazu:

wenn ich das bis jetzt sichtig verstanden habe werden variablen die z.b. mit int i = 0 am stack erzeugt. wenn man sie mit new anlegt int *i = new int(0) hingegen am heap.

ein char array kann ich mit char arr[] = "ASDF" oder char *arr = "ASDF" erzeugen, und es sollte immer das gleiche raus kommen. doch wo wird diese nun erzeugt?

wraith
12-08-2003, 13:04
Original geschrieben von Alex_K

wenn ich das bis jetzt sichtig verstanden habe werden variablen die z.b. mit int i = 0 am stack erzeugt. wenn man sie mit new anlegt int *i = new int(0) hingegen am heap.


So könnte man das sehr vereinfacht sagen,auch unter der Annahme,daß int i nicht global ist.
<picky>
Weder stack noch heap werden im Standard auch nur erwähnt.Es gibt Systeme,die über nicht sowas verfügen,was man allg. als Heap bezeichnen würde.
Oder anders ausgedrückt: It depends ;)
</picky>



ein char array kann ich mit char arr[] = "ASDF" oder char *arr = "ASDF" erzeugen, und es sollte immer das gleiche raus kommen. doch wo wird diese nun erzeugt?
Das sind zwei völlig verschiedene Dinge.
char [],ist ein Array,und char* ist ein Zeiger.
Im Fall char*pC = "ABCD" haben wir einen Zeiger,der auf eine Konstante Zeichenkette zeigt."ABCD" liegt i.A. in einem Read-Only Speicherbereich
Das Verändern dieser Zeichenkette erzeugt undefiniertes Verhalten.
Darum sollte man sich angewöhnen in solchen Fällen immer const char* zu nehmen.Das ist korrekt,die Gründe,daß auch char* 'korrekt' ist,daß im Prestandard C "ABCD" nicht in einem Read-Only Speicherbereich lag.
Der gcc trägt diesem mit einer Compileroption noch heute Rechnung.

char arr[] ist ein Array mit allen Rechten und Pflichten.
Die Zeichenkette "ABCD" wird in das Array kopiert,und weil wir es hier mit einem Array zutun haben,welches nicht const ist,können die Einträge geändert werden.

Wo aber diese jetzt konkret erzeugt werden: It depends ;).

cyneox
12-08-2003, 21:29
Original geschrieben von wraith
char *argv[] ist ein Array von Zeigern auf char.
Wenn wir uns jetzt das mal als Speicherlayout denken (Bsp mit drei Einträgen),hätten wir sowas
1.Zeiger auf char | 2.Zeiger auf char| 3.Zeiger auf char |
(das soll ein Array im Speicher darstellen).


ok...das ist klar aber warum wird dieser array-zeiger mit array[1],... und nicht mit *argv[1] angesprochen???
char **array; //definiert ein zeiger ,der auf das erste element des array zeigt ..oder????

wraith
12-08-2003, 21:46
Original geschrieben von cyneox
ok...das ist klar aber warum wird dieser array-zeiger mit array[1],... und nicht mit *argv[1] angesprochen???

Na,das ist doch klar,
Wenn argv[1] einen Zeiger auf char zurückliefert (also char*),dann liefert die Dereferenzerung (also *argv[1]) dieses Zeigers einen char,also ein Zeichen.
Oder nochmal erklärt,
argv[1] liefert einen char*,gut das machen wir uns klar


char* p = argv[1];

p ist ein Zeiger auf eine Zeichenkette.
Jetzt ist *p das erste Zeichen des Strings,und *p == *argv[1]



char **array; //definiert ein zeiger ,der auf das erste element des array zeigt ..oder????
Das definiert erstmal nur einen Zeiger,der auf einen Zeiger von char zeigt.
Im Fall von **argv zeigt argv[0] auf die erste Zeichenkette,und argv[0][0] auf das erste Zeichen,der ersten Zeichenkette.
Tja,und argv selber zeigt auf den Beginn dieser ganzen Struktur (also die Adresse),erst durch Dereferenzierung kann man konkreter werden.

cyneox
13-08-2003, 11:07
Original geschrieben von wraith
Na,das ist doch klar,
Wenn argv[1] einen Zeiger auf char zurückliefert (also char*),dann liefert die Dereferenzerung (also *argv[1]) dieses Zeigers einen char,also ein Zeichen.


tja...und warum wird beim code:


main(int argc,char *argv[])

printf("%s",argv[1]);


nicht ein zeichen ausgegeben,sondern die ganze zeichenkette,auf die argv[1] zeigt???



Das definiert erstmal nur einen Zeiger,der auf einen Zeiger von char zeigt.
Im Fall von **argv zeigt argv[0] auf die erste Zeichenkette,und argv[0][0] auf das erste Zeichen,der ersten Zeichenkette.

argv[0] zeigt auf die erste zeichenkette,wenn wir folgenden code haben:


main(int argc,char **array)


warum wird das gleiche áusgegeben wenn wir folgenden code haben:


main(int argc,char *argv[])
printf("%s",argv[1]);


obwohl du geschrieben hast ,dass in diesem fall argv[1] ein zeiger auf char liefert und nicht eine zeichenkette???

wraith
13-08-2003, 15:15
Original geschrieben von cyneox

obwohl du geschrieben hast ,dass in diesem fall argv[1] ein zeiger auf char liefert und nicht eine zeichenkette???
Das obwohl ist hier falsch.
Weil ich geschrieben habe,daß argv[1] ein Zeiger auf char ist wird nicht ein Zeichen,sondern eine Zeichenkette ausgegeben.

Ein Zeiger auf char zeigt auf eine Position im Speicher.Das char sagt dem Compiler,interpretieren das worauf der Zeiger zeigt als char (uhm,ich sehe das ist wieder mehrdeutig interpretierbar).

Vielleicht bringt ja jemand anders eine ausführliche Erklärung,darum belasse ich es jetzt mal bei der schwammigen Formulierung:
Eine Zeichenkette ist ein Bereich im Speicher,auf den ein char Zeiger zeigt,und der Bereich ist mit einer '\0' abgeschlossen.
printf hangelt sich also solange an der Adresse in byte Schritten voran,bis er auf ein '\0' trifft.

cyneox
13-08-2003, 20:46
trotzdem danke für deine bemühungen..
ich hab auch ziemlich lange überlegt und ich glaub ich hab das verstanden.

thx