2013-04-10 6 views
5

Warum kann ich nicht zeigen Char ** auf Array von C-Strings ??char ** vs char * c [] für den Zugriff auf ein String-Array

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

    char* c1[] = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //works fine 

vs

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

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 
+6

Zeiger sind keine Arrays. –

Antwort

6

Ich denke, die Verwirrung hier stammt aus der Überzeugung, dass {"Hey","Hello"} ein Array ist. Es ist nicht. Es ist überhaupt kein Objekt. Es ist nur eine spezielle Initialisierungssyntax, die zum Initialisieren eines Arrays verwendet werden kann. Sie können es nicht verwenden, um ein char** zu initialisieren, da ein char** ein Zeiger und kein Array ist. Es erstellt nicht automatisch ein Array-Objekt, das Sie in einen Zeiger konvertieren können.

Vielleicht haben Sie daran gedacht wie eine [...] Liste in Python oder ein { ... } Objekt in JavaScript. Es ist überhaupt nicht wie diese. Diese Ausdrücke erzeugen tatsächlich Objekte dieses Typs und können überall in einem Ausdruck verwendet werden, der diese Objekte aufnehmen kann.Die Syntax, die wir in C++ verwenden, ist nur eine Initialisierungssyntax.

Zum Beispiel Sie könnte dies tun:

const char* array[] = {"Hey","Hello"}; 
const char** p = array; 

Sie können jedoch nicht etwas Dummes tun, wie folgt:

std::cout << {"Hey", "Hello"}[1]; 

Hier haben wir tatsächlich das Array-Objekt erstellt, in dem die Zeiger werden gespeichert. Nur dann können wir dieses Array in eine const char** konvertieren.

+0

Sehr klar..dannxxx – tez

1

Warum kann ich weis ein char** auf Anordnung von C-Strings?

Wie Sie gesagt haben, c1 ist ein Array. Sie müssen es also als Array von Zeigern zu char deklarieren.

Seit "Hey" und "Hello" sind String litterals, jede c1[i] Saite ist einem anonymen Zeichenfolge zeigt. Deshalb können Sie anstelle von Arrays von char Zeiger auf char verwenden.

Um ein Array von Zeigern auf char zu erstellen, können Sie jedoch kein char ** verwenden.

2

Änderung

char** c1 = (char *[]){"Hey","Hello"};

0

"char ** c1", sagt Compiler, der einen Zeiger auf einen Zeiger für Typ char, ist skalaren Typ (ein Wert).

Die Initialisierung mit einer Werteliste funktioniert nur für Aggregattypen.

+0

Es gibt keine Mehrdeutigkeit in 'char ** c1'. Es ist ein Zeiger auf einen Zeiger auf 'char'. (Natürlich können beide Zeiger im obigen Beispiel für das erste Element eines Arrays stehen.) –

+0

@James Kanze, ja, mein Fehler. Löschte es. – Arun

0
int main(int argc, char *argv[]) { 

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 

In dem obigen Code versuchen Sie, einen Zeiger auf einen Zeiger auf eine Gruppe von zwei Zeichenfolgen festzulegen. Wo ist der Speicher für die beiden Zeiger, die die Adresse "Hey" bzw. "Hallo" enthalten? Nirgends.

Sie könnten tun:

char *a = "Hey"; 
char *b = "Hello"; 
char *c[] = { a, b };  // This MAY not compile due to a and b not being compile time constants. 
char **c1 = c; 

(Ich habe es aufgeteilt in mehrere einzelne Variablen auf, als es tatsächlich braucht, aber ich denke, es wird erklärt, was ganz klar „falsch“ mit Ihrem Code ist).

Ein anderes Beispiel wäre, wenn wir die char * in int ändern:

const int a = 1; 
const int b = 2; 

int c[] = { a, b }; 

int *c = { a, b }; // Doesn't work, there is nowhere to store a copy of a and b. 

Es ist das Gleiche, nur mit ganzen Zahlen.