2009-10-17 13 views
5

In höheren Sprachen wäre ich in der Lage etwas ähnliches zu diesem Beispiel in C und es wäre in Ordnung. Wenn ich jedoch dieses C-Beispiel kompiliere, beklagt es sich bitter. Wie kann ich dem von mir deklarierten Array neue Arrays zuweisen?Einfache C-Array-Deklaration/Zuweisung Frage

int values[3]; 

if(1) 
    values = {1,2,3}; 

printf("%i", values[0]); 

Danke.

+1

Sehen Sie hier einige Ideen: http: // Stackoverflow.com/questions/1223736/c-ändern-alle-Werte-eines-Array-von-Strukturen-in-One-Linie/1223806 # 1223806 –

Antwort

1

Sie können mit Daten statische Array deklarieren zu initialisieren aus:

static int initvalues[3] = {1,2,3}; 
… 
if(1) 
    memmove(values,initvalues,sizeof(values)); 
+0

Kann ich nicht memmove (Werte, {1,2,3}, sizeof (Werte)); ? –

+0

Nein, du kannst es nicht so machen. – hlovdal

+1

Ich denke, du könntest: memmove (Werte, (int [3]) {1,2,3}, sizeof (int [3])); Siehe meine Antwort unten. –

11

Sie können nur Mehrfachbelegung des Arrays zu tun, wenn Sie das Array deklarieren:

int values[3] = {1,2,3}; 

Nach Erklärung, werden Sie jeden Wert individuell zuweisen müssen, dh

if (1) 
{ 
    values[0] = 1; 
    values[1] = 2; 
    values[2] = 3; 
} 

Oder Sie könnte eine Schleife verwenden, abhängig davon, welche Werte Sie verwenden möchten.

if (1) 
{ 
    for (i = 0 ; i < 3 ; i++) 
    { 
    values[i] = i+1; 
    } 
} 
+0

Dies funktioniert für 3 Werte, aber was wäre, wenn ich ein Array mit 50 Werten hätte ? –

+0

Dann würden Sie eine Schleife verwenden, oder Sie würden "memmove"/"memcpy" wie @hacker schlägt in einer anderen Antwort vor. –

+0

memcpy scheint am saubersten. Danke für Ihre Hilfe. –

2
//compile time initialization 
int values[3] = {1,2,3}; 

//run time assignment 
value[0] = 1; 
value[1] = 2; 
value[2] = 3; 
6

In C99, compound literals verwenden, können Sie tun:

memcpy(values, (int[3]){1, 2, 3}, sizeof(int[3])); 

oder

int* values = (int[3]){1, 2, 3}; 
+3

+1; Denken Sie daran, dass das Array im letzteren Fall eine automatische Speicherdauer hat, dh dass es bei einer Rückkehr von einer Funktion zu einem Grue – Christoph

+0

Christoph führt, würde das bedeuten, dass 'memove' aus einem solchen Array zuerst initialisiert werden müsste im automatischen Speicher und dann kopieren Sie es über? –

+0

@hacker: im Prinzip, ja, in der Praxis wird der Compiler es optimieren (für gcc, '-O1 'ist genug) – Christoph

0

Es ist auch möglich, das memcpy mit der Blockkopie des Konstruktors des Compilers auszublenden. Es macht den Code hässlich wegen all der .i und i: aber vielleicht löst es dein spezifisches Problem.

typedef struct { 
    int i[3]; 
} inta; 

int main() 
{ 
    inta d = {i:{1, 2, 3}}; 

    if (1) 
     d = (inta){i:{4, 5, 6}}; 

    printf("%d %d %d\n", d.i[0], d.i[1], d.i[2]); 

    return 0; 
} 
0

Dies funktioniert und optimiert besser unter gcc mit O3 (der Compiler vollständig entfernt den Code), während die Memcpy der Speicher in allen Fällen kopiert werden zwingt.

template <typename Array> 
struct inner 
{ 
    Array x; 
}; 


template <typename Array> 
void assign(Array& lhs, const Array& rhs) 
{ 
    inner<Array>& l((inner<Array>&)(lhs)); 
    const inner<Array>& r((inner<Array>&)(rhs)); 
    l = r; 
} 

int main() 
{ 
    int x[100]; 
    int y[100]; 

    assign(x, y); 
} 
+0

