2014-01-22 13 views
7

Ich habe den folgenden Code:Assign to Array in Struktur in c

typedef struct Test { 
    long mem[1000]; 
} Test; 

extern Test *test; 
int main() { 
    Test *test = (Test *)malloc(sizeof(Test)); 
    test->mem[0] = 1; 
    test->mem[1] = 2; 
    test->mem[2] = 3; 
    test->mem[3] = 4; 
    test->mem[4] = 5; 
    test->mem[5] = 6; 
    return 0; 
} 

Es ist OK zu arbeiten, aber ich mag das initialisiert des mem-Array ändern, so zu sein:

test->mem = {1,2,3,4,5,6}; 

Aber die gcc mir diesen Fehler geben:

error: expected expression before '{' token test->mem = {1,2,3,4,5,6}; With arrow pointing to the left open braces.

Was kann es sein?

Danke!

EDIT: Ich versuche auch, diesen Code:

long mem[1000] = {1,2,3,4,5,6}; 
    test->mem = mem; 

Und ich erhalte diesen Fehler von gcc:

error: incompatible types when assigning to type 'long int[1048576]' from type 'long int *' test->mem = mem;

Ich verwende nicht zulassen, dass alle C-Funktionen.

Antwort

10

Die Syntax something = { initial values } wird nur in Initialisierungen erlaubt, wo ein Objekt definiert ist, wie zum Beispiel:

long mem[1000] = { 1, 2, 3, 4, 5, 6 }; 

mit Ausdrücken wie x = value eineZuweisung ist und die Syntax für die Initialisierungen nicht verwenden kann.

Eine Alternative ist ein temporäres Objekt zu erstellen, die Sie initialisieren, und dann den Inhalt dieses temporären Objekt in das Ziel kopieren:

static const long temporary[] = { 1, 2, 3, 4, 5, 6 }; 
memcpy(test->mem, temporary, sizeof temporary); 

In Bezug auf die edit:

Arrays können nicht zugeordnet werden ; x = value ist nicht gültig, wenn x ein Array ist. Allerdings werden Strukturen zugewiesen werden, so dass eine weitere Alternative ist es, eine Struktur als temporäres Objekt zu erstellen, initialisieren, und weisen Sie ihm:

// (After the malloc is successful.) 
static const Test temporary = { { 1, 2, 3, 4, 5, 6 } }; 
*test = temporary; 

Beachten Sie jedoch, dass dieser Code etwas tut, der Stand der Code nicht. Das vorherige Beispiel, das ich zeigte, kopiert lediglich sechs Elemente in das Array. Dieser Code erstellt ein temporäres Objekt vom Typ Test, das 1000 Elemente enthält, von denen die meisten Null sind, und kopiert alle diese Elemente in *test. Selbst wenn der Compiler dies optimiert und etwas Code verwendet, um *test zu löschen, anstatt tatsächlich im Speicher gespeicherte Nullen zu kopieren, dauert es länger als nur sechs Elemente zu kopieren. Also, wenn Sie nur ein paar Elemente initialisiert haben wollen und sich nicht um den Rest kümmern, verwenden Sie den früheren Code. Wenn Sie alle Elemente initialisiert haben wollen (am meisten auf Null), können Sie den letzteren Code verwenden. (Trotzdem würde ich Alternativen, wie die Verwendung von calloc anstelle von malloc betrachten.)

+0

Bitte beachten Sie die Änderung in der Frage. – Nir

2

Arrays sind keine Zeiger (aber Arrays Zerfall auf Zeiger, siehe this) und Sie Arrays nicht zuordnen können ( sie nur initialisieren, oder struct -s ordnen sie enthält). Sie könnten das Array kopieren, z.

Test *test = (Test *)malloc(sizeof(Test)); 
if (!test) { perror("malloc"); exit(EXIT_FAILURE); }; 
static const int arr[] = {1,2,3,4,5,6}; 
memcpy (test->mem, arr, sizeof(arr)); 

BTW, könnte man ohne memcpyfor (int i=0; i<6; i++) test->mem[i] = arr[i]; durch Codierung Ihre Schleife kopieren ....

Dies lässt 9994 ganze Zahlen in test uninitialized; Sie könnten sie löschen wollen:

memset (test->mem+6, 0, 9994*sizeof(int)); 

oder eine andere for Schleife verwenden.

Sie könnten auch Ihre initialisierte Struktur definieren, z.

Test mystruct = {0, 2, 4, 6, 8}; 

dann zuweisen, z.

*test = mystruct; 

aber Sie können keine Arrays zuweisen! Auch

// wrong code, won't compile 
int ta[4] = { 0, 1, 2, 3}; // initialization, not assignment 
int tb[4] = { 2, 4, 6, 8}; // ditto 
int *tp = &ta; 
ta = tb; // wrong! 
tb = tp; // also wrong 

wird nicht kompilieren.

FWIW, C++11 hat std::array um darüber zu helfen.

Der §6.5.16.1 Einfache Zuweisung Abschnitt des C11 Standard (siehe n1570 Entwurf Seite 102) listet eine Reihe von Einschränkungen in Bezug auf Zuordnung und Array-Zuordnung paßt nicht da. Daher ist es verboten. Eine Faustregel besagt, dass nur Skalare (die Zeiger und numerische l-values enthalten) oder struct -s auf der linken Seite einer Zuweisung (oder return -ed von einer Funktion) angezeigt werden können.

+0

Sorry, ich verstehe nicht. warum test-> mem [0] = 1; arbeiten und testen-> mem = {1,2,3,4,5,6}; nicht? – Nir

+1

Ich sehe nicht, wie die Aussage "Arrays sind keine Zeiger" relevant ist. Der Code in der Frage versucht nicht, einen Zeiger als ein Array oder umgekehrt zu verwenden. Das Problem besteht darin, eine Zuweisung mithilfe der Initialisierungssyntax zu versuchen. –

+1

@EricPostpischil Ich glaube, dass es mit dem letzten Schnitt zur Frage relevant geworden ist. – ApproachingDarknessFish