2010-09-03 26 views
9

A continuación se presentan 2 programas¿por qué diferentes respuestas?

Primeros

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    int *p; 
    p=&a; 
    printf("%u %u",p,p+1); 
} 

Segunda

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    printf("%u %u",&a,&a+1); 
} 

Ahora, en los dos programs..I han impreso los valores de una & usando p en la primera código y directamente en el segundo ..

¿Por qué son los resultados diferentes?

la respuesta que estoy obteniendo son.

for first 3219048884 3219048888 
for second 3219048884 3219048904 
+1

Podría por favor formatear sus líneas de código con el botón de código en el editor? Hace que sea mucho más fácil para las personas ayudar. – jlafay

+2

¿Cuáles son los resultados que está obteniendo? –

+2

¿Y cuáles son los resultados que ves? –

Respuesta

14

El tipo de &a es int (*) [5]. Por lo tanto, &a+1 es un puntero que es 5 int s más allá de a. Sin embargo, el tipo de p es int *, por lo tanto p+1 es un puntero que es 1 int más allá de p.

+0

Sneaky! Lo apruebo. –

+0

Sí, pero eso es irrelevante con la pregunta, excepto por el último valor de la serie – kriss

+1

@kriss: ¿Cómo es esto irrelevante? Es el último valor en cada secuencia que difiere, y esta es la razón. –

-2

Debe utilizar p = a y no p = &a. Una matriz como a ya se supone un puntero constante. No necesita desreferenciarlo con el operador &.

+0

'a' no es un puntero. Nunca jamás. – GManNickG

+0

@GMan ¿Por qué entonces puedes decir '* a = 2' con el mismo significado que' a [0] = 2'? – Frank

+0

Porque las matrices tienen una conversión implícita a puntero. Pero las matrices no son punteros. – GManNickG

2

En ambos programas, está imprimiendo las direcciones de memoria de la matriz.

Esto puede variar cada vez que ejecuta el programa. La memoria que el OS elige darle puede ser diferente.

Cuando su programa declara una matriz de 5 enteros, el sistema operativo promete darle 5 enteros consecutivos, NO promete qué memoria obtendrá, o que obtendrá la misma memoria cada vez.

7

Cuando corro que, me sale esto:

1245036 1245040 1245036 1245040 
1245036 1245040 1245036 1245056 

con la única diferencia de estar en la última posición, p+1 vs &a+1

p es un puntero a un entero, por lo p+1 es la dirección del siguiente entero. (Es decir 4 byte adicional en memeory)

a es una matriz de 5 números enteros, por lo & a + 1 es la dirección de la siguiente matriz de 5 números enteros. (es decir, 20 bytes más en memeory)

1

Su primer programa no es válido. Es ilegal asignar p = &a, ya que p tiene tipo int * y &a tiene tipo int (*)[5]. Estos tipos no son compatibles. Si su compilador es lo suficientemente suelto como para permitir este tipo de tarea (¿al menos lo advirtió?), Probablemente lo interpretó como p = (int *) &a, es decir, reinterpreta con fuerza el valor de &a como un puntero int *. Por lo tanto, toda la aritmética del puntero en su primer programa es int * aritmética. Esta es la razón por la cual el primer programa produce la misma salida para los valores a+1 y p+1.

En el segundo programa, el valor de &a no se reinterpreta. Mantiene su tipo original `` int () [5] and it follows the rules of normal pointer arithmetic for type int () [5] , meaning that when you do & a + 1 , the pointer is moved sizeof (int [5]) `bytes, como debería. Esta es la razón por la cual el resultado es diferente del primer programa.

2

Tiene dos programas con diferentes marcos de pila, no es de extrañar que las direcciones de las variables locales sean diferentes. Puede cambiar cada vez que ejecutas el programa (eso es lo que hace cuando lo intento, código compilado con gcc en Linux).

Pero obtendrás los mismos valores con el programa que se muestra a continuación, excepto el último valor de la serie (excepto el último, por la forma en que funciona la aritmética del puntero).

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    int *p; 
    p=&a; 
    printf("%u %u %u %u ",a,a+1,p,p+1); 
    printf("%u %u %u %u",a,a+1,&a,&a+1); 
} 

Para una explicación (bastante) completa de diferencia entre apuntadores y arreglos se puede ver en mi respuesta here

Cuestiones relacionadas