2011-12-14 19 views
6

Tengo un fragmento de código escrito en C donde se realiza cierta aritmética de puntero. Me gustaría saber cómo la salida llega a ser esto?¿Cómo sale la salida de este programa a ser esto?

#include <stdio.h> 
int main() 
{ 
    char arr[] = "gookmforgookm"; 
    char *ptr1 = arr; 
    char *ptr2 = ptr1 + 3; 
    printf ("ptr2 - ptr1 = %d\n", ptr2 - ptr1); 
    printf ("(int*)ptr2 - (int*) ptr1 = %d", (int*)ptr2 - (int*)ptr1); 
    getchar(); 
    return 0; 
} 

salida es a continuación:

ptr2 - ptr1 = 3 
(int*)ptr2 - (int*) ptr1 = 0 
+1

interesante. Trataré de encontrar una solución. +1 – ApprenticeHacker

Respuesta

6

Estrictamente hablando, está invocando un comportamiento indefinido y cualquier resultado que el programa produzca está bien según el estándar C.

Sin embargo, es probable que esté en una máquina donde sizeof(int) == 4 (en lugar de decir, 2). Dado que hay 4 bytes en un entero, dos direcciones separadas por 3 bytes son parte del mismo número entero, por lo que la diferencia entre las direcciones es 0 * sizeof(int). Puede encontrar una respuesta diferente si elige ptr1 = arr + 1;, o puede que no. Pero esa es la belleza del comportamiento indefinido: sería 'correcto' en cualquier caso.

+0

¿No sería más bien 'malo' de cualquier manera? :) – Lundin

0

Al restar dos punteros, siempre que apuntan en la misma matriz, el resultado es el número de elementos que los separa.

Pointer Subtraction and Comparison

+0

¡Estoy más interesado en buscar la respuesta para la segunda parte! –

4

Después de la resta es necesario dividir el resultado en el tamaño del tipo de punta.

(int*)ptr2 - (int*)ptr1 == (0x1000003 - 0x1000000)/sizeof(int) 
(int*)ptr2 - (int*)ptr1 == (0x1000003 - 0x1000000)/4 == 0 
+0

Gracias @MByD Pero supongamos que mi declaración es como esta printf ("(char *) ptr2 - (char *) ptr1 =% d", (char *) ptr2 - (char *) ptr1); y ptr1 y ptr2 son del tipo int en el inicio, ¿lo dividiremos o lo repetiremos? –

1

ptr1 y ptr2 son tanto char * tipo, que significa un byte de un puntero.

char *ptr2 = ptr1 + 3; 

por lo

ptr2 - ptr1 = 3 

A continuación, echar tanto puntero de tipo int *, int tipo de necesidad 4 bytes, por lo tanto objetivo puntero al mismo int, tanto puntero tener el mismo valor a través de la alineación de memoria , obtienes el resultado 0.

0

Las direcciones de memoria de los elementos de la misma matriz son siempre secuenciales. es decir si la dirección de memoria de myarray [0] es:

0x4000000 

entonces la dirección de memoria de myarray [2] será definitivamente

0x4000002 

Así que cuando vaya a guardar la dirección de arr en ptr1 asumir que sea x , y luego cuando se hace la dirección de ptr2, tres unidades más alta que ptr1, será x + 3. Así que cuando se resta ptr1 de ptr2 la respuesta será:

(x 3) - x = 3

ahí la respuesta.

En la segunda printf() declaración, si lo desea para mostrar el mismo resultado que el anterior (3), usted tiene que convertir el puntero a int y no int*.

char *myvar; // given contents somewhere 
int addr = (int)myvar; // addr now = the char pointer 

Así que en su caso:

printf ("(int)ptr2 - (int) ptr1 = %d", (int)ptr2 - (int)ptr1); 
Cuestiones relacionadas