简体   繁体   English

用printf打印字符

[英]Printing a char with printf

Are both these codes the same 这两个代码是否相同

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

Will it print a garbage value? 它会打印垃圾值吗?

I am confused about this 我很困惑

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

Will this print 0 or garbage value? 这会打印0还是垃圾值? Because when i do this 因为我这样做的时候

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

It prints 4. Why is sizeof('\\n') 4 bytes? 它打印4.为什么sizeof('\\n') 4个字节? The same thing in C++ prints 1 bytes. C ++中的相同内容打印1个字节。 Why is that? 这是为什么?

So here's the main question 所以这是主要问题

in c language is printf("%d", '\\0') supposed to print 0 在c语言中, printf("%d", '\\0')应该打印0

and in C++ printf("%d", '\\0') supposed to print garbage? 在C ++ printf("%d", '\\0')应该打印垃圾?

%d prints an integer: it will print the ascii representation of your character. %d打印一个整数:它将打印您角色的ascii表示。 What you need is %c : 你需要的是%c

printf("%c", ch);

printf("%d", '\\0'); prints the ascii representation of '\\0' , which is 0 (by escaping 0 you tell the compiler to use the ascii value 0. 打印'\\0'的ascii表示,为0(通过转义0,告诉编译器使用ascii值0。

printf("%d", sizeof('\\n')); prints 4 because a character literal is an int , in C, and not a char . 打印4因为字符文字是int ,在C中,而不是char

This is supposed to print the ASCII value of the character, as %d is the escape sequence for an integer. 这应该打印字符的ASCII值,因为%d是整数的转义序列。 So the value given as argument of printf is taken as integer when printed. 因此,作为printf参数给出的值在打印时被视为整数。

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

Same holds for printf("%d", '\\0'); 同样适用于printf("%d", '\\0'); , where the NULL character is interpreted as the 0 integer. ,其中NULL字符被解释为0整数。

Finally, sizeof('\\n') is 4 because in C, this notation for characters stands for the corresponding ASCII integer. 最后, sizeof('\\n')是4,因为在C中,这个字符表示法代表相应的ASCII整数。 So '\\n' is the same as 10 as an integer. 所以'\\ n'与整数10相同。

It all depends on the interpretation you give to the bytes. 这一切都取决于你给字节的解释。

In C, character constant expressions such as '\\n' or 'a' have type int (thus sizeof '\\n' == sizeof (int) ), whereas in C++ they have type char . 在C中,诸如'\\n''a'字符常量表达式具有int类型(因此sizeof '\\n' == sizeof (int) ),而在C ++中它们具有char类型。

The statement printf("%d", '\\0'); 语句printf("%d", '\\0'); should simply print 0; 应该只打印0; the type of the expression '\\0' is int , and its value is 0. 表达式'\\0'的类型是int ,其值为0。

The statement printf("%d", ch); 声明printf("%d", ch); should print the integer encoding for the value in ch (for ASCII, 'a' == 97). 应该打印ch值的整数编码(对于ASCII, 'a' == 97)。

In C char gets promoted to int in expressions. 在C中, char被提升为表达式中的int That pretty much explains every question, if you think about it. 如果你考虑一下,这几乎可以解释每一个问题。

Source: The C Programming Language by Brian W.Kernighan and Dennis M.Ritchie 资料来源:Brian W.Kernighan和Dennis M.Ritchie的C编程语言

A must read if you want to learn C. 如果你想学习C,必须阅读。

Also see this stack overflow page , where people much more experienced then me can explain it much better then I ever can. 另外看到这个堆栈溢出页面 ,那里的人们经验丰富,然后我可以解释它比以前更好。

#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;
}

Yes, it prints GARBAGE unless you are lucky. 是的,它会打印GARBAGE,除非你很幸运。

VERY IMPORTANT. 很重要。

The type of the printf/sprintf/fprintf argument MUST match the associated format type char. printf / sprintf / fprintf参数的类型必须与关联的格式类型char匹配。

If the types don't match and it compiles, the results are very undefined. 如果类型不匹配并且编译,则结果非常不确定。

Many newer compilers know about printf and issue warnings if the types do not match. 许多较新的编译器了解printf并在类型不匹配时发出警告。 If you get these warnings, FIX them. 如果你收到这些警告,请修复它们。

If you want to convert types for arguments for variable functions, you must supply the cast (ie, explicit conversion) because the compiler can't figure out that a conversion needs to be performed (as it can with a function prototype with typed arguments). 如果要为变量函数的参数转换类型,则必须提供强制转换(即显式转换),因为编译器无法确定是否需要执行转换(因为它可以使用带有类型参数的函数原型) 。

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

In this example, printf is being TOLD that there is an "int" on the stack. 在这个例子中,printf是TOLD,堆栈上有一个“int”。 The cast makes sure that whatever thing sizeof returns (some sort of long integer, usually), printf will get an int. 演员确保无论sizeof返回什么东西(通常是某种长整数),printf都会得到一个int。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM