2016-12-10 4 views
4

Ich habe dieses kleine Programm:Inkrementieren Zeiger auf mehrdimensionales Array in C

#include <stdio.h> 

int main() { 
    char *argv[3] = {{"abc"}, {"def"}, {"ghi"}}; 

    printf("%c\n", (*++argv)[1]); //error. I wanted to print 'b' 
    printf("%c\n", *++argv[1]); //prints e 

    return 0; 
} 

die Fehlermeldung:

error: cannot increment value of type 'char *[3]' 
printf("%c\n", (*++argv)[1]); 

Ich möchte argv zu erhöhen, um b zu zeigen. Ich nahm diese Verwendung (*++argv)[i] gerade aus C-Programmiersprache von K & R, wo sie ein Beispiel auf Seite 117 auf argv inkrementieren genau wie ich. Sie weisen auch darauf hin, dass (*++argv)[0] der Zeiger auf das erste Zeichen in einer Zeichenfolge ist, während *++argv[0] den Zeiger argv[0] inkrementiert. Tatsächlich wird (*argv)[1]b drucken, während *argv[1]d drucken wird. Doch irgendwie inkrementell (*++argv)[0] bleiben nur Fehler.

+1

Sie haben ein Array von Zeigern, kein Zeiger auf Array. und die Art, wie "argv" deklariert wird, könnte anders sein. Ich denke in k & r deklarierte es als "char **". – user3528438

+1

wird es hilfreich sein, wenn Sie die Fehlermeldung anzeigen. In diesem Fall erhalten Sie den Fehler, weil 'argv' ein Array ist und Sie' '' '' '' nicht verwenden können, da sein Wert nicht geändert werden kann. – user3528438

Antwort

3

Zuerst dies:

char *argv[3] = {{"abc"},{"def"},{"ghi"}}; 

Sollte dies sein, wie andere schon angemerkt:

char *argv[3] = {"abc", "def", "ghi"}; 

Zweitens, was Sie getan haben, ist nicht das, was die K & R Buch der Fall ist.

Array-Namen verhalten sich wie konstante Zeiger, also können Sie sie nicht so ändern, wie Sie es mit dem argv = argv + 1 versucht haben (erweiterte Version von ++argv).

Aber das Buch hat, das zu einem argvin dem Haupt von der Kommandozeile weitergegeben, so dass, wenn char* argv[] Haupt eintritt, es zerfällt auf einen Zeiger auf Zeiger (char**) und dann, ja, Sie (*++argv)[1] Arbeit machen könnten wenn Sie die Zeichenfolgen als Befehlszeilenargumente übergeben.

Versuchen Sie, einen falschen argv innerhalb main zu erstellen, wie Sie, und vergleichen Sie die zugehörigen Adressen mit den Adressen im Zusammenhang mit einem echten argv in Main über die Befehlszeile übergeben.

Sie werden sehen, dass man ein char** und das andere ist ein char* array:

#include <stdio.h> 

int main(int argc, char* argv[]) 
{  
    printf("argv:  %p\n", argv); 
    printf("&argv[0]: %p\n", &argv[0]); 
    printf("&argv: %p\n\n", &argv); 

    char* bogus_argv[] = {"abc", "def", "ghi"}; 
    printf("bogus_argv:  %p\n", bogus_argv); 
    printf("&bogus_argv[0]: %p\n", &bogus_argv[0]); 
    printf("&bogus_argv: %p\n\n", &bogus_argv); 

    printf("%c\n", (*++argv)[1]); // prints 'b' 
    printf("%c\n", *++argv[1]); // prints 'e' 

    return 0; 
} 

Run: ./program abc def ghi

Ausgang auf meinem Rechner:

argv:  0x7ffcde5aca98 
&argv[0]: 0x7ffcde5aca98 
&argv: 0x7ffcde5ac9a0 

bogus_argv:  0x7ffcde5ac980 
&bogus_argv[0]: 0x7ffcde5ac980 
&bogus_argv: 0x7ffcde5ac980 

b 
e 
1

Sie haben einen Fehler gemacht mit Array Ihre Deklaration. Es sollte dir eine Warnung sein. Es sollte

char *argv[3] = {"abc","def","ghi"}; 

Die inneren Klammern sind nicht notwendig sein als Strings char Zeiger und daher „arrays“ sind.

Sie könnten eine zweite Zeigervariable deklarieren und weisen es argv:

p
char ** p; 
p = argv; 

und dann erhöhen.

Last but not least, wenn Sie zuerst b und dann e drucken möchten, müssen Sie den Operator "++" hinter die Variable setzen. Andernfalls würde der Zeiger vor der Auswertung erhöht und Sie würden e und h drucken.

+0

guter Punkt mit den Klammern. Ich habe das Array neu deklariert, trotzdem bekomme ich den gleichen Fehler. – Yos

+0

Was ist mit den anderen Dingen, die ich erwähnt habe? –

+0

Erstellen von p hat auch nicht geholfen. Inkrementieren, guter Punkt, aber das Hauptproblem besteht weiter. – Yos

2

Das Beispiel von K & R bezieht sich auf argv wie definiert als zweites Argument für die Funktion main. Ihre Definition ist anders, Sie definieren ein Array von 3 Zeigern zu Strings, während das Funktionsargument ein Zeiger zu einem solchen Array ist.

Die Syntax des Funktionsprototyps ist etwas irreführend, da dieselbe Syntax für einen anderen Objekttyp verwendet wird. Einige Leute bevorzugen diese Syntax:

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

Mit diesem Prototyp, die Art der argv (ein Zeiger auf einen Zeiger auf char) scheint mehr explizit, aber viele Programmierer bevorzugen die äquivalente char *argv[] Syntax, um die Tatsache zu unterstreichen, dass argv Punkte ein Array von Zeigern im Gegensatz zu einem einzelnen Zeiger.

argv Da es sich um ein Array in Ihrem Code handelt, können Sie es nicht inkrementieren. Dies erklärt, warum Sie einen Fehler für printf("%c\n", (*++argv)[1]); erhalten.

Sie können Ihr Programm diese Art und Weise ändern:

#include <stdio.h> 

int main(void) { 
    char *argument_array[4] = { "abc", "def", "ghi", NULL }; 
    char **argv = argument_array; 

    printf("%c\n", (*++argv)[1]); // will print 'e' instead of 'b' 
    printf("%c\n", *++argv[1]); // prints 'h', not 'e' 

    return 0; 
} 

Beachten Sie auch, dass Sie die redundante {} in der Initialisierungsliste entfernen sollte, und der ++ Operator ist Präfix, so ist der Ausgang nicht genau das, was Sie erwarten.