2012-03-24 15 views
7

¿Por qué la diferencia entre las dos direcciones es incorrecta? http://codepad.org/NGDqFWjJPuntero/Dirección de diferencia

#include<stdio.h> 
int main() 
{ 
    int i = 10, j = 20; 
    int *p = &i; 
    int *q = &j; 
    int c = p - q; 
    printf("%d\n", p); 
    printf("%d\n", q); 
    printf("%d", c); 
    return 0; 
} 

Salida:

-1083846364 
-1083846368 
1 

Respuesta

17

En primer lugar, la aritmética de punteros no está definido cuando se realiza en punteros no relacionados.

En segundo lugar, tiene sentido. Al restar punteros se obtiene el número de elementos entre esas direcciones, no el número de bytes.

Si se va a tratar de que con

char *p1 = &i, *p2 = &j; 

que se obtendría un resultado diferente.


Como nota al margen, utilice %p al imprimir punteros.

+0

Estrictamente hablando, eso es cierto, pero cada implementación que he usado hace "lo correcto". Lo mismo ocurre con los OP, en realidad. –

+0

@CarlNorum Sí, edité. – cnicutar

+0

Lo tengo. ¡Gracias! – Ava

2

Estrictamente hablando, su programa causa algunos tipos de comportamiento indefinido, primero debido a la aritmética del puntero en punteros no relacionados, y luego al no emparejar cadenas de formato y argumentos en sus instrucciones de impresión. Sin embargo, incluso si se corrigieran, vería los mismos resultados. La razón por la cual la diferencia es 1 es porque la aritmética del puntero da resultados en unidades del tamaño del tipo apuntado - en su caso int es un tipo de 4 bytes, por lo que restar int * punteros que separan 4 bytes produce un resultado de 1.

6

Como han dicho otros, el resultado que obtienes está en un múltiplo del tamaño del tipo al que apuntan los punteros. Equípelos para que sean punteros de caracteres y el resultado que obtienes será en términos de bytes. Además, debe usar ptrdiff_t type, de modo que en los sistemas con punteros de 64 bits, el tipo debe ser lo suficientemente grande como para contener el resultado.

ptrdiff_t c = (char*)p - (char*)q; 

También tenga en cuenta que la toma de la diferencia de las direcciones de los dos valores que no están en la misma matriz no está definido en la norma, pero funciona en casi todos los sistemas.

+0

Aparece un error para 'arithmetic en los punteros para anular' cuando intento esto. –

+0

Resulta que la aritmética en punteros 'void *' es [comportamiento no estándar] (https://stackoverflow.com/a/3524270/1289657) solo compatible con algunos compiladores con (fuera) ciertos indicadores. Cambié la respuesta para recomendar solamente punteros 'char *', que funciona correctamente y es un comportamiento estándar. – AgentME