Ich bin ein wenig überrascht von Folgendem.
Beispiel 1:
char s[100] = "abcd"; // declare and initialize - WORKS
Beispiel 2:
char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)
Ich frage mich, warum der zweite Ansatz nicht funktioniert. Es scheint natürlich, dass es sollte (es funktioniert mit anderen Datentypen)? Könnte mir jemand die Logik dahinter erklären?
s[0] = 'x'; s[1] = 'y'; s[2] = 'z'; s[3] = 'm';
funktioniert, wenn man die Zeichenketten auch nach der Initialisierung einzeln ersetzen möchte.char s[100]; s = "abcd";
Fehlern ist absolut sinnvoll, da s effektiv als konstanter Zeiger behandelt wird. Wenn wir also versuchen, "abcd" in der zweiten Zeile zuzuweisen, versuchen wir, den Wert des Zeigers zu ändern, der nicht zulässig ist. Wenn jedoch ein const-Zeiger auf einen Speicherort zeigt, sollte der Inhalt des Speicherorts natürlich geändert werden können. Angenommen,s
zeigt auf Speicherplatz 1000, dann enthält s 1000 und Speicherplatz # 1000 enthält a. Ich kann s nicht ändern, um einen neuen Speicherort zu speichern, z. B. 2000, aber ich kann ein neues Zeichen, z. B. z, an einem Speicherort 1000 speichern.In C gibt es keine "Zeichenfolge". In C sind Zeichenfolgen ein eindimensionales Array von
char
, das durch ein Nullzeichen abgeschlossen wird\0
. Da Sie in C keine Arrays zuweisen können, können Sie auch keine Zeichenfolgen zuweisen. Das wörtliche "Hallo" ist syntaktischer Zucker fürconst char x[] = {'h','e','l','l','o','\0'};
Der richtige Weg wäre:
char s[100]; strncpy(s, "hello", 100);
oder noch besser:
#define STRMAX 100 char s[STRMAX]; size_t len; len = strncpy(s, "hello", STRMAX);
quelle
Initialisierung und Zuweisung sind zwei unterschiedliche Operationen, die hier zufällig denselben Operator ("=") verwenden.
quelle
1 char s[100]; 2 s = "hello";
In dem von Ihnen angegebenen Beispiel wird s tatsächlich in Zeile 1 und nicht in Zeile 2 initialisiert. Obwohl Sie ihm zu diesem Zeitpunkt keinen expliziten Wert zugewiesen haben, hat der Compiler dies getan. In Zeile 2 führen Sie eine Zuweisungsoperation aus, und Sie können ein Array von Zeichen keinem anderen Array von Zeichen wie diesem zuweisen. Sie müssen strcpy () oder eine Art Schleife verwenden, um jedes Element des Arrays zuzuweisen.
quelle
char s[6]
genugUm Sparrs Antwort zu erweitern
Stellen Sie sich das so vor:
Stellen Sie sich vor, es gibt zwei Funktionen:
InitializeObject
undAssignObject
. Wenn der Compiler siehtthing = value
, sieht er sich den Kontext an und ruft einen auf,InitializeObject
wenn Sie einen neuen erstellenthing
. Wenn nicht, wird stattdessen angerufenAssignObject
.Normalerweise ist dies in Ordnung
InitializeObject
undAssignObject
verhält sich normalerweise genauso. Außer beim Umgang mit Char-Arrays (und einigen anderen Randfällen) verhalten sie sich in diesem Fall anders. Warum das? Nun, das ist ein ganz anderer Beitrag, der den Stapel gegen den Haufen und so weiter und so fort betrifft.PS: Abgesehen davon hilft Ihnen das Denken auf diese Weise auch dabei, Kopierkonstruktoren und andere solche Dinge zu verstehen, wenn Sie sich jemals in C ++ wagen
quelle
Beachten Sie, dass Sie noch Folgendes tun können:
s[0] = 'h'; s[1] = 'e'; s[2] = 'l'; s[3] = 'l'; s[4] = 'o'; s[5] = '\0';
quelle
Ich weiß, dass dies bereits beantwortet wurde, aber ich wollte eine Antwort teilen, die ich jemandem gegeben habe, der in einer C / C ++ - Facebook-Gruppe eine sehr ähnliche Frage gestellt hat.
Arrays haben keine Zuweisungsoperatorfunktionen *. Dies bedeutet, dass Sie einem Zeichenfolgenliteral nicht einfach ein char-Array zuweisen können. Warum? Weil das Array selbst keinen Zuweisungsoperator hat. (* Es ist ein konstanter Zeiger, der nicht geändert werden kann.)
Um ein Zeichenfolgenliteral (wie
"Hello world"
oder"abcd"
) in Ihr Zeichenarray zu kopieren, müssen Sie alle Zeichenelemente des Zeichenfolgenliteral manuell in das Array kopieren.char s[100];
Dadurch wird ein leeres Array mit der Länge 100 initialisiert.Verwenden Sie nun, um Ihr String-Literal in dieses Array zu kopieren
strcpy
strcpy(s, "abcd");
Dadurch wird der Inhalt aus dem Zeichenfolgenliteral"abcd"
kopiert und in dass[100]
Array kopiert .Hier ist ein großartiges Beispiel dafür, was es tut:
int i = 0; //start at 0 do { s[i] = ("Hello World")[i]; //assign s[i] to the string literal index i } while(s[i++]); //continue the loop until the last char is null
Sie sollten natürlich
strcpy
anstelle dieses benutzerdefinierten String-Literal-Kopierers verwenden, aber es ist ein gutes Beispiel, das erklärt, wiestrcpy
grundlegend funktioniert.Hoffe das hilft!
quelle
Sie können dies verwenden:
yylval.sval=strdup("VHDL + Volcal trance...");
Wobei yylval char * ist. strdup von macht den Job.
quelle
Was ich verwenden würde, ist
char *s = "abcd";
quelle
const char*
.