2014-09-30 72 views
-6
#include<stdio.h> 
int main() 
{ 
int a=1; 
printf("%d%d%d",a,++a,a++); 

} 

這裏爲什麼是輸出331和122不輸出錯誤在C程序

我互聯網上找到的理由是,arguements傳遞格羅姆從右到左。首先a ++然後++ a然後a得到評估,然後以相反的順序打印。這是正確的原因嗎?

+0

沒有告訴我原因 – 2014-09-30 10:07:50

+0

原因-undefined行爲 – 2014-09-30 10:09:14

+0

@酷guybut我的書說,它有什麼與調用約定 – 2014-09-30 10:10:43

回答

-1

GCC -S your_source.c解釋你的問題

movl $1, -4(%rbp) #, a 
    movl -4(%rbp), %ecx # a, a.0 
    addl $1, -4(%rbp) #, a 
    addl $1, -4(%rbp) #, a 
    movl -4(%rbp), %edx # a, tmp61 
    movl -4(%rbp), %eax # a, tmp62 
    movl %eax, %esi  # tmp62, 
    movl $.LC0, %edi  #, offset to "%d%d%d" sttring 
    movl $0, %eax  #, 
    call printf # 

編譯器開發者絕對不要指望有人會嘗試使用它在這樣一個醜陋的方式

如果你真的需要122:然後更改ASM代碼如下:

movl $1, -4(%rbp) #, a 
    movl -4(%rbp), %eax # a, a.0 
    addl $1, -4(%rbp) #, a 
    movl -4(%rbp), %edx # a, tmp61 
    movl -4(%rbp), %ecx # a, tmp62 
    movl %eax, %esi  # tmp62, 
    movl $.LC0, %edi  #, 
    movl $0, %eax  #, 
    call printf # 
    addl $1, -4(%rbp) #, a 
    leave 
-3

輸出取決於機器體系結構和編譯器。 請參閱:Compilers and argument order of evaluation in C++

在這種情況下,考慮到其中編譯器符合執行順序爲從右到左的機器:由左即

第三輸出,一個++將爲1,因爲它是一個後遞增的,這意味着a的現有值用於printf,然後其內存地址處的值遞增並保存。因此,printf獲取1作爲參數,之後a變爲2.

從左側開始的第二個輸出即++ a將是a(從上面2)加1的值。請注意,因爲它是預增量。首先更新a地址處的值,然後將此更新值傳遞給printf。因此,2 + 1 = 3

左起第一個輸出的值,也就是現在的3

+0

r使用讓我們c – 2014-09-30 10:17:02

+0

@IshanBansal它不依賴於書友。它取決於參數類型,被調用函數的調用約定,構造和編譯器。在x86上,Pascal調用約定從左到右評估參數,而在C調用約定(__cdecl)中,它是正確的。在這裏閱讀更多http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c – kundan 2014-09-30 10:34:28

+0

我不讚美你。你的回答是不正確的。 – 2014-09-30 11:13:40