webentwicklung-frage-antwort-db.com.de

Was ist der Typ des Befehlszeilenarguments 'argv' in C?

Ich lese einen Abschnitt aus C Primer Plus über das Befehlszeilenargument argv und habe Schwierigkeiten, diesen Satz zu verstehen.

Es steht dass,

Das Programm speichert die Befehlszeilenzeichenfolgen im Speicher und speichert die Adresse jeder Zeichenfolge in einem Array von Zeigern. Die Adresse dieses Arrays wird im zweiten Argument gespeichert. Konventionell heißt dieser Zeiger auf Zeiger für Argumentwerte argv.

Bedeutet dies, dass die Befehlszeilenzeichenfolgen als Array von Zeigern auf das Array von char im Speicher gespeichert werden?

14
Jin

Direktes Zitieren aus C11, Kapitel §5.1.2.2.1/p2, Programmstart, (Hervorhebung meines)

int main(int argc, char *argv[]) { /* ... */ }

[...] Wenn der Wert von argc größer als Null ist, müssen die Array-Member argv[0] bis argv[argc-1] inklusive Zeiger auf Strings , [...]

und

[...] und die Zeichenfolgen, auf die das argv-Array zeigt, [...]

Im Grunde ist argv ein Zeiger auf das erste Element eines String-Arrays hinweis. Dies kann aus der Alternativform klarer gemacht werden.

int main(int argc, char **argv) { /* ... */ } 

Sie können das als Zeiger auf das erste Element eines Arrays von Zeigern auf das erste Element von char-Arrays mit Nullterminierung umformulieren, aber ich würde lieber Strings behalten.


HINWEIS:

Um die Verwendung von "Zeiger auf das erste Element eines Arrays" zu verdeutlichen, in der obigen Antwort, folgt §6.3.2.1/p3

Außer, wenn es sich um den Operanden des sizeof-Operators, des _Alignof-Operators oder des Unären &-Operators handelt oder um ein String-Literal zum Initialisieren eines Arrays, einen Ausdruck mit dem Typ '' Array vom Typ '' wird in einen Ausdruck mit dem Typ '' Zeiger auf den Typ '' umgewandelt der auf auf das Anfangselement des Arrayobjekts zeigt und ist kein lvalue. [...]

15
Sourav Ghosh

argv ist vom Typ char **. Es ist kein Array . Es ist ein Zeiger auf char. Befehlszeilenargumente werden im Speicher gespeichert, und die Adresse jedes Speicherplatzes wird in einem Array gespeichert. Dieses Array ist ein Array von Zeigern auf char. argv zeigt auf das erste Element dieses Arrays. 

 Einige 
 Felder 
 
 + ------- + + ------ + ------ + ---- --------- + ------ + 
 argv ----------> | | | | | | 
 | 0x100 + ------> | | | . . . . . . | | Programmname1
 0x900 | | | | | | 
 | | + ------ + ------ + ------------- + ------ + 
 + ------- + 0x100 0x101 
 | | + ------ + ------ + ------------- + ------ + 
 | 0x205 | | | | | 
 0x904 | + ------> | | | . . . . . . | | Arg1
 | | . | | | | | 
 + ------- + + ------ + ------ + ------------- + ------ + 
 | . | . 0x205 0x206 
 | . 
 | . | . 
 | . 
 + ------- +. + ------ + ------ + ------------- + ------ + 
 | | | | | | 
 | 0x501 + ------> | | | . . . . . . | | Argargc-1
 | | | | | | | 
 + ------- + + ------ + ------ + ------------- + ------ + 
 | | 0x501 0x502 
 | NULL | 
 | | 
 + ------- + 
 
 
0xXXX Stellt die Speicheradresse dar

1. In den meisten Fällen steht argv[0] für den Programmnamen, aber wenn der Programmname nicht in der Host-Umgebung verfügbar ist, steht argv[0][0] für Nullzeichen. 

22
haccks

Dieser Thread ist so ein Zugunglück. Hier ist die Situation:

  • Es gibt ein Array mit argc+1-Elementen vom Typ char *.
  • argv zeigt auf das erste Element dieses Arrays.
  • Es gibt argc andere Arrays vom Typ char und verschiedene Längen, die nullterminierte Zeichenfolgen enthalten, die die Befehlszeilenargumente darstellen.
  • Die Elemente des Zeigerarrays zeigen jeweils auf das erste Zeichen eines der Arrays von char; mit Ausnahme des letzten Elements des Arrays von Zeigern, das ein Nullzeiger ist.

Manchmal schreiben Leute "Zeiger auf Array von X", um "Zeiger auf das erste Element eines Arrays von X" zu bedeuten. Sie müssen die Kontexte und Typen verwenden, um herauszufinden, ob sie dies tatsächlich bedeuteten oder nicht.

11
M.M

argv ist ein Array von Zeigern auf Zeichen.

Der folgende Code zeigt den Wert von argv und den Inhalt von argv an und führt einen Speicherabzug für den Speicher aus, auf den der Inhalt von argv zeigt. Hoffentlich beleuchtet dies die Bedeutung der Indirektion.

#include <stdio.h>
#include <stdarg.h>

print_memory(char * print_me)
{
    char * p;
    for (p = print_me; *p != '\0'; ++p)
    {
        printf ("%p: %c\n", p, *p);
    }

    // Print the '\0' for good measure
    printf ("%p: %c\n", p, *p);

}

int main (int argc, char ** argv) {
    int i;

    // Print argv
    printf ("argv: %p\n", argv);
    printf ("\n");

    // Print the values of argv
    for (i = 0; i < argc; ++i)
    {
        printf ("argv[%d]: %p\n", i, argv[i]);
    }
    // Print the NULL for good measure
    printf ("argv[%d]: %p\n", i, argv[i]);
    printf ("\n");

    // Print the values of the memory pointed at by argv
    for (i = 0; i < argc; ++i)
    {
        print_memory(argv[i]);
    }

    return 0;
}

Probelauf:

$ ./a.out Hello World!
argv: ffbfefd4

argv[0]: ffbff12c
argv[1]: ffbff134
argv[2]: ffbff13a
argv[3]: 0

ffbff12c: .
ffbff12d: /
ffbff12e: a
ffbff12f: .
ffbff130: o
ffbff131: u
ffbff132: t
ffbff133:
ffbff134: H
ffbff135: e
ffbff136: l
ffbff137: l
ffbff138: o
ffbff139:
ffbff13a: W
ffbff13b: o
ffbff13c: r
ffbff13d: l
ffbff13e: d
ffbff13f: !
ffbff140:

$

Sie haben dieses große zusammenhängende Array von ffbff12c bis ffbff140, das die Befehlszeilenargumente enthält (dies ist vom Standard nicht garantiert ein zusammenhängendes Array, wird aber im Allgemeinen so gemacht). argv enthält nur Zeiger in dieses Array, damit Sie wissen, wo Sie nach den Wörtern suchen müssen.

argv ist ein Zeiger ... auf Zeiger ... auf Zeichen

0
QuestionC

Ja genau.

argv ist ein char** oder char*[] oder einfach ein Array von char * -Pointern.

Argv [0] ist also ein char* (eine Zeichenfolge) und argv[0][0] ist eine char.

0
blue112

Ja.

Der Typ von argv ist char**, d. H. Ein Zeiger auf einen Zeiger auf char. Wenn Sie char* als eine Zeichenfolge betrachten, ist argv ein Zeiger auf ein String-Array.

0
Peter K