Die Frage ist mit C markiert, nicht mit C++. Diese Antwort ist C++ und in C vollständig ungültig. –

0

Es gibt auch diese ... :)

char S[16]=""; 
strncpy(S,"Zoodlewurdle...",sizeof(S)-1); 

testen, was passiert, wenn Sie S erklären [8] oder S [32], um zu sehen, warum das so effektiv ist.

Ich schrieb meine eigenen String-Funktionen basierend auf der Logik von OpenBSDs strlcpy, um sicherzustellen, dass ein Terminator-Byte im Falle eines Überlaufs existieren muss, und Standard Strncpy wird dies nicht tun, so müssen Sie sorgfältig beobachten, wie Sie es verwenden .

Die oben beschriebene Methode ist effektiv, weil die ="" bei der Deklaration im ganzen 0 Byte gewährleistet und sizeof(S)-1 stellt sicher, dass, wenn Sie die Zeichenfolge in Anführungszeichen übergaben Strncpy übertreiben, Sie Abschneiden und keine Verletzung der letzten 0 Byte bekommen, so ist dies sicher gegen Überlauf jetzt, UND beim späteren Zugriff auf die Zeichenfolge. Ich habe dies auf ANSI C gerichtet, also sollte es überall sicher sein.

+1

Ich weiß, dass dies eine Zeichenkette ist, nicht ein Array von ganzen Zahlen, aber es könnte eine Möglichkeit geben, die Methode entsprechend zu übersetzen, ohne einen eigenen Iterationscode schreiben zu müssen. – Lostgallifreyan

+0

'strncpy' ist zu Zeichenarrays wie ___ zu Ganzzahlarrays? –

0

Ich würde dies als Kommentar posten, aber ich habe nicht genug Ruf. Ein anderer (vielleicht dreckiger) Weg, ein Array zu initialisieren, besteht darin, es in eine Struktur zu wickeln.

#include <stdio.h> 

struct wrapper { int array[3]; }; 

int main(){ 
    struct wrapper a; 
    struct wrapper b = {{1, 2, 3}}; 

    a = b; 

    printf("%i %i %i", a.array[0], a.array[1], a.array[2]); 

    return 0; 
} 
1
#include<stdio.h> 
#include<stdlib.h> 
#include<stdarg.h> 

int *setarray(int *ar,char *str) 
{ 
    int offset,n,i=0; 
    while (sscanf(str, " %d%n", &n, &offset)==1) 
    { 
     ar[i]=n; 
     str+=offset; 
     i+=1; 
    } 
    return ar; 
} 

int *setarray2(int *ar,int num,...) 
{ 
    va_list valist; 
    int i; 
    va_start(valist, num); 

    for (i = 0; i < num; i++) 
     ar[i] = va_arg(valist, int); 
    va_end(valist); 
    return ar; 
} 

int main() 
{ 
    int *size=malloc(3*sizeof(int*)),i; 
    setarray(size,"1 2 3"); 

    for(i=0;i<3;i++) 
     printf("%d\n",size[i]); 

    setarray2(size,3 ,4,5,6); 
    for(i=0;i<3;i++) 
     printf("%d\n",size[i]); 

    return 0; 
} 
+0

Sie können auch scsanf von einer Funktion loopen und dann das Array zurückgeben – frozenat99

+0

Willkommen bei Stack Overflow. Bitte lesen Sie die [Über] Seite bald. Wenn Sie eine Frage mehr als 6 Jahre nach der Anfrage beantworten (und sie hat die Antworten abgestimmt und akzeptiert), müssen Sie etwas Besonderes hinzufügen - ein neuartiger Ansatz, oder vielleicht hat sich das Produkt seit der ursprünglichen Antwort geändert. Glücklicherweise schlägt Ihnen keine der anderen Antworten vor, eine String-Repräsentation der Array-Werte zu analysieren - so dass vieles in Ordnung ist. Ich bin mir nicht sicher, ob es ein guter Mechanismus ist, aber es ist anders. Ihr Aufruf an 'malloc()' ist nicht genug Platz auf jedem Rechner, wo 'sizeof (char)! = Sizeof (int)'. –

+0

bearbeitet malloc, wenn die Verwendung von Strings nicht funktioniert, können Sie auch die Funktionen von stdarg.h verwenden – frozenat99