2009-10-17 11 views
5

En los lenguajes de nivel superior podría hacer algo similar a este ejemplo en C y estaría bien. Sin embargo, cuando compilo este ejemplo C, se queja con amargura. ¿Cómo puedo asignar nuevas matrices a la matriz que declare?Pregunta simple de declaración/asignación de matriz C

int values[3]; 

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

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

Thanks.

+1

Vea aquí algunas ideas: http: // stackoverflow.com/questions/1223736/c-change-all-values-of-a-array-of-structures-in-one-line/1223806 # 1223806 –

Respuesta

1

puede declarar matriz estática con los datos para inicializar a partir de:

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

¿No puedo hacer memmove (values, {1,2,3}, sizeof (values)); ? –

+0

No, no puedes hacerlo así. – hlovdal

+1

Creo que podrías: memmove (values, (int [3]) {1,2,3}, sizeof (int [3])); Ver mi respuesta a continuación. –

11

Sólo se puede hacer una asignación múltiple de la matriz, cuando se declara la matriz:

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

Después de la declaración, se le han de asignar a cada valor individual, es decir

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

O podría usar un bucle, dependiendo de qué valores desee usar.

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

Esto funciona para 3 valores, pero ¿y si tuviera una matriz con 50 valores? ? –

+0

Entonces usarías un bucle, o 'memmove' /' memcpy' como @hacker sugiere en otra respuesta. –

+0

memcpy parece más ordenado. Gracias por tu ayuda. –

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

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

En C99, usando compound literals, se podría hacer:

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

o

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

+1; Tenga en cuenta que en el último caso, la matriz tendrá una duración de almacenamiento automática, es decir, devolverla de una función hará que se coma por gristo – Christoph

+0

Christoph, ¿eso significaría que 'memmove'ing de dicha matriz implicaría inicializarlo primero? en el almacenamiento automático y luego copiarlo? –

+0

@hacker: en principio, sí, en la práctica, el compilador lo optimizará (para gcc, '-O1' es suficiente) – Christoph

0

También es posible ocultar el memcpy utilizando la copia de estructura del bloque del compilador. Hace el código feo debido a todos los .i e i: pero tal vez resuelve tu problema específico.

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

Esto funciona mejor bajo y optimiza gcc con -O3 (el compilador elimina por completo el código), mientras que el establecimiento de memoria obliga a la memoria para ser copiada en todos los casos.

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

La pregunta está etiquetada C, no C++. Esta respuesta es C++ y completamente inválida en C. –

0

Se da también una ... :)

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

prueba de lo que sucede si se declara S [8] o S [32], para ver por qué esto es tan eficaz.

Escribí mis propias funciones de cadena basadas en la lógica de strlcpy de OpenBSD, destinadas a asegurar que un byte terminador DEBE existir en caso de desbordamiento, y strncpy estándar no hará esto, así que debe observar cuidadosamente cómo lo usa .

El método anterior es eficaz porque el ="" en la declaración asegura 0 bytes en todo, y sizeof(S)-1 asegura que si exagerar la citada cadena pasó a strncpy, se obtiene el truncamiento y ninguna violación del último byte 0, por lo que esta es segura contra desbordamiento ahora, Y al acceder a la cadena más tarde. Apunté esto a ANSI C, por lo que debería estar seguro en cualquier lugar.

+1

Me doy cuenta de que esto es una cadena, no una matriz de enteros, pero puede haber una forma de traducir el método en consecuencia, sin tener que escribir su propio código de iteración. – Lostgallifreyan

+0

'strncpy' es para matrices de caracteres como ___ para matrices enteras? –

0

Lo publicaría como comentario, pero no tengo suficiente reputación. Otra forma (quizás sucia) de inicializar una matriz es envolverla en una estructura.

#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

también puede ejecutar sscanf desde una función y luego devolver la matriz – frozenat99

+0

Bienvenido a Desbordamiento de pila. Lea la página [Acerca de] pronto. Cuando responde una pregunta más de 6 años después de haberla formulado (y ha votado y aceptado las respuestas), debe tener algo distintivo para agregar: un enfoque novedoso, o tal vez el producto ha cambiado desde que se dieron las respuestas originales. Afortunadamente para ti, ninguna de las otras respuestas sugiere analizar una representación de cadena de los valores de la matriz, por lo que mucho está bien. No estoy seguro de que sea un buen mecanismo, pero es diferente. Su llamada a 'malloc()' no está asignando espacio suficiente en cualquier máquina donde 'sizeof (char)! = Sizeof (int)'. –

+0

malloc editado, si usar cadenas no funciona, también puede usar las funciones de stdarg.h – frozenat99