Ich denke, in meinem Fall ist es am bequemsten, anstatt jedes Element zuzuweisen, jedes gewünschte Array in ein globales Array zu kopieren. Vielen Dank
– David H
29. Juni 2010 um 3:59 Uhr
+1 für C99. 😉 memcpy(myarray,(int [sizeof(myarray)/sizeof(myarray[0])]{1,2,3,4}, Größe meines Arrays); um den Rest auf die entsprechende Null zu initieren.
– Nyan
29. Juni 2010 um 6:31 Uhr
@Nyan: Tolle Idee. Dies löst auch einen Fehler aus, wenn zu viele Initialisierer vorhanden sind.
– AnT steht zu Russland
29. Juni 2010 um 6:52 Uhr
Ich habe einen Nachtrag zu Ihrer Antwort gepostet, der auch einen Kompilierzeitfehler auslöst, falls dies auch der Fall ist wenig Initialisierer.
– Joseph Quinsey
30. Juni 2010 um 14:38 Uhr
paxdiablo
Nein, Sie können sie nicht in einer Anweisung auf beliebige Werte setzen (es sei denn, dies ist Teil der Deklaration).
Sie können es entweder mit Code tun, so etwas wie:
Die andere Möglichkeit besteht darin, einige Vorlagen beizubehalten sind zum Zeitpunkt der Deklaration gesetzt und verwenden Sie sie, um Ihr Array zu initialisieren, etwa so:
Dies hat den Vorteil, dass es (höchstwahrscheinlich) schneller ist und es Ihnen ermöglicht, kleinere Arrays als die Vorlagen zu erstellen. Ich habe diese Methode in Situationen verwendet, in denen ich ein Array schnell neu initialisieren muss, aber auf einen bestimmten Zustand (wenn der Zustand alle Nullen wäre, würde ich einfach verwenden memset).
Sie können es sogar auf eine Initialisierungsfunktion lokalisieren:
Das statische Array wird (mit ziemlicher Sicherheit) zur Kompilierzeit erstellt, sodass dafür keine Laufzeitkosten anfallen, und das memcpy sollte unglaublich schnell sein, wahrscheinlich schneller als 1.229 Zuweisungsanweisungen, aber auf jeden Fall weniger Tipparbeit von Ihrer Seite :-).
Gibt es eine Möglichkeit, ein Array in C zuerst zu deklarieren und dann zu initialisieren?
Es gibt! aber nicht mit der Methode, die Sie beschrieben haben.
Sie können nicht mit einer kommaseparierten Liste initialisieren, dies ist nur in der Deklaration erlaubt. Sie können jedoch initialisieren mit …
myArray[0] = 1;
myArray[1] = 2;
...
oder
for(int i = 1; i <= SIZE; i++)
{
myArray[i-1] = i;
}
Danke, aber was ich gesucht habe, war, es in einer durch Kommas getrennten Liste initialisieren zu können, weil diese Arrays sehr groß sein werden und ich dachte, dass es auf diese Weise bequemer wäre.
– David H
29. Juni 2010 um 3:53 Uhr
Josef Quinsey
Dies ist ein Nachtrag zur akzeptierten Antwort von AndreyT mit Nyans Kommentar zu nicht übereinstimmenden Array-Größen. Ich bin mit ihrer automatischen Einstellung des fünften Elements auf Null nicht einverstanden. Es sollte wahrscheinlich sein 5 –die Zahl nach 1,2,3,4. Also würde ich memcpy() einen Wrapper vorschlagen, um a zu erzeugen Kompilierzeit Fehler, wenn wir versuchen, Arrays unterschiedlicher Größe zu kopieren:
#define Memcpy(a,b) do { /* copy arrays */ \
ASSERT(sizeof(a) == sizeof(b) && /* a static assert */ \
sizeof(a) != sizeof((a) + 0)); /* no pointers */ \
memcpy((a), (b), sizeof (b)); /* & unnecesary */ \
} while (0) /* no return value */
Dieses Makro generiert einen Kompilierungsfehler, wenn Ihr Array die Länge 1 hat. Das ist vielleicht ein Feature.
Da wir ein Makro verwenden, scheint das zusammengesetzte C99-Literal ein zusätzliches Paar Klammern zu benötigen:
Memcpy(myarray, ((int[]) { 1, 2, 3, 4 }));
Hier ist ASSERT() ein ‘statisches Assertion’. Wenn Sie noch keine eigene haben, verwende ich Folgendes auf einer Reihe von Plattformen:
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum {EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
#define ASSERTM(e,m) /* version of ASSERT() with message */ \
enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
Warum können Sie nicht initialisieren, wenn Sie deklarieren?
Welchen C-Compiler verwendest du? Unterstützt es C99?
Wenn C99 unterstützt wird, können Sie die Variable dort deklarieren, wo Sie sie benötigen, und sie initialisieren, wenn Sie sie deklarieren.
Die einzige Entschuldigung, die mir dafür einfällt, wäre, dass Sie es deklarieren müssen, aber vor der Verwendung einen frühen Exit durchführen müssen, sodass der Initialisierer verschwendet würde. Ich vermute jedoch, dass ein solcher Code nicht so sauber organisiert ist, wie er sein sollte, und so geschrieben werden könnte, dass dies kein Problem darstellt.
Danke für die schnelle Antwort! Ich muss nach der Deklaration initialisieren, da dies je nach Bedingung unterschiedlich sein wird, ich meine so etwas wie dieses int myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, …} } else if(condition2) { myArray{y1, y2, y3, …} } . . usw. Ich verwende XCode
– David H
29. Juni 2010 um 3:47 Uhr
Sind die Arrays konstant? Wenn dies der Fall ist, besteht eine Möglichkeit darin, zwei separat initialisierte konstante Arrays zu verwenden und dann einen Zeiger (auf konstante Daten) so zu setzen, dass er auf das relevante Array zeigt. Sie würden die Arrays auch statisch machen. Wenn die Arrays nicht konstant sind, müssen Sie meines Erachtens nacheinander jedes Element berechnen.
– Jonathan Leffler
29. Juni 2010 um 5:13 Uhr
Ja, die Arrays sind konstant, ich werde diese Methode auch ausprobieren, danke.
– David H
29. Juni 2010 um 13:47 Uhr
Das OP ließ einige wichtige Informationen aus der Frage aus und fügte sie nur in einen Kommentar zu einer Antwort ein.
Ich muss nach der Deklaration initialisieren, da dies je nach Bedingung unterschiedlich sein wird, ich meine so etwas wie dieses int myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, …} } else if(condition2) { myArray{y1, y2, y3, …} } . . usw…
Vor diesem Hintergrund müssen alle möglichen Arrays sowieso irgendwo in Daten gespeichert werden, sodass kein Memcpy erforderlich (oder erwünscht) ist, sondern nur ein Zeiger und ein 2d-Array erforderlich sind.
//static global since some compilers build arrays from instruction data
//... notably not const though so they can later be modified if needed
#define SIZE 8
static int myArrays[2][SIZE] = {{0,1,2,3,4,5,6,7},{7,6,5,4,3,2,1,0}};
static inline int *init_myArray(_Bool conditional){
return myArrays[conditional];
}
// now you can use:
//int *myArray = init_myArray(1 == htons(1)); //any boolean expression
Die nicht-inline-Version gibt diese resultierende Assembly auf x86_64:
Für zusätzliche Bedingungen/Arrays ändern Sie einfach die 2 in myArrays in die gewünschte Zahl und verwenden eine ähnliche Logik, um einen Zeiger auf das richtige Array zu erhalten.
Danke für die schnelle Antwort! Ich muss nach der Deklaration initialisieren, da dies je nach Bedingung unterschiedlich sein wird, ich meine so etwas wie dieses int myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, …} } else if(condition2) { myArray{y1, y2, y3, …} } . . usw. Ich verwende XCode
– David H
29. Juni 2010 um 3:47 Uhr
Sind die Arrays konstant? Wenn dies der Fall ist, besteht eine Möglichkeit darin, zwei separat initialisierte konstante Arrays zu verwenden und dann einen Zeiger (auf konstante Daten) so zu setzen, dass er auf das relevante Array zeigt. Sie würden die Arrays auch statisch machen. Wenn die Arrays nicht konstant sind, müssen Sie meines Erachtens nacheinander jedes Element berechnen.
– Jonathan Leffler
29. Juni 2010 um 5:13 Uhr
Ja, die Arrays sind konstant, ich werde diese Methode auch ausprobieren, danke.
– David H
29. Juni 2010 um 13:47 Uhr
Es ist nicht möglich, einem Array nach der Initialisierung alle Werte auf einmal zuzuweisen. Die beste Alternative wäre die Verwendung einer Schleife.
for(i=0;i<N;i++)
{
array[i] = i;
}
Sie können Werte fest codieren und zuweisen wie —array[0] = 1 usw.
Memcpy kann auch verwendet werden, wenn Sie die Daten bereits in einem Array gespeichert haben.
14113500cookie-checkDeklarieren und Initialisieren von Arrays in Cyes