2009-03-13 16 views
3

Betrachten Sie eine typische Umgebung, warum ist der folgende Code in C illegal?Warum ist der folgende C-Code illegal?

{ 
int x; 
&x = (int*) malloc(3*sizeof(int)); 
... 
} 
+0

Warum wurde dies als "Hausaufgabe" markiert?Ich sehe nichts, was darauf hindeutet, dass es Hausaufgaben sind. –

+0

Die meisten dieser Antworten sind die gleichen. Warum nicht die Antworten stimmen, auf die man sich einigt, statt sie zu revanchieren? –

+0

@Ctrl Alt D-1337: Ich stimme respektvoll nicht zu. Einige Antworten sind subtil unterschiedlich und/oder erklären das Problem anders. Für jemanden, der sich nicht in der Sache auskennt, können die unterschiedlichen Standpunkte zu einem vollständigeren Verständnis führen. – bernie

Antwort

30

Man kann nicht etwas an die Adresse x zuweisen, weil er Adresse x ist ein nicht lvalue

(An lvalue ist „etwas, das zugewiesen werden kann“, dh es ist nicht auf die sein kann L inks Seite eines Gleichheitszeichen)

Versuchen

int* x; 
x = (int*) malloc(3*sizeof(int)); // TODO: Call free(x) 

Jetzt x Punkte auf Ihren zugewiesenen Speicher und Sie können Dinge wie

int foo = *x; 
int bar = x[0]; 

können Sie zuweisen die Adresse x- etwas anderes, durch die & Betreiber auf diese Weise mit:

int x = 1; 
int* y = &x; // y now holds the address of x 
*y = 2;  // Now x = 2 
2

Die Adresse einer Variablen kann nicht geändert werden. Stattdessen möchten Sie wahrscheinlich etwas in der Art:

int *x = (int *)malloc(3 * sizeof(int)); 
... 
free(x); 
+0

Selbst wenn x auf dem Heap war, würde der Code nicht funktionieren. (Z. B. bei Verwendung globaler Variablen.) – strager

+0

Guter Punkt, bearbeitet, um zu klären. – NilObject

0

So ist die Sprache konzipiert. Um zu tun, was Sie wollen, verwenden Sie einen Zeiger.

11

Da die Adresse von x kein Lvalue ist, kann sie nicht geändert werden. C erlaubt Ihnen, Dinge zu ändern, auf die Adressen zeigen - es erlaubt Ihnen nicht, die Adressen selbst zu ändern.

+0

Also Adressen sind nicht L-Werte, weil Sie ihnen nicht zuweisen können? – KingNestor

+0

Ein Lvalue ist definiert als etwas, das Sie zuweisen können. Wenn Sie es also nicht zuweisen können, ist es definitionsgemäß kein lvalue. –

+1

KingNestor, es ist kein lvalue, weil es nicht irgendwo gespeichert werden muss. Lvalue bedeutet "hat einen Ort". historisch bedeutet lvalue linkswert und ist die linke seite einer aufgabe - aber das ist geschichte. Beispiele für lvalues, die nicht zugewiesen werden können, sind Arrays und Konstanten (z. B. const int). –

1

& x gibt Zeiger auf x zurück. Sie können es nicht im linken Teil einer Aufgabe verwenden, nur auf der rechten Seite.

Wenn Sie einem Zeiger etwas zuweisen möchten, müssen Sie ihn als Zeiger deklarieren, genau wie int * x;

3

Jeder hat Recht. Die Adresse von X zum Zeitpunkt der Codeausführung ist CONSTANT. Mit anderen Worten, es heißt "Hey, du kannst CHANGE, wo ich, der Compiler, die 'x' Variable speichern kann."

könnten Sie tun dies

int main() 
{ 
    int* x; 
    *(&x) = malloc(3*sizeof(int)); 

} 
1

Nicht, dass dies ganz wertvoll ist, aber da sonst niemand brachte es auf (alle oben genannten Antworten sind richtig, btw, und überflüssig, ich bin einverstanden, dass die Menschen die Abstimmung sollte richtig antworten, anstatt immer wieder dasselbe zu sagen).

In Ihrem Beispiel ist x eine Stapelvariable. malloc gibt Ihnen Heap-Speicher. Das ist wahrscheinlich nichts, worüber Sie in der heutigen Programmierung zu viel nachdenken sollten, aber wenn Sie jemals in einer Umgebung arbeiten, in der der Arbeitsspeicher knapp ist, sollten Sie Ihren Stack so gut wie möglich speichern.

Es ist auch erwähnenswert, dass Sie aus irgendeinem Grund 3 * sizeof (int) zuweisen. Selbst wenn Sie Speicher dem Stack zuweisen könnten, in Ihrem Beispiel, da Sie nur versuchen, 1 int zu bekommen, würden Sie nur 1 * sizeof (int) benötigen, der Rest wäre verschwendet.

Verwandte Themen