Zeiger auf ein Array von chars (char* argv[])



  • Hallo!

    Sitze jetzt schon Ewigkeiten um zu verstehen, wie das im Titel angegebene Array ausschauen sollte bzw. wie es aufgebaut ist.

    Irgendwo habe ich einen Denkfehler und bekomme den nicht weg!

    Ich wäre um eine Erklärung sehr dankbar. Die, die ich bisher im Internet gefunden habe, konnten mein Problem nicht lösen 😞
    Hier der Code mit dem ich probiert habe:

    die Aufrufparameter sind: ./altklausur.c beispiel c

    int main(int argc, char* argv[])
    {
    	char** v = argv;
    	printf("%p\n", argv[0]); 		// 0x7ffc9f9427a3 /
    	printf("%s\n", argv[0]);		// ./altklausur1
    	printf("%c\n", *argv[0]);		// .
    	printf("%c\n", v[1][0]);		// b
    	printf("%p\n", *v);				// 0x7ffc9f9427a3
    	printf("%c\n", **v);			// .
    	printf("%p\n", &(**(v + 1)));	// 0x7ffc9f9427b1
    
    	printf("%p\n", &argv[0][0]);	// 0x7ffde1bc57b1
    
    	printf("%c\n", v[0][0]); 		// .
    	printf("%c\n", *argv[1]);		// b
    	printf("%c\n", *(*argv + 1));	// /
    	printf("%c\n", argv[1][2]);		// i
    
    	return EXIT_SUCCESS;
    
    }
    

    Wie sieht das Array nun aus? Beinhaltet es die Adressen oder die Chars?
    Warum kann ich zb. mit argv[1][2] das Array als 2-Dimensional ansprechen?
    Warum muss ich da nicht dereferenzieren?

    Je mehr ich probiere, desto weniger versteh ich 😕

    Hoffe es kann mir wer weiterhelfen und schonmal danke im Voraus!



  • cdecl.org sagt zu char* argv[] : "declare argv as array of pointer to char"

    argv ist ein Array von Zeiger auf char

    Das Array enthält die Adressen. die Zeichenketten sind irgendwo gespeichert.
    (beim argv von main hast du darauf keinen Einfluss)

    Reverseiuh schrieb:

    Warum muss ich da nicht dereferenzieren?

    der Klmmeroperator [] dereferenziert auch einen Zeiger.
    Der Compiler macht aus argv[i] ein *(argv + i)

    Aus argv[0][1] macht er *(argv[0] + 1) und dweiter ((argv + 0) + 1) und (da +0 keinen Effekt hat) *(*argv + 1)


  • Mod

    Das ist ein Zeiger auf ein Array von Zeigern auf Arrays von chars.

    Fangen wir bei den char-Arrays an. Wie du sicher weißt, sind da jeweils der Programmaufruf und seine Argumente drin.

    "./altklausur1"
    "parameter1"
    "parameter2"
    

    Diese Arrays sind jeweils völlig unabhängig voneinander einfach wild irgendwo im Speicher verteilt. Daher kann man Zeiger auf diese Arrays haben. Beziehungsweise keine Zeiger auf die ganzen Arrays am Stück, sondern in C ist es üblich, stattdessen auf das erste Element eines Arrays zu zeigen. Also:

    char *zeiger0 = "./altklausur1";
    char *zeiger1 = "parameter1";
    char *zeiger2 = "parameter2";
    

    Wenn man seine Variablen variable0, variable1, variable2, usw. nennt, dann ist das immer ein gutes Zeichen dafür, dass man stattdessen ein Array haben möchte. Also packen wir die Zeiger in ein Array. Und an das Ende des Arrays packen wir noch einen Nullzeiger, dann braucht man sich nicht zu merken, wie lang das Array ist, sondern kann einfach gucken, bis man den Nullzeiger findet. Dazu brauchen wir also ein Array von Zeigern auf char-Zeiger:

    char *programmargumente[4] = {zeiger0, zeiger1, zeiger2, NULL};
    

    Nun wollen wir das noch an die main-Funktion übergeben. Arrays kann man nicht direkt als Ganzes via Funktionsargument übergeben. Stattdessen ist es üblich, einen Zeiger auf das Array zu übergeben, oder wie oben erklärt, einen Zeiger auf das erste Element. Das ist also ein Zeiger auf einen Zeiger auf char. Und das ist das argv:

    char **argv = programmargumente;
    

    Wenn man einen Zeiger in der Parameterliste einer Funktion definiert, dann darf man auch [] statt * schreiben. Das macht technisch absolut gar keinen Unterschied, es ist immer noch ein Zeiger. Man macht damit etwas besser deutlich, dass man erwartet, dass dieser Zeiger auf den Anfang eines Arrays zeigt.



  • Danke für die Erklärung, macht es um einiges einfacher das Ganze nachzuvollziehen1



  • https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorität

    allgemein sagt man natürlich, dass man bei der kleinsten unsicherheit über diese prioritäten so mit klammern arbeiten soll, dass das alles mit der gewünschten auswertung übereinstimmt.

    aber aus der tabelle ergibt sich auch das array auf pointer.


Anmelden zum Antworten