¿Cuál es exactamente el nombre del array en c?


Estoy teniendo dificultades para entender el tipo y el uso del nombre de la matriz en C. Podría parecer un post largo, pero por favor tengan paciencia conmigo.

Entiendo que la siguiente declaración declara a ser de tipo int []es decir, matriz de enteros.

int a[30];

Mientras que a también señala el primer elemento de matriz y cosas como *(a+2) son válidas. Así, haciendo que aparezca un puntero a un entero. Pero en realidad los tipos int [] y int* son diferentes; mientras que el primero es un tipo de matriz y más tarde es un puntero a un entero.

También una variable de tipo int [] se convierte en una variable de tipo int* al pasarla a funciones; como en C los arrays se pasan por referencia (con la excepción del operador sizeof).

Aquí viene el punto que me hace colgar. Echa un vistazo a la siguiente pieza de código:

int main()
{
    int (*p)[3];
    int a[3] = { 5, 4, 6 };

    p = &a;

    printf("a:%d\t&a:%d\n",a,&a);
    printf("%d",*(*p + 2));
}

SALIDA:

a:2686720       &a:2686720
6

Entonces, ¿cómo funciona el código anterior? Tengo dos preguntas:

  1. a y &a tienen los mismos valores. ¿Por qué?
  2. ¿Qué hace exactamente int (*p)[3];? Declara un puntero a un array, lo sé. Pero, ¿cómo es un puntero a un array diferente del puntero al primer elemento del array y nombre del array?

¿Puede alguien aclarar las cosas? Estoy teniendo un montón de confusiones.

Sé que debo usar %p como marcador de posición en lugar de usar %d para imprimir el valor de las variables de puntero. Como el uso del marcador de posición entero puede imprimir direcciones truncadas. Pero sólo quiero mantener las cosas simples.

Author: darxtrix, 2014-06-28

6 answers

  1. a y &a tienen los mismos valores.¿Cómo?

Tienen el mismo valor pero diferentes tipos. Los objetos Array no tienen relleno entre elementos (antes o después) por lo que la dirección del array y la dirección del primer elemento del array son iguales.

Eso es:

(void *) a == (void *) &a
  1. Qué hace exactamente int (*p)[3]; Declara un puntero a un array,lo sé.Pero, cómo un puntero a una matriz es diferente del puntero a la primera elemento de la matriz y nombre de la matriz?

Estos son dos tipos de puntero diferentes. Tomemos, por ejemplo, la aritmética del puntero:

a + 1   /* address of the second element of the array */
&a + 1  /* address one past the last element of the array */

EDIT: debido a la demanda popular he añadido a continuación alguna información sobre la conversión de matrices.

Con tres excepciones, en una expresión un objeto de tipo array de T se convierte en un valor de tipo puntero a T apuntando al primer elemento del array. Las excepciones son si el objeto es el operando de sizeof o & operador unario o si el objeto es una cadena literal inicializando una matriz.

Por ejemplo esta declaración:

printf("a:%d\t&a:%d\n", a, &a);

Es en realidad equivalente a:

printf("a:%d\t&a:%d\n", &a[0], &a);

También tenga en cuenta que d el especificador de conversión solo se puede usar para imprimir un entero con signo; para imprimir un valor de puntero debe usar p el especificador (y el argumento debe ser void *). Así que para hacer las cosas correctamente use:

printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);

Respectivamente:

printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
 16
Author: ouah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-02 19:49:32

Otras respuestas ya explicaron el problema. Estoy tratando de explicarlo con algún diagrama. Espero que esto ayude.


Cuando se declara un array

int a[3] = {5, 4, 6}  

La disposición de la memoria se parece a

introduzca la descripción de la imagen aquí

Ahora respondiendo a su pregunta:

  1. a y &a tienen los mismos valores.¿Cómo?

Como ya sabes, a es de tipo array y el nombre del array a se convierte en un puntero a first elemento de matriz a (después de decaimiento),es decir, apunta a la dirección 0x100. Tenga en cuenta que 0x100 también es la dirección inicial del bloque de memoria (array a). Y usted debe saber que, en general, la dirección del primer byte se dice que es la dirección de la variable. Es decir, si una variable es de 100 bytes, entonces su dirección es igual a la dirección de su primer byte.

&a es la dirección de todo el bloque de memoria, es decir, es una dirección de array a. Ver el diagrama:

introduzca la descripción de la imagen aquí

Ahora puedes entender por qué a y &a ambos tienen el mismo valor de dirección aunque ambos son de tipo diferente.

Qué hace exactamente int (*p)[3]; Declara un puntero a un array,lo sé.Pero, ¿cómo un puntero a una matriz es diferente del puntero al primer elemento de la matriz y el nombre de la matriz?

Vea la figura anterior, se explica claramente cómo el puntero a una matriz es diferente del puntero a una matriz elemento.
Cuando se asigna &a a p, entonces p apunta a toda la matriz que tiene la dirección de inicio 0x100.


NOTA: Respecto a la línea

... como en C los arrays son pasados por referencias (con excepción de la función sizeof).

En C, los argumentos se pasan por valor. No pasa por referencia en C. Cuando una variable ordinaria se pasa a una función, su valor es copiado ; cualquier cambio en el parámetro correspondiente no afecta a la variable.
Las matrices también se pasan por valor, pero la diferencia es que el nombre de la matriz decae a puntero al primer elemento y este puntero se asigna al parámetro (aquí, el valor del puntero se copia) de la función; la matriz en sí no se copia.
En contraste con la variable ordinaria, un array usado como argumento no está protegido contra cualquier cambio, ya que no se hace ninguna copia del array en sí, en su lugar se hace una copia del puntero al primer elemento.

Usted también debe tener en cuenta que sizeof no es una función y el nombre de la matriz no actúa como argumento en este caso. sizeofes un operador y el nombre del array sirve como un operando . Lo mismo ocurre cuando el nombre de la matriz es un operando del operador unario &.

 46
Author: haccks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-30 20:16:21
  1. a corresponde al puntero que apunta al 0to elemento de la matriz. Mientras que, lo mismo es el caso con &a.It solo da la dirección inicial de la matriz.

As, a --> pointer pointing to starting element of array a[],it does not know about other element's location..

&a --->address location for storing array a[] which stores first element location,but knows every element's location.

Del mismo modo,la ubicación de otros elementos será (a+2),(a+4) y así hasta el final de la matriz.

Por lo tanto,usted consiguió tal resultado.

  1. int (*p)[3] es un puntero al array. si hubiera sido int * p[3], se entendería completamente diferente. Habría significado una serie de indicadores que habrían sido totalmente diferentes de este contexto.

El puntero a una matriz se encargará automáticamente de todos los demás elementos en el array.In en este caso, el suyo es (p);

Considerando que, el puntero al primer elemento de la matriz, es decir, una voluntad solo conoce el primer elemento de la matriz.Tendrás que hacerlo manualmente dar direcciones aritméticas puntero para acceder a los siguientes elementos.Ver, en este case - - - podemos obtener el segundo elemento de a añadiendo 2 a a, i. e. a + 2, tercer elemento añadiendo 4 a a, es decir, a + 4 y así sucesivamente. // cuidado con el diferencia de dos, ya que es una matriz entera!

 2
Author: Am_I_Helpful,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-28 14:33:33

En respuesta a la pregunta 1, esto es simplemente un aspecto del lenguaje C como está diseñado, a diferencia de la mayoría de los otros lenguajes modernos C/C++ permite la manipulación directa de direcciones en memoria y ha construido en instalaciones para 'entender' eso. Hay muchos artículos en línea que explican esto mejor que yo en este pequeño espacio. Aquí hay uno y estoy seguro de que hay muchos otros: http://www.cprogramming.com/tutorial/c/lesson8.html

 1
Author: Jeff D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-28 14:33:42

De Norma C99 n1124 6.3.2.1 p3

Excepto cuando es el operando del operador sizeof o unario & operador, or es un literal de cadena utilizado para inicializar una matriz, un expresión que tiene tipo "array of type" se convierte en un expresión con tipo "puntero a tipo" que apunta a la inicial elemento del objeto array y no es un lvalue. Si el objeto array tiene la clase de almacenamiento register, el comportamiento es indefinido.

 1
Author: ooga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-28 15:06:21

A y &a tienen el mismo valor porque hace mucho tiempo se le requería usar el operador de direcciones & on arrays para obtener la dirección del array, pero ya no es necesario. El nombre de la matriz (a en este caso) en estos días solo representa la dirección de memoria de la matriz en sí, que también es lo que obtiene de &a. Es una abreviatura que el compilador maneja por usted.

 0
Author: steviesama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-28 22:51:28