2009-04-13 15 views
13

He hecho una pregunta similar sobre las estructuras here, pero estoy tratando de averiguar cómo C maneja cosas como la asignación de variables y por qué no está permitido asignarlas entre sí si son funcionalmente iguales.C declaración y asignación de matriz?

Digamos que tengo dos matrices:

int x[10]; 
int y[10]; 

¿Por qué no x = y compilar? Si ambos tienen la misma "firma", ¿no deberías poder asignarlos de un lado a otro?

¿Puedo declarar esto de una manera que me permita hacer eso en C? Tiene sentido para mí que usted sea capaz de hacerlo, pero tal vez haya una forma de hacerlo. Typedefs for structs parecía ser la solución, ¿sería lo mismo para la declaración y la asignación de array?

Agradezco la ayuda de sus muchachos, soy nuevo en Stackoverflow pero hasta ahora ha sido un recurso realmente bueno para mí.

Respuesta

23

En pocas palabras, las matrices no se pueden asignar. Son un "valor l no modificable". Por supuesto, esto plantea la pregunta: ¿por qué? Por favor refiérase a esta pregunta para obtener más información:

Why does C++ support memberwise assignment of arrays within structs, but not generally?

Las matrices no son punteros.x aquí hace hace referencia a una matriz, aunque en muchas circunstancias esto "decae" (se convierte implícitamente) en un puntero a su primer elemento. Del mismo modo, y también es el nombre de una matriz, no un puntero.

Usted puede hacer la asignación de matrices dentro de estructuras:

struct data { 
    int arr[10]; 
}; 

struct data x = {/* blah */}; 
struct data y; 
y = x; 

Pero no se puede hacer directamente con matrices. Use memcpy.

+0

Ese código todavía no hace lo que él * quería * hacer, ¿o sí? Quizás estoy equivocado, pero me dio la impresión de que esperaba copiar el contenido de la matriz y en x. –

+0

Es cierto. Afortunadamente, muchas otras respuestas indican que memcpy() es la elección correcta. Lo agregaré en ... –

+6

"El nombre de una matriz es en realidad la dirección del primer elemento de esa matriz. \ El código de ejemplo que proporciona aquí intenta asignar a algo que no es un valor l". : por el bien de la posteridad, pensé que notaria que ambas oraciones de la respuesta más votada son incorrectas. En primer lugar, el nombre de una matriz definitivamente * no es * un puntero (por ejemplo, think sizeof()), simplemente se descompone en un puntero en muchos casos. En segundo lugar, el nombre de la matriz * es * un valor l, simplemente no es un valor l modificable. –

1

Para asignar matrices, tendrá que asignar los valores dentro de la matriz.

es decir. x = y es equivalente a

for(int i = 0; i < 10 < ++i) 
{ 
x[i] = y[i]; 
} 
+0

x = y es un error del compilador. – Naveen

+0

¡por eso estoy dando el equivalente! –

+0

da la impresión de que x = y es una declaración válida – Naveen

0

Al decir "int x [10]" está diciendo "se reserva un cierto margen de 10 enteros y me pasa un puntero a la ubicación". Entonces, para que la copia tenga sentido, debe operar en la memoria apuntada por, en lugar de 'el nombre de la ubicación de la memoria'.

Así que para copiar aquí usarías un bucle for o memcpy().

2

Algunos mensajes aquí dicen que el nombre de una matriz produce la dirección de su primer elemento. No siempre es cierto:

#include <stdio.h> 

int 
main(void) 
{ 
    int array[10]; 

    /* 
    * Print the size of the whole array then the size of a pointer to the 
    * first element. 
    */ 
    printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]); 

    /* 
    * You can take the address of array, which gives you a pointer to the whole 
    * array. The difference between ``pointer to array'' and ``pointer to the 
    * first element of the array'' matters when you're doing pointer arithmetic. 
    */ 
    printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1)); 

    return 0; 
} 

Salida:

40 4 
0xbfbf2ca4 0xbfbf2c80 
0

he utilizado compiladores de C cuando ello compilar bien ... y cuando se ejecuta el código podría hacer x punto a la matriz de y.

Verá, en C, el nombre de una matriz es un puntero que apunta al inicio de la matriz. De hecho, las matrices y punteros son esencialmente intercambiables.Puede tomar cualquier puntero e indexarlo como una matriz.

Cuando C se desarrollaba a principios de los 70, estaba destinado a programas relativamente pequeños que apenas superaban el lenguaje ensamblador en abstracción. En ese entorno, fue muy útil poder ir y venir fácilmente entre la indexación de matriz y la matemática de puntero. Copiar matrices enteras de datos, por otro lado, era algo muy costoso, y difícilmente algo alentador o abstraído del usuario.

Sí, en estos tiempos modernos tendría más sentido que el nombre de la matriz sea una abreviatura de "toda la matriz", en lugar de "ponter al frente de la matriz". Sin embargo, C no fue diseñado en estos tiempos modernos. Si quieres un idioma que fue, prueba Ada. x: = y hace exactamente lo que cabría esperar; copia el contenido de una matriz a la otra.

+0

Ping aleatorio amigable. :) Como indudablemente (ahora) sabes, el nombre de una matriz no es un puntero. – GManNickG

1

En un intento de complementar la respuesta de blanco, que ideó el siguiente programa:

localhost:~ david$ cat test.c 
#include <stdlib.h> 
#include <stdio.h> 
int main (int argc, char * argv []) 
{ 
    struct data { 
    int c [2]; 
    } x, y; 
    x.c[0] = x.c[1] = 0; 
    y.c[0] = y.c[1] = 1; 
    printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]); 
    printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]); 
    x = y; 
    printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]); 
    printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]); 

    return 0; 
} 

Cuando se ejecuta, el siguiente es resultado de:

x.c 0x7fff5fbff870 0 0 
y.c 0x7fff5fbff860 1 1 
x.c 0x7fff5fbff870 1 1 
y.c 0x7fff5fbff860 1 1 

El punto es ilustrar cómo la copia de las estructuras 'valores ocurre.

3
int x [sz]; 
int *y = x; 

Esto compila y y será el mismo que x.

+2

'y' será un puntero equivalente a' & x [0] ', debido a la conversión de matriz a puntero, pero no será" lo mismo "que' x' es una matriz, no un puntero. – GManNickG

Cuestiones relacionadas