2010-06-07 39 views
9

我有一些C代碼:函數參數中的預增和後增的操作順序?

main() 
{ 
    int a=1; 
    void xyz(int,int); 

    xyz(++a,a++);  //which Unary Operator is executed first, ++a or a++? 

    printf("%d",a); 
} 
void xyz(int x,int y) 
{ 
    printf("\n%d %d",x,y); 
} 

功能xyz在,++aa++傳遞兩個參數。有人可以解釋操作的順序來解釋結果嗎?

上面的代碼根據使用的編譯器打印「3 13」或「2 23」。

+1

如果您在示例程序中使用了不同的變量,它可能會更清晰。另外,你應該在你正在打印的值之後加上「\ n」*,而不是之前。這將打印「2 23」 – DevinB 2010-06-07 13:07:50

+0

你應該嘗試一些更清楚。這個語法對於一個人來說很奇怪。簡化代碼,不要試圖編寫複雜的東西。 – INS 2010-06-07 14:51:58

回答

26

嗯,有考慮與你的示例代碼兩件事情:

  1. 的函數參數評價的順序是不確定的,所以無論是++aa++首先計算是實現相關的。
  2. 多次修改a的值,如果在修改之間沒有序列點,則會導致未定義的行爲。所以,你的代碼的結果是不確定的。

如果我們簡化代碼並刪除不明確的,不確定的行爲,那麼我們就可以回答這個問題:

void xyz(int x) { } 

int a = 1; 
xyz(a++); // 1 is passed to xyz, then a is incremented to be 2 

int a = 1; 
xyz(++a); // a is incremented to be 2, then that 2 is passed to xyz 
+0

在第二種情況下,函數被調用之前更新了'a'是否爲真?我知道*表達式*'++ a'的結果是2,這是傳遞給'xyz'的結果,但我的理解是副作用可能不一定在函數調用之前應用。 – 2010-06-07 14:58:47

+2

@John:是的:在對函數的所有參數進行評估之後但在函數調用之前有一個序列點。 – 2010-06-07 15:01:38

9

引述Kernighan的&裏奇,章節2.12:

中的順序哪些函數參數 評估沒有指定,所以 語句

printf("%d %d\n", ++n, power(2, n)); /* WRONG */ 

可以與 不同的編譯器產生不同的結果,具體取決於 在調用 的電源之前n是否遞增。該溶液,當然,是 寫

++n; 
printf("%d %d\n", n, power(2, n)); 

函數調用,嵌套分配 報表以及增量和 遞減運算符原因``側 效應「」 - 一些變量改變 作爲副產物評價 的表達。在涉及副作用的任何表達式 中,可能存在 對 中的順序的微妙依賴性,其中參與 表達式的變量被更新。一個不高興 情況是由語句

a[i] = i++; 

的問題是,標 是否是我的舊值或新的代表。 編譯器可以用不同的方式解釋這個問題,並根據它們的解釋生成不同的 答案。標準 故意留下大多數此類事項 未指定。當副作用 (賦值給變量)發生時 的表達式由編譯器自行決定,因爲 的最佳順序強烈依賴於機器的 體系結構。(該標準並 指定的 參數所有副作用生效稱爲 函數之前,但不會在通話 幫助上面的printf)的 寓意是寫代碼 取決於評估的順序在任何 語言中都是 糟糕的編程習慣。當然,需要 知道需要避免什麼,但是如果您不知道如何在各種機器上完成它們,您將不會被誘惑 來利用特定的 實現。一個函數

2

元運算符的評價順序:

#include <stdio.h> 

void xyz(int x, int y) { 
    printf("x:%d y:%d ", x, y); 
} 

main() { 
    int a; 
    a=1; xyz(++a, a);  printf("a:%d\n", a); 
    a=1; xyz(a, a++);  printf("a:%d\n", a); 
    a=1; xyz(++a, a++);  printf("a:%d\n", a); 
} 

將輸出

x:2 y:2 a:2 
x:2 y:1 a:2 
x:3 y:1 a:3 

在我的系統。這表明函數的第二個參數正在被首先評估。您不應該依賴函數參數的評估順序。它沒有定義,所以它在不同的系統上會有所不同。儘管如此,找到這種行爲的一個很好的例子還是不錯的。

-1

對於非上等運算符,有前增量(++ i)和後增量(i ++)。對於預增量,要增加的值將在操作之前添加。例如:

#include <iostream> 
using namespace std; 

void main() 
{ 
    int i = 0; 
    cout << ++i; 
} 

在這種情況下,輸出將是1。變量的「i」是由1的值之前的任何其它操作遞增即「清點< < ++ I」。現在

,如果我們這樣做了後增量在同一個函數:

#include <iostream> 
using namespace std; 

void main() 
{ 
    int i = 0; 
    cout << i++; 
} 

輸出只會是0。這是因爲增量會在手術後發生。但既然你想知道在將它們作爲參數,這是它怎麼會跑到:

#include <iostream> 
using namespace std; 
// Function Prototypes 
void PrintNumbers(int, int); 

void main() 
{ 
    int a = 0, b = 0; 
    PrintNumbers(++a, b++); 
} 

void PrintNumbers(int a, int b) 
{ 
    cout << "First number: " << a << endl; 
    cout << "Second number: " << b << endl; 
} 

當通過這些變量作爲參數,輸出將是:

First number: 1 
Second number: 0 

我希望這幫助!