[英]what does the output of this code mean? printf(“%d”, “x”);
這是完整的代碼
#include<stdio.h>
int main(void) {
printf("%d", "x");
getchar();
return 0;
}
輸出為15620184。邏輯上應返回字符串“ x”的數字值。 但是x本身不是字符串。
我想弄清楚,就像其他人所說的那樣,此代碼是錯誤的,因為它具有未定義的行為,因此可以在您的平台上執行任何操作。 不要這樣做...但是有助於理解:-
"x"
是一個字符串常量,它衰減為該字符串的指針,並作為參數傳遞給printf
。 您已經要求它打印一個“ int”,以便它將地址的字節解釋為好像是一個int
並打印出來。
實際上,這將以十進制數字打印字符串存儲的地址。
但是標准中沒有任何東西可以保證這一點,它可以做任何事情,並且在其他平台上可能會有所不同。 總的來說,由於C的實現方式,盡管在大多數情況下,它將按照我描述的那樣進行。
請注意,在某些64位平台上,int是32位,而地址是64位,因此,它最多可能僅根據地址的一半字節輸出整數。
正如其他人所說的那樣,它是不確定的且不好的,所以不要這樣做,但是了解它的實際作用仍然很有用。
編輯:根據建議...如果要解釋正確傳遞的數據,請使用%p
而不是%d
,后者告訴printf
將傳遞的數據解釋為內存地址而不是int
。 盡管格式取決於系統,但它可能會打印為相同的int
,並且是正確定義的行為,然后
這段代碼是“ UNDEFINED BEHAVIOR ”,您永遠不要使用它來打印您必須使用"%s"
作為說明符的字符串,打印存儲在指針中的地址,您必須使用"%p"
並強制轉換指針使void *
printf("%p\n", (void *) "x");
總是在printf()
后面添加一個"\\n"
字符以刷新輸出緩沖區,這對於stderr
來說是不必要的,但是養成這種習慣還是不錯的。
另外, "x"
是一個字符串,如果您希望將字符'x'
的ascii值設為該字符,則此
printf("%d\n", 'x');
請注意單引號。
請閱讀print(3) ,並了解由printf()
和family處理的許多說明符。
該代碼的作用是什么? printf(“%d”,“ x”);
該代碼將具有未定義的行為。 您粘貼的代碼將發出警告。 看看我用gcc
編譯代碼得到的警告。
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
printf("%d", "x");
在查看了以上警告之后,您可以知道應該使用int
類型的變量或常量代替"x"
,但是您已經傳遞了一個指向以空字符結尾的字符數組( which is "x"
)的指針。 這是因為您在printf函數中指定了格式說明符"%d"
,它需要一個int
數據類型變量或常量。
邏輯上應該返回字符串“ x”的數字值
要打印char類型或字符常量( 'x'
)類型的變量的數值,請使用printf作為
printf("%d", 'x'): //Remeber character literal in c are stored as int
要打印字符數組"x"
,請使用printf作為
printf("%s", "x"); //OR
printf("x");
要打印存儲在指針中的地址,必須使用“%p”格式說明符作為
printf("%p", "x");
c中有許多格式說明符。 下面給出的很少-
%c - For Character Variable
%d - For Integers
%f - For Double
%s - For Null-Terminated Character Array
%p - For Pointers (of void * type)
本質上,您試圖將字符串文字"x"
的地址打印為十進制整數,但不能保證正常工作。
表達式 "x"
類型為“ char
2元素數組”; 由於該表達式不是sizeof
或一元&
運算符的操作數,因此將其轉換(“衰減”)為“ pointer to char
”類型的表達式,並且該表達式的值是字符串的第一個字符的地址。
d
轉換說明符期望其對應的參數具有int
類型; 您要傳遞int *
類型的參數,因此行為是不確定的。 輸出可能是地址值的精確表示形式(十進制整數),也可能是總垃圾。
類型很重要,特定的轉換指定者希望其對應的參數具有特定的類型(改編自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 *
注意,指針值的表示是實現定義的。 您可能要使用的大多數平台都會以十六進制表示形式輸出整數值。 有些人可能會為NULL指針輸出字符串“ null”。 有些人可能使用完全不同的表示形式。
請注意,要打印指針值,應將參數顯式轉換為void *
如果尚未創建):
printf( "%p\n", (void *) "x" );
這可能是C中唯一需要將指針值顯式轉換為void *
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.