2011-12-20 21 views
5

Aquí, tengo algo de Duda con la salida.punteros que apuntan a la matriz de números enteros

¿Por qué la salida es la misma?

int (*r)[10]; 
    printf("r=%p *r=%p\n",r,*r); 
    return 0; 

plataforma- GCC UBUNTU 10.04

+0

¿Qué salida obtiene? ¿Cómo se compara con la salida que espera obtener? –

+0

Aquí está la salida r = 0x427ff4 * r = 0x427ff4 que son las mismas –

+1

Véase también http: // blogs.oracle.com/ksplice/entry/the_ksplice_pointer_challenge – Artefacto

Respuesta

7

porque el nombre de la matriz se desintegra a un puntero a su primer elemento.

int (*r)[10]; 

es un puntero a una matriz de enteros 10.
r le proporciona el puntero.

Este puntero a la matriz debe desreferenciarse para acceder al valor de cada elemento.
Así que al contrario de lo que piensas **r y no *r te da acceso al primer elemento de la matriz.
*r le da dirección del primer elemento de la matriz de enteros, que es igual que r

importante señalar aquí que:
Las matrices no son punteros

Pero las expresiones que implican nombre de la matriz a veces se comportan como puntero cuando los que se usan como nombre de la matriz no tengan sentido.

+0

Y si estoy en lo cierto, la expresión '* r' tiene un lvalue de tipo' int [10] ', pero luego se convierte a' int * 'por medio de conversión lvalue-to-rvalue. – Kos

+0

Además, "' ** r' y '* r' le da acceso al primer elemento de la matriz" es confuso ... –

+0

¿Es 'r' una matriz de punteros, o es un puntero a una matriz? –

4

Lo entenderá mejor si mira el siguiente programa.

#include <stdio.h> 

int main() 
{ 
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    int (*r)[10] = &a; 

    printf("r=%p *r=%p *(r+0)=%p *(r+1)=%p\n", r, *r, *(r+0), *(r+1)); 
    printf("sizeof(int)=%d \n", sizeof(int)); 

    return 0; 
} 

La salida es la siguiente:

r=0xbfeaa4b4 *r=0xbfeaa4b4 *(r+0)=0xbfeaa4b4 *(r+1)=0xbfeaa4dc 
sizeof(int)=4 

Observaciones/Point (s) -to-nota:

  • _DO_NOT_ de-referencia un puntero que no tiene todavía hecho para señalar una dirección. Por lo tanto, en su programa int (*r)[10]; fue desreferenciado sin ser asignado a un área de memoria. Esto no es aceptable.

  • Si ve la salida - * r es igual a * (r + 0) que es igual que R (sólo WRT este caso)

  • Si ve la salida de * (r + 0) y * (r + 1) es 40 bytes (0xbfeaa4dc - 0xbfeaa4b4 = sizeof (int) * tamaño de la matriz (que es 10 en este caso). Por lo tanto, cuando incrementa un puntero a un tipo particular, se incrementa a sizeof (tipo) bytes!

  • los otros puntos que vale la pena-notable de un puntero-a-una-serie-de-enteros se explican here

Espero que esto ayude!

4

Recuerde que cuando aparece una expresión de tipo "matriz de elementos N de T" en la mayoría de contextos, se convertirá en una expresión de tipo "puntero a T" y su valor será la dirección del primer elemento en la matrizLas excepciones a esta regla son cuando la expresión de matriz es un operando de los operandos sizeof o unario & (dirección de), o si la expresión de matriz es un literal de cadena que se usa como inicializador en una declaración de matriz.

Su situación es un reflejo de lo siguiente:

int a[10] = {0}; 
printf("a = %p, &a = %p\n", (void *) a, (void *) &a); 

En la llamada printf, la expresión a tiene su tipo convertidos de "matriz de 10 elementos de int" a "puntero a int" basado en la regla anterior, y su valor será la dirección del primer elemento (&a[0]). La expresión &a tiene el tipo "puntero a matriz de 10 elementos de int", y su valor será el mismo que a (la dirección del primer elemento en la matriz es la misma que la dirección de la matriz misma).

Su código tiene un comportamiento indefinido en el sentido de que está desreferenciando r antes de asignarlo a un punto significativo, por lo que no puede confiar en que el resultado sea exacto. Podemos arreglar eso de esta manera:

int a[10] = {0}; 
int (*r)[10] = &a; 
printf("r = %p, *r = %p\n", (void *) r, (void *) *r); 

En este caso, r == &a y *r == a.

La expresión r tiene el tipo "puntero a la matriz de 10 elementos de int", y su valor es la dirección de a. La expresión *r tiene tipo "array de 10 elementos de int, que se convierte en 'puntero a int', y su valor se establece en la dirección del primer elemento, que en este caso es a[0]. De nuevo, la valores de las dos expresiones son las mismas.

Cuestiones relacionadas