2017-03-04 7 views
4

Ich bin relativ neu in Coding und habe einige Probleme zu verstehen, wie Zeiger in Kombination mit Arrays arbeiten (die ich für sich verstehe). IchVerwendung eines Zeigers auf ein Char-Array in C++

verstanden, dass es möglich ist, einen Array von Zeigern wie zu erstellen:

#include <iostream> 
using namespace std; 

int main() { 
    int i; 
    int *pArr[10]; 
    pArr[0]=&i; 
    return 0; 
} 

In einem Tutorial ich dann den folgenden Code gefunden:

#include <iostream> 
using namespace std; 

int main() { 
    char *names[4] = { 
     "name A", 
     "name B", 
     "name C", 
     "name D" 
}; 

for (int i = 0; i < 4; i++) { 
    cout << names[i] << endl; 
} 
return 0; 
} 

Warum ist es, dass ich mehr zuweisen Zeichen, oder um eine Zeichenfolge wie "Name A" zu einem Zeiger zu sagen, der auf ein Zeichen zeigen sollte.

Sollte ich nicht A:

Nur in der Lage sein, um die Adresse eines char auf jede dieser vier Zeiger zuweisen ich herstellte.

Und B:

Nur in der Lage sein, einen Zeiger zuweisen, auf einen einzigen Buchstaben (a char), zu jedem.

Ich hoffe, jemand kann helfen, meine Verwirrung zu einem gewissen Grad zu beseitigen.

+1

'" Name A "' s Typ ist eigentlich 'const char *'. –

+1

1. Bitte lesen Sie "const" 2. "Mit std ist schlecht" - google auch –

+0

Sehen Sie einige nützliche Compiler-Warnungen hier: http://coliru.stacked-crooked.com/a/f67971a42cebd76f –

Antwort

1

Jedes Zeichen * zeigt auf das erste Zeichen in der Zeichenfolge. Wenn Sie eine literale Zeichenfolge sehen, die "mystring" eingebettet ist, zeigt ein char * auf das "m" von "mystring".

Der Befehl cout ist so aufgebaut, dass beim Übergeben einer char * -Variable alle Zeichen ab dieser Speicheradresse gedruckt werden, bis ein Nullbyte (Binärwert 0, nicht das geschriebene Zeichen "0") erreicht wird.

Das Endergebnis ist, dass Sie tatsächlich die char * Zeiger erhöhen können kürzeren Strings zu erhalten. z.B. Wenn Sie 1 zu einem Zeiger hinzufügen, der auf "mystring" zeigt, würde er jetzt auf "ystring" zeigen. Ihre Annahme war also grundsätzlich richtig, ein Zeichen * zeigt auf einen Buchstaben, nicht auf das ganze Wort.

3

In C (und C++) hat ein Zeichenfolgenliteral (ein Ausdruck wie) den Typ const char*. Unter der Haube werden diese Zeichenfolgen irgendwo im Datenbereich der Binärdatei gespeichert. Und das String-Literal wird durch den Zeiger auf das erste dieser Zeichen ersetzt. So wird die folgende Erklärung

char *names[4] = { 
    "name A", 
    "name B", 
    "name C", 
    "name D" 
}; 

Weist den Compiler vier Saiten in dem Datenabschnitt zuzuteilen, und dann names vier Zeiger auf die Zeigerfeld zuzuordnen.

+5

In C++ kann String-Literal 'const char *' zugewiesen werden, aber in C können Sie es auch 'char *' zuweisen. Dies ist jedoch * nicht * der Typ des String-Literals - String-Literale sind keine Zeichenzeiger, sie sind Zeichen-Arrays. – dasblinkenlight

+0

Zum zweiten ... 'std :: cout << typeid (" foo ") .name()' druckt "char const [4]". Die richtige Erklärung wäre also, dass es sich um ein Zeichen-Array handelt und der Compiler das Array durch einen Zeiger auf das erste Zeichen ersetzt. – zett42

+0

Der String-Literaltyp ist 'const char [7]', nicht 'const char *' Die Konvertierung von Array in einen Zeiger prvalue findet nur in einigen Kontexten statt –

2

Sie haben ein Array mit 4 Pointern auf char erstellt.

A "string Litteral" ist ein Array von char. Und die Adresse dieses Arrays ist ein Zeiger auf char. Also kein Problem, es in Ihr Array von Zeigern zu setzen.

Jetzt sieht Ihr Code kompilieren? Oder beschwert es über das Mischen von char * und const char *? Dies wäre eine andere Frage, für die es bereits viele Antworten auf SO

+0

Vor C++ 11 war es erlaubt (aber veraltet) a zuzuweisen Zeichenfolgenliteral zu 'char *' –

6

Dies ist eine Abkürzung durch den Compiler angeboten, um es einfacher für Programmierer Strings in ihrem Code enthalten.

Wenn Sie eine Stringliteral"name A" schreiben, bereitet der Compiler einen Sieben-Zeichen-Array für Sie:

const char hidden0[] = {110, 97, 109, 101, 32, 65, 0}; // "name A" 

Die ersten sechs Ziffern entsprechen den Zeichencodes von Symbolen in der Zeichenkette. Das letzte Zeichen ist Null - der sogenannte Null-Terminator.

Der Compiler macht das gleiche für alle vier Stringliterale, so dass Ihr Feldinitialisierung sieht wie folgt aus:

const char *names[4] = { 
    &hidden0[0], 
    &hidden1[0], 
    &hidden2[0], 
    &hidden3[0] 
}; 

hiddenK das Array für die entsprechende Stringliteral erstellt ist. Es hat keinen Namen, aber der Compiler kennt seine Adresse und speichert sie im Array name[].

Verwandte Themen