2012-10-25 51 views
7

可能重複:
Parameter evaluation order before a function calling in C錯誤輸出,同時運行C語言代碼

對於下面的代碼我期望的輸出爲20和76,而是75和21正在添加作爲輸出。請解釋爲什麼是這樣。

#include<stdio.h> 

    unsigned func(unsigned n) 
    { 

     unsigned int a =1 ;   
     static unsigned int b=2;   
     a+=b; b+=a;   
     { 

     unsigned int a=3;   
     a+=b; b+=a;   
     } 
     //printf("%d %d ",a,b); 
     return (n+a+b);   
    } 
    int main() 
    { 
     printf("%d %d\n",func(4),func(5)); 
     return 0; 
    } 
+0

我還沒有證實,但我強烈懷疑這一點:http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in-c – Mysticial

回答

10

你期待func(4)被調用之前func(5)但反對ite與您的編譯器發生。功能參數評估的順序是未指定的按C標準。因此,編譯器可以自由選擇首先調用哪個函數。因此,在不同的運行過程中,您可能會觀察到函數調用的不同順序,儘管使用相同的編譯器不太可能發生這種情況。

+0

哇。所以這就呈現了所有printf風格的funcs以及其他一些可能不可移植的func。 – SomeWittyUsername

+4

@icepack你爲什麼這麼認爲?如果標準沒有規定特定的順序,並且您將編寫依賴* unspecified *行爲的代碼,這意味着您的* code *不是可移植的,而是* printf()*。 –

+0

這是一個很好描述的情況,稱爲「功能副作用」,幾乎可以在每種語言中出現,應該避免。 http://stackoverflow.com/a/13063692/986760 – fayyazkl

1

參數以相反的順序壓入堆棧。在您的編譯器實現中,似乎在func(4)之前調用了func(5)

3

func(4)和func(5)的評估順序未由C標準定義。

2

表達式求值的順序是unspecified behaviour因此func(4)func(5)可以在不同的順序被稱爲你應該

你可能想參觀它更

Compilers and argument order of evaluation in C++

Parameter evaluation order before a function calling in C

+0

你的意思是未指定。該程序展現出未指定的行爲,但據我所知,它並不表現出未定義的行爲。 (「實際參數中的函數標識符的評估順序,實際參數和子表達式是未指定的」C99 6.5.2.2:10) –

+0

@Pascal:是的,你說得對。我的意思是實際上是 – Omkant

1

評估順序可能是原因。因爲,

//printf("%d %d\n",func(4),func(5)); 
     printf("%d \n",func(4)); 
     printf("%d \n",func(5)); 

打印

20 
76 
0

FUNC(5)得到第一次執行:

a = 3 
b = 13 
func(5) = 21 

由於,B:執行FUNC(5)後的變量

值是靜態的,執行func(4)後的值:

a = 14 
b = 57 
func(4) = 75 
0

代碼很簡單,記住static變量將在函數調用之間保留它們的值。

在程序中,由於編譯器(因此編譯器特異性的,不是由標準定義):

func(5)首先執行,:返回21 .. 解釋:

unsigned func(unsigned n) /*first with 5*/ 
    { 

     unsigned int a =1 ;   
     static unsigned int b=2;   
     a+=b; b+=a;  // a = 3, b = 5 
     { 

     unsigned int a=3;   
     a+=b; b+=a;  // a = 8, b = 13 
     } 
     //printf("%d %d ",a,b); 
     return (n+a+b);  // 5 + 3 + 13 = 21. 
    } 

FUNC(4)接下來執行,

解釋:

unsigned func(unsigned n) /*first with 5*/ 
    { 

     unsigned int a =1 ;   
     static unsigned int b=2;   
     a+=b; b+=a;  // a = 14, b = 27 
     { 

     unsigned int a=3;   
     a+=b; b+=a;  // a = 30, b = 57 
     } 
     //printf("%d %d ",a,b); 
     return (n+a+b);  // 4 + 57 + 14 = 75(which is printed first). 
    } 

因此輸出。

0

這是一個衆所周知的術語,稱爲「功能副作用」。你可以在一個函數內改變一個變量,調用該函數並依靠一個聲明使用期望它已經改變的變量。通常這應該避免,並不是一個好方法。

在這種情況下更好的替代方法是調用函數並存儲返回值,然後在printf中使用它們或進行兩個不同的printf調用。

side effects