![](/img/trans.png)
[英]Why is the use of cin, cout or %I64d preferred over %lld specifier in C++?
[英]Why “%I64d” is giving strange output when it is used multiple times in same format string?
當我解決代碼強制的編程問題時,我發現當格式說明符“%I64d”在同一格式字符串中多次使用時,如:
long long int a, b, c;
a = 1, b = 3, c = 5;
printf("%I64d %I64d %I64d\n", a, b, c);
輸出是
1 0 3
但是,當我分隔每個說明符時,如:
long long int a, b, c;
a = 1, b = 3, c = 5;
printf("%I64d ", a);
printf("%I64d ", b);
printf("%I64d ", c);
puts("");
輸出是,如預期的那樣:
1 3 5
這是一個ideone鏈接,可以看到上面的代碼片段: http ://ideone.com/f2udRB
請幫我理解為什么會這樣? 如果這是未定義的行為,如何顯示這樣的輸出? 我怎樣才能理解有時出現這種意外輸出的原因?
使用格式字符串%I64d
printf()
需要堆棧上的4字節數字,因為使用GNU printf I
意思是“使用替代輸出數字”而64
表示“填充到64個字符”。 其余的d
代表帶符號的32位整數。
但是你要推8個字節的數字,因為a, b, c
的類型是long long
。
數字低於2 ^ 32,所以你看到的堆棧(以4字節為單位)
1 0 3 0 5 0
printf只解釋前3個數字,其余數字被丟棄。 當您使用%lld
, printf()
正確地將堆棧數據解釋為8字節數字。
請幫我理解為什么會這樣? 如果這是未定義的行為,如何顯示這樣的輸出?
是的,行為是未定義的,但輸出不同的原因是由於調用約定 。 ideone編譯器以32位運行,這意味着參數在堆棧上傳遞(根據System V ABI)而不是寄存器。 您可能會看到代碼的反匯編顯示如下:
push 0
push 5
push 0
push 3
push 0
push 1
push OFFSET FLAT:.LC0
call printf
第二個代碼片段是不同的,因為您每次只傳遞一個參數,因此它獲得正確的(即第一個)值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.