简体   繁体   English

此代码的输出是什么意思? printf(“%d”,“ x”);

[英]what does the output of this code mean? printf(“%d”, “x”);

Here is the full code 这是完整的代码

#include<stdio.h>

int main(void) {

    printf("%d", "x");

    getchar();
    return 0;
}

The output is 15620184. Logically is should return the numeral value of the string "x". 输出为15620184。逻辑上应返回字符串“ x”的数字值。 But x itself is not a string. 但是x本身不是字符串。

I want to make it clear as other have said that this code is wrong because it has undefined behavior so could do absolutely anything on your platform. 我想弄清楚,就像其他人所说的那样,此代码是错误的,因为它具有未定义的行为,因此可以在您的平台上执行任何操作。 Don't do this... However to aid understanding :- 不要这样做...但是有助于理解:-

"x" is a string constant and this decays to a pointer to the string and passed as a parameter to printf . "x"是一个字符串常量,它衰减为该字符串的指针,并作为参数传递给printf You've asked it to print an "int" so it interprets the bytes of the address as if they were an int and prints those. 您已经要求它打印一个“ int”,以便它将地址的字节解释为好像是一个int并打印出来。

In practice this will print the address that the string is stored at as a decimal number. 实际上,这将以十进制数字打印字符串存储的地址。

But nothing in the standard guarantees this, it could do anything, and is likely to differ on other platforms. 但是标准中没有任何东西可以保证这一点,它可以做任何事情,并且在其他平台上可能会有所不同。 In general though, due to the way C is implement though in most cases it will do what I've described. 总的来说,由于C的实现方式,尽管在大多数情况下,它将按照我描述的那样进行。

Note than on some 64 bit platforms an int is 32 bits but an address is 64 bits so this is likely to at best only print an integer based on half the bytes of the address. 请注意,在某些64位平台上,int是32位,而地址是64位,因此,它最多可能仅根据地址的一半字节输出整数。

As others have said it's undefined and bad so don't do this, but it's still useful to understand what it's actually doing. 正如其他人所说的那样,它是不确定的且不好的,所以不要这样做,但是了解它的实际作用仍然很有用。

Edit: As suggested... If you want to interpret the data passed properly use %p instead of %d which tells printf to interpret the data passed as a memory address rather than an int . 编辑:根据建议...如果要解释正确传递的数据,请使用%p而不是%d ,后者告诉printf将传递的数据解释为内存地址而不是int Although the format is system dependent it's likely to be print the same int , and is properly defined behavior then 尽管格式取决于系统,但它可能会打印为相同的int ,并且是正确定义的行为,然后

This code is " UNDEFINED BEHAVIOR ", you should never use it, to print a string of characters you MUST use "%s" as the specifier, to print the address stored in a pointer you MUST use "%p" and cast the pointer to void * , example 这段代码是“ UNDEFINED BEHAVIOR ”,您永远不要使用它来打印您必须使用"%s"作为说明符的字符串,打印存储在指针中的地址,您必须使用"%p"并强制转换指针使void *

printf("%p\n", (void *) "x");

ALWAYS add a trailing "\\n" character to printf() to flush the output buffer, that's only unnecessary with stderr , but it's still good to develop the habit. 总是在printf() 后面添加一个"\\n"字符以刷新输出缓冲区,这对于stderr来说是不必要的,但是养成这种习惯还是不错的。

Also, "x" IS a string, and if you want the ascii value of 'x' the character then, this 另外, "x" 一个字符串,如果您希望将字符'x'的ascii值设为该字符,则此

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

note the single quotes. 请注意单引号。

Please read print(3) , and learn about the many specifiers handled by printf() and family. 请阅读print(3) ,并了解由printf()和family处理的许多说明符。

what does this code do? 该代码的作用是什么? printf(“%d”, “x”); printf(“%d”,“ x”);

The code will have undefined behavior. 该代码将具有未定义的行为。 The code you have pasted will give warning. 您粘贴的代码将发出警告。 Have a look at the warning that i have got by compiling your code with gcc . 看看我用gcc编译代码得到的警告。

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
  printf("%d", "x");

You can get to know after looking at the above warning that in place of "x" you should pass a variable or constant of type int but you have passed a pointer to null-terminated character array ( which is "x" ). 在查看了以上警告之后,您可以知道应该使用int类型的变量或常量代替"x" ,但是您已经传递了一个指向以空字符结尾的字符数组( which is "x" )的指针。 It is because you have specified a format specifier which is "%d" in your printf function which requires a int data type variable or constant. 这是因为您在printf函数中指定了格式说明符"%d" ,它需要一个int数据类型变量或常量。

Logically is should return the numeral value of the string "x" 逻辑上应该返回字符串“ x”的数字值

To print the numerical value of variable of type char or character constant ( 'x' ), use printf as 要打印char类型或字符常量( 'x' )类型的变量的数值,请使用printf作为

printf("%d", 'x'): //Remeber character literal in c are stored as int

To print the character array "x" , use printf as 要打印字符数组"x" ,请使用printf作为

printf("%s", "x"); //OR
printf("x");

To print the address stored in a pointer, you must use "%p" format specifier as 要打印存储在指针中的地址,必须使用“%p”格式说明符作为

printf("%p", "x");

There are many format specifiers in c. c中有许多格式说明符。 Few are given below- 下面给出的很少-

%c - For Character Variable
%d - For Integers
%f - For Double
%s - For Null-Terminated Character Array
%p - For Pointers (of void * type)

Essentially, you're attempting to print the address of the string literal "x" as a decimal integer, which isn't guaranteed to work. 本质上,您试图将字符串文字"x"的地址打印为十进制整数,但不能保证正常工作。

The expression "x" has type "2-element array of char "; 表达式 "x"类型为“ char 2元素数组”; since the expression is not the operand of the sizeof or unary & operators, it is converted ("decays") to an expression of type "pointer to char ", and the value of the expression is the address of the first character of the string. 由于该表达式不是sizeof或一元&运算符的操作数,因此将其转换(“衰减”)为“ pointer to char ”类型的表达式,并且该表达式的值是字符串的第一个字符的地址。

The d conversion specifier expects its corresponding argument to have type int ; d转换说明符期望其对应的参数具有int类型; you're passing an argument of type int * , so the behavior is undefined. 您要传递int *类型的参数,因此行为是不确定的。 The output may be an accurate representation of the address value as a decimal integer, or it may be total garbage. 输出可能是地址值的精确表示形式(十进制整数),也可能是总垃圾。

Types matter, and specific conversion specifers expect their corresponding arguments to be of a specific type (adapted from Harbison & Steele , § 15.11.7): 类型很重要,特定的转换指定者希望其对应的参数具有特定的类型(改编自Harbison&Steele ,第15.11.7节):

Output Format     Specifier        Argument Type
-------------     ---------        -------------
Decimal Integer     hhi,hhd                 char
 (Signed)             hi,hd                short
                        i,d                  int
                      li,ld                 long
                    lli,lld            long long
                      zi,zd               size_t
                      ti,td            prtdiff_t
                      ji,jd             intmax_t

Decimal Integer         hhu                 char
 (Unsigned)              hu                short
                          u                  int
                         lu                 long
                        llu            long long
                         zu               size_t
                         tu            prtdiff_t
                         ju             intmax_t

Octal Integer           hho         unsigned char
                         ho        unsigned short
                          o          unsigned int
                         lo         unsigned long
                        llo    unsigned long long
                         zo                size_t
                         to             ptrdiff_t
                         jo              intmax_t

Hexadecimal         hhx,hhX         unsigned char
 Integer              hx,hX        unsigned short
                        x,X          unsigned int
                      lx,lX         unsigned long
                    llx,llX    unsigned long long
                      zx,zX                size_t
                      tx,tX             ptrdiff_t
                      jx,jX              intmax_t

Decimal Float          f,lf                double 
                         Lf           long double

Decimal Float,    e,E,le,lE                double
 Exponential          Le,LE           long double     
 Notation           

Decimal Float,    g,G,lg,lG                double
 Same as f or         Lg,LG           long double
 e depending on 
 value

Hexadecimal       a,A,la,lA                double
 Float                La,LA           long double

Single Character          c                   int
Single Wide Character    lc                wint_t

String                    s                char *
Wide String              ls             wchar_t *

Pointer Value             p                void *

Note that the representation of a pointer value is implementation-defined. 注意,指针值的表示是实现定义的。 Most platforms you're likely to work on will output an integral value in hex notation. 您可能要使用的大多数平台都会以十六进制表示形式输出整数值。 Some may output the string "null" for a NULL pointer. 有些人可能会为NULL指针输出字符串“ null”。 Some may use a completely different representation. 有些人可能使用完全不同的表示形式。

Note that, to print a pointer value, you should explicitly cast the argument to void * if it isn't already: 请注意,要打印指针值,应将参数显式转换为void *如果尚未创建):

printf( "%p\n", (void *) "x" );

This is probably the only place in C where you need to explicitly cast a pointer value to void * . 这可能是C中唯一需要将指针值显式转换为void *

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

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