2010-07-26 10 views
9

¿Cómo es la siguiente línea interpretado por el compilador GCC:¿Cómo se interpreta la instrucción printf?

printf("HELLO"); 

Quiero saber esto porque cuando estoy corriendo siguiente programa:

main() 
{ 
    printf(5+"Good Morning"); 
} 

El programa está imprimiendo:

Morning 

¿Por qué el compilador está comenzando a imprimir desde el sexto personaje?

Respuesta

22

Aquí suceden muchas cosas. Como han dicho otros, printf() no 'sabe' nada sobre la expresión 5+"Good Morning". El valor de esa expresión está determinado por el lenguaje C.

Primero, a+b es lo mismo que b+a, entonces 5+"Good Morning" es lo mismo que "Good Morning"+5.

Ahora, el tipo de "Good Morning" (es decir, un literal de cadena) es una "matriz de char". Específicamente, "Good Morning" es una matriz de 13 caracteres (12 caracteres "regulares", seguidos de 0). Cuando se usa en la mayoría de las expresiones, el type of an array in C "decae" en un puntero a su primer elemento, y la adición binaria es uno de esos casos.Todo esto significa que en "Good Morning"+5, "Good Morning" se desintegra a un puntero a su primer elemento, que es el carácter G.

Aquí es cómo se ve la memoria como:

0 1 2 3 4 5 6 7 8 9 0 1 2 
+---+---+---+---+---+---+---+---+---+---+---+---+---+ 
| G | o | o | d | | M | o | r | n | i | n | g | 0 | 
+---+---+---+---+---+---+---+---+---+---+---+---+---+ 

El valor de la dirección de G más 5 es un puntero que apunta a 5 poblaciones de G anteriormente, que se M. Entonces, printf() está obteniendo una dirección que está en M. printf() imprime hasta que encuentra un 0. Por lo tanto, verá Morning como salida.

+5

+1 para no estorbar (especialmente en la mayoría de las expresiones, el tipo de una matriz en C "decae" en un puntero a su primer elemento "en lugar de" la la la, una matriz es un puntero, la la la ") – detly

7

IS es lo mismo que escribir

char *ptr="Good Morning"; 

seguido por

printf(ptr + 5); 

que es &ptr[5] esto apunta a adress "mañana";

Adición de un número entero n para un resultado puntero a una dirección ptr + n * sizeof (tipo)

4

Debido "Good Morning" es un puntero a la cadena (en realidad al primer byte de la misma) y la adición de 5 a ese puntero produce un puntero al 5to personaje. Las cadenas C tienen terminación nula, de cualquier forma, printf se ejecuta hasta que encuentra el nulo al final.

25

Este es un artefacto de C puntero-aritmética; printf es solo una pista falsa.

El tipo de una cadena literal (como "Good morning ") es const char * Su código es equivalente a:..

const char *p = "Good morning"; 
p = p + 5; 
printf(p); 

Adición de un puntero y un número entero produce un puntero al elemento quinto en la secuencia

+0

Anotador: ¿me gustaría comentar? –

3

se hace avanzar el puntero de entrada por 5 bytes y por lo tanto se salta la palabra "bueno".

Esto es pointer arithmetic en C.

Asumamos puntero base de la cadena "buena mañana" es p, y 5 + p = p + 5 y apunta a letra M.

Por lo tanto la entrada a printf es el puntero de la letra M.

Cuestiones relacionadas