¿Declaración y asignación de matriz C?

6 minutos de lectura

avatar de usuario
mitráx

He hecho una pregunta similar sobre estructuras aquí, 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.

Digamos que tengo dos matrices:

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

¿Por qué x = y no compila? Si ambos son la misma “firma” así, ¿no debería poder asignarlos de un lado a otro?

¿Puedo declararlos de una manera que me permita hacer eso en C? Tiene sentido para mí que pueda hacerlo, pero tal vez haya una manera de hacerlo. Typedefs para estructuras parecía ser la solución, ¿sería lo mismo para la declaración y asignación de matrices?

Agradezco su ayuda, soy nuevo en Stackoverflow, ¡pero hasta ahora ha sido un recurso realmente bueno para mí!

En pocas palabras, las matrices no son asignables. Son un “lvalue no modificable”. Esto, por supuesto, plantea la pregunta: ¿por qué? Consulte esta pregunta para obtener más información:

¿Por qué C++ admite la asignación de arreglos entre miembros dentro de estructuras, pero no en general?

Las matrices no son punteros. x aquí lo hace se refieren a una matriz, aunque en muchas circunstancias esto “decae” (se convierte implícitamente) en un puntero a su primer elemento. Igualmente, y también es el nombre de una matriz, no un puntero.

Puede hacer la asignación de matrices dentro de las estructuras:

struct data {
    int arr[10];
};

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

Pero no puedes hacerlo directamente con arreglos. Utilizar memcpy.

  • Ese código todavía no hace lo que estaba falto que hacer sin embargo, ¿verdad? Tal vez me equivoque, pero tuve la impresión de que esperaba copiar el contenido de la matriz y en x.

    – TED

    13 de abril de 2009 a las 18:18

  • Cierto. Afortunadamente, muchas otras respuestas han indicado que memcpy() es la opción correcta. Lo agregaré en…

    usuario82238

    13 de abril de 2009 a las 18:21

  • “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 algo que no es un valor l”.: por el bien de la posteridad, pensé que d tenga en cuenta que ambas oraciones de la respuesta más votada son incorrectas. Primero, el nombre de una matriz definitivamente no es un puntero (por ejemplo, piense en sizeof()), simplemente se descompone en un puntero en muchos casos. En segundo lugar, el nombre de la matriz es un lvalue, pero no un lvalue modificable.

    – Alexandros Gezerlis

    31/10/2011 a las 23:32

  • Me estoy burlando de esta respuesta. Es el más votado y aceptado, pero contenía información incorrecta y el usuario ya no está. Esperemos que esto aclare las cosas.

    – GManNickG

    5 de octubre de 2016 a las 6:16

avatar de usuario
mikeD

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

Esto compila y y será lo mismo que x.

  • 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

    5 de octubre de 2016 a las 6:05

avatar de usuario
Bastien leonard

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;
}

Producción:

40 4
0xbfbf2ca4 0xbfbf2c80

avatar de usuario
aJ.

Para asignar matrices, deberá 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];
}

En un intento de complementar la respuesta de Blank, 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, se emite lo siguiente:

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 se produce la copia de los valores de las estructuras.

avatar de usuario
amo-ej1

Al decir “int x[10]” está diciendo, “reserve espacio para 10 números enteros y pásame un puntero a la ubicación”. Entonces, para que la copia tenga sentido, debe operar en la memoria señalada por, en lugar de ‘el nombre de la ubicación de la memoria’ .

Entonces, para copiar aquí, usaría un bucle for o memcpy().

avatar de usuario
TED

He usado compiladores de C donde eso compilaría bien… y cuando se ejecuta el código haría que x apunte 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 los punteros son esencialmente intercambiables. Puedes tomar ninguna puntero e indexarlo como una matriz.

Cuando se estaba desarrollando C a principios de los años 70, estaba destinado a programas relativamente pequeños que apenas estaban por encima del lenguaje ensamblador en abstracción. En ese entorno, era muy útil poder alternar fácilmente entre la indexación de matrices y las matemáticas de puntero. Copiar arreglos completos de datos, por otro lado, era algo muy costoso, y difícilmente algo para alentar o abstraer del usuario.

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

  • Ping aleatorio amistoso. 🙂 Como sin duda (ahora) sabes, el nombre de una matriz no es un puntero.

    – GManNickG

    5 de octubre de 2016 a las 6:05

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad