#include <stdio.h>
int main()
{
printf(5 + "Good Morning\n");
return 0;
}
代碼打印上午。代碼應該打印Morning還是應該顯示未定義的行爲?printf的行爲()
#include <stdio.h>
int main()
{
printf(5 + "Good Morning\n");
return 0;
}
代碼打印上午。代碼應該打印Morning還是應該顯示未定義的行爲?printf的行爲()
它應該顯示'早上'。
你正在使用指針算術 - 儘管你似乎不知道它! "Good Morning\n"
是一個char *
指向常量字符串的指針。然後你給這個指針加5,它將前進5個字符。因此指針現在指向'Morning'的'M'。
該代碼是正確的,因爲printf
定義爲:
int printf (const char * format, ...);
而且根據指針arithmitic 5 + "Good Morning\n"
是指向的"Morning\n"
第一個元素。所以statment:
printf(5 + "Good Morning\n");
具有相同的結果:
printf("Morning\n");
說明:
|G|o|o|d| |M|o|r|n|i|n|g|\n|
^ ^
| |
"Good Morning\n" >---- |
+ |
5 >----------------------
這不完全等同於二進制文件仍然包含整個字符串。如果函數不像'printf',在指針傳遞之前回溯到字節,以及它在正常情況下浪費空間的事實,這可能是重要的。 – abligh
是什麼讓你有 「未定義行爲」 作爲一個可能的方案?這個代碼中有什麼特別讓你懷疑UB? – AnT
這裏的答案已經很好地解釋了發生了什麼,但作爲一個經驗法則,您應該避免使用printf的非常量格式參數,因爲這會使編譯器難以找到類型錯誤。考慮做'printf(「%s」,「早上好」\ n「+ 5)'而不是 – hugomg
奇怪的是,這並不是一堆無數的問題。指針算術似乎很少見。 – devnull