-1
我的機器下面的代碼的輸出是奇怪使用%d 6次會給出一個奇怪的輸出結果。爲什麼?
#include <stdio.h>
void main() {
int x = 5,y=6,sum=0;
sum=x+y;
printf("%d %d %d %d %d %d", sum = x +y);
getch();
}
我的機器下面的代碼的輸出是奇怪使用%d 6次會給出一個奇怪的輸出結果。爲什麼?
#include <stdio.h>
void main() {
int x = 5,y=6,sum=0;
sum=x+y;
printf("%d %d %d %d %d %d", sum = x +y);
getch();
}
也就是說未定義行爲。
簡短的回答是不這樣做,並使編譯器警告在編譯時-Wformat
或-Wall
檢測到它。
龍答:
函數聲明爲:
int printf(const char *format, ...);
這意味着它知道第一個參數是一個格式,之後可能會有更多一些。它會掃描format
字符串,並且對於每個說明符(例如%d
),它會嘗試從與該類型對應的堆棧中刪除數據(在本例中爲int
)。
當調用你的函數,你這樣做:
push sum
push const_format_string_pointer
call printf
在printf中,它會先讀取const_format_string_pointer,然後相加,那麼無論是和之前的堆棧。這通常是調用函數的局部變量(在此例中爲x
,y
,sum
)。事實上,它確實打印出11和6,對應於sum
和y
。另一個%d
可能會打印出5個。
三個大數字是編譯器爲了自己的需要而添加到堆棧中的東西。它們在調試模式下有意義,但它是編譯器特定的。此外,如果您通過優化編譯代碼(例如-O2
),它可能會刪除部分或全部較大的數字,並且您最終會在堆棧中打印比調用方的本地函數更深的內容,例如調用者的推送ebp
,或來電者的回信地址等。
你期望的結果是什麼,你要求打印6個數字,你打算打印哪些數字? – pm100