2009-04-17 24 views
12

Considere el siguiente fragmento de código:Aritmética de punteros en C

int (*p)[3]; 
int (*q)[3]; 

q = p; 
q++; 
printf("%d, %d\n", q, p); 
printf("%d\n", q-p); 

Sé que la aritmética de punteros es inteligente, lo que significa que la operación q++ avances q suficientes bytes por delante para que apunte a un lado 3-enteros-array, por lo no me sorprende que la primera impresión es '12, 0' lo que significa que incrementando q hizo más grande en 12.

Pero la segunda impresión hace me sorprende. ¡Imprime 1!
¿Por qué imprimiría 1 en lugar de 12? solo me desconcierta.

Respuesta

27

Al igual que el operador de incremento ++, el operador de resta - con punteros también tiene en cuenta el tamaño de los objetos a los que apunta. Específicamente, el resultado devuelto es el número de bytes de diferencia en los valores del puntero dividido por el tamaño del objeto apuntado (12, en su ejemplo). Entonces la diferencia es 12 bytes, dividido por tamaño 12, o 1.

+0

¿Así que no hay forma de tomar dos punteros y obtener su diferencia en bytes? –

+8

Lanza los punteros a (char *) y obtendrás la diferencia en bytes. –

+4

@Leif: O simplemente multiplique la diferencia por sizeof (your_type). –

4

Si realmente desea saber la diferencia, coloque cada puntero en a (char *) y luego en (int) y luego reste. Eso debería darte la respuesta.

Este código le da el valor absoluto:

printf("%d\n", abs((int)((char*)q) - (int)((char*)p))); 

Recuerde incluir math.h.

Editar: Como se señala en un comentario, no es necesario un doble molde. Al convertir cada pointerpointer en un int y luego en restar se obtiene la misma respuesta que el double casting (innecesario) anterior.

printf("%d\n", abs((int)(q) - (int)(p))); 
+0

¿Por qué doble-elenco? –

+0

Eso no funcionará de manera confiable si sizeof (int) Idelic