簡體   English   中英

為什么“%I64d”在同一格式字符串中多次使用時會給出奇怪的輸出?

[英]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個數字,其余數字被丟棄。 當您使用%lldprintf()正確地將堆棧數據解釋為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM