在我所知,%c
期望int值(如char
在Ç視爲整數),%s
預計char *
作爲參數,但我的疑問是,請問%S需要一個指向字符的塊?它可以指向雙引號中的單個字符嗎?%s和%c格式說明符之間有什麼區別?
例如:
char * s = "string";
printf("%s",s);// output: string
如何能夠計算出所述存儲器塊,其中該字符串存在並通過'\0'
終止編譯器?。
在我所知,%c
期望int值(如char
在Ç視爲整數),%s
預計char *
作爲參數,但我的疑問是,請問%S需要一個指向字符的塊?它可以指向雙引號中的單個字符嗎?%s和%c格式說明符之間有什麼區別?
例如:
char * s = "string";
printf("%s",s);// output: string
如何能夠計算出所述存儲器塊,其中該字符串存在並通過'\0'
終止編譯器?。
編譯器如何能夠找出 字符串以'\ 0'結尾的內存塊?
因爲字符串文字(雙引號之間的x個字符數量)獲取編譯器向其添加的NUL終止符\0
。
char * s = "string";
char foo = s[6]; // \0
所以printf
只是打印字符串中的字符,直到找到一個\0
。
是%s需要指向字符塊的指針。它可以指向一個 單引號雙引號?
是的你可以,雙引號中的單個字符仍然是一個字符串文字,最後是\0
。
在雙引號的單個字符仍然是一個C字符串,實際上包含兩個字符:單字符加上終止空字符:
char const* str = "a"; // actually points to an array { 'a', '\0' }
所以你還是有%s
使用它。其實,你可以與%c
使用它,也一樣,如果你取消引用字符串:
printf("%c\n", *str);
// ^
你可以做到這一點與任何C-字符串(與空單「」的除外),但只有前然後字符將被印...
加成響應您的評論:
函數調用(至少的cdecl和stdcall調用約定)將函數參數壓入堆棧完成(在大多數現代系統,類型比int小的int在堆棧中被提升爲int)。 printf
然後簡單地分析格式字符串,如果它發現%s,它會將堆棧中的下一個sizeof(void*)
字節解釋爲指向空終止字符串的指針(因此直接通過str
),如果它發現%c,它將直接讀取字符從堆棧 - 所以你需要放置一個,而不是一個指針,因此你需要解除引用。
或者,您可以使用'str [0]'而不是'* str'。 –
@Aconcagua爲什麼%c需要尊重str,但%s不是? –
@ Matec009添加了一些額外的信息給我的答案。 – Aconcagua
字符串由字符組成,就像char數組由字符組成一樣。
編譯器應該聰明,和gcc必須能夠識別哪個是哪個函數,[執行相應的操作(如添加一個空結束)
並回答你的問題,是的,它仍然會打印到控制檯,就像
char * s = "string";
printf("%s",s);// output: string
將打印到控制檯。
是的,它可以指向長度爲1的字符串。 –
*雙*引號中的單個字符仍然是一個C字符串,即NUL結尾,與單引號內的單個字符不同。 – Evert