2011-01-19 14 views
16

Son estos dos códigos de la mismaImpresión de un char con printf

char ch = 'a'; 
printf("%d", ch); 

¿Va a imprimir un valor de basura?

Estoy confundido acerca de este

printf("%d", '\0'); 

Will esta impresión 0 o basura valor? Porque cuando hago esto

printf("%d", sizeof('\n')); 

imprime 4. ¿Por qué es sizeof('\n') 4 bytes? Lo mismo en C++ imprime 1 bytes. ¿Porqué es eso?

Así que aquí está la pregunta principal

en lenguaje C se supone que printf("%d", '\0') imprimir 0

y en C++ printf("%d", '\0') supuesta imprimir basura?

Respuesta

5

En C char se promociona a int en expresiones. Eso explica mucho cada pregunta, si lo piensas bien.

Fuente: El Lenguaje de Programación C W.Kernighan por Brian y Dennis M.Ritchie

A debe leer si quieres aprender C.

también ver this stack overflow page, donde la gente mucho más experimentado entonces me puede lo explicaré mucho mejor que nunca.

+0

@nightcracker: promovido ..? – BlackBear

+0

@BlackBear: Sí, porque (en la mayoría de los sistemas) un carácter es un byte y un int cuatro, por lo que es una promoción. – orlp

+0

@nightcracker: oh gracias. No me di cuenta de que% d;) – BlackBear

29

%d imprime un entero: imprimirá la representación ascii de tu personaje. Lo que necesita es %c:

printf("%c", ch); 

printf("%d", '\0'); impresiones de la representación ASCII de '\0', que es 0 (0 escapando le dicen al compilador que utilice el valor ASCII 0.

printf("%d", sizeof('\n')); impresiones 4 porque un carácter literal es un int, en C, y no un char.

+2

Ni siquiera leíste la pregunta del tipo. – orlp

+0

@nightcracker: ¿hm? Si 'printf ("% d ", ch);' imprime un valor de basura ", supongo que es porque quería imprimir' A', en lugar de su valor ascii ... – peoro

+0

Nunca dijo nada que imprimiera un valor de basura, él preguntó si lo haría o no. – orlp

7

Esto se supone que imprimir el valor ASCII del carácter, como %d es la secuencia de escape para un entero. por lo tanto el valor dado como argumento o f printf se toma como número entero cuando se imprime.

char ch = 'a'; 
printf("%d", ch); 

mismo vale para printf("%d", '\0');, donde el carácter NULL se interpreta como el número entero 0.

Por último, sizeof('\n') es 4 porque en C, esta notación para los caracteres representa el correspondiente entero ASCII. Entonces '\ n' es lo mismo que 10 como un entero.

Todo depende de la interpretación que le dé a los bytes.

+0

+1 para que printf ("% d", ch) muestre (int) 97 y printf ("% d", "\ 0") (int) 0 – BlackBear

+0

Yo diría que como "So '\ n' es un int, 32 bits, 4 bytes y sizeof() devuelve 4. El * valor * de '\ n' es 10, decimal. NEWLINE en ascii." La oración original es verdadera, pero quizás demasiado escueta. –

5

En C, carácter expresiones constantes tales como '\n' o 'a' tener tipo int (por lo tanto sizeof '\n' == sizeof (int)), mientras que en C++ que tienen tipo char.

La declaración printf("%d", '\0'); debe simplemente imprimir 0; el tipo de la expresión '\0' es int, y su valor es 0.

La declaración printf("%d", ch); debe imprimir la codificación de número entero para el valor en ch (por ASCII, 'a' == 97).

-2

Sí, imprime BASURA a menos que tenga suerte.

MUY IMPORTANTE.

El tipo del argumento printf/sprintf/fprintf DEBE coincidir con el tipo de formato asociado char.

Si los tipos no coinciden y compila, los resultados son muy indefinidos.

Muchos compiladores más nuevos saben sobre printf y emiten advertencias si los tipos no coinciden. Si recibe estas advertencias, CORREGELAS.

Si desea convertir tipos para argumentos para funciones de variables, debe proporcionar el molde (es decir, conversión explícita) porque el compilador no puede darse cuenta de que se debe realizar una conversión (como puede hacerlo con un prototipo de función con argumentos escritos).

printf("%d\n", (int) ch) 

En este ejemplo, se dice a printf que hay un "int" en la pila. El elenco se asegura de que sea cual sea el tamaño de los retornos (algún tipo de entero largo, generalmente), printf obtendrá un int.

printf("%d", (int) sizeof('\n')) 
+1

-1 Casi todo está mal aquí. Asumiendo que el prototipo para printf es visible, está perfectamente bien pasar un char o short a% d debido a las promociones integrales que ocurren para funciones variadas. Casting es tonto en el mejor de los casos. – Jens

3
#include <stdio.h> 
#include <stdlib.h> 

int func(char a, char b, char c) /* demonstration that char on stack is promoted to int !!! 
            note: this promotion is NOT integer promotion, but promotion during handling of the stack. don't confuse the two */ 
{ 
    const char *p = &a; 
    printf("a=%d\n" 
     "b=%d\n" 
     "c=%d\n", *p, p[-(int)sizeof(int)], p[-(int)sizeof(int) * 2]); // don't do this. might probably work on x86 with gcc (but again: don't do this) 
} 


int main(void) 
{ 
    func(1, 2, 3); 

    //printf with %d treats its argument as int (argument must be int or smaller -> works because of conversion to int when on stack -- see demo above) 
    printf("%d, %d, %d\n", (long long) 1, 2, 3); // don't do this! Argument must be int or smaller type (like char... which is converted to int when on the stack -- see above) 



    // backslash followed by number is a oct VALUE 
    printf("%d\n", '\377');    /* prints -1 -> IF char is signed char: char literal has all bits set and is thus value -1. 
                -> char literal is then integer promoted to int. (this promotion has nothing to do with the stack. don't confuse the two!!!) */ 
             /* prints 255 -> IF char is unsigned char: char literal has all bits set and is thus value 255. 
                -> char literal is then integer promoted to int */ 


    // backslash followed by x is a hex VALUE 
    printf("%d\n", '\xff');    /* prints -1 -> IF char is signed char: char literal has all bits set and is thus value -1. 
                -> char literal is then integer promoted to int */ 
             /* prints 255 -> IF char is unsigned char: char literal has all bits set and is thus value 255. 
                -> char literal is then integer promoted to int */ 


    printf("%d\n", 255);    // prints 255 


    printf("%d\n", (char)255);   // prints -1 -> 255 is cast to char where it is -1 
    printf("%d\n", '\n');    // prints 10 -> Ascii newline has VALUE 10. The char 10 is integer promoted to int 10 
    printf("%d\n", sizeof('\n'));  // prints 4 -> Ascii newline is char, but integer promoted to int. And sizeof(int) is 4 (on many architectures) 
    printf("%d\n", sizeof((char)'\n')); // prints 1 -> Switch off integer promotion via cast! 

    return 0; 
} 
+1

Limite sus líneas a 90 caracteres. La mitad de tu texto está oculto. –

Cuestiones relacionadas