C 引數傳遞問題

2021-06-26 06:13:33 字數 1300 閱讀 3551

偶然碰到乙個十分奇怪的問題,如下的**段。

#include using namespace std;

void fun(int a,int b,int c,int d);

void main()

{ int i=6;

fun(++i,i++,i++,++i);

cout<

大家可以自己想思考下這樣結果的原因。

想了很久,查詢了很多資料,最後我的理解如下,如果有什麼不妥大家一起討論學習一下。

首先、main函式執行到fun函式時,先計算函式的實參,這順序一般函式都是從右至左,編譯器需要從右至左儲存引數,所以等於是執行了++i,i++,i++,++i這四步。

我們知道在記憶體模組中,有乙個堆疊塊,用於儲存區域性變數,形參,實參。在這個**中,函式引數使用值傳遞,也就將實參的值賦給了形參。而在堆疊塊中,實參和形參是分開儲存的,所以在main中呼叫fun函式時,會開闢一塊記憶體用於儲存形參,然後將實參值賦值過來。

然後,還有乙個要注意的地方,自增自減操作符,首先,前置自增是運算元加一,同時操作結果是修改後的值;而後置自增是運算元加一,但操作結果是修改前的值。比如

int i=0;

int j;

j=++i;//結果是j=1,i=1

j=i++;//結果是j=1,i=2

更重要的是,前置操作返回的是乙個左值,而後置操作返回的是乙個右值。左值可直接作為實參,而右值一般是不能直接作為引數傳遞的,但是現在的c++版本中,提供了乙個右值引用,所以現在右值也可以當實參,不過是引用傳遞而不是值傳遞。(大家對值傳遞與引用傳遞的區別一定比較熟悉了)

綜合上述,我理解的過程是這樣,首先執行到fun入口,main函式先計算實參,首先是++i,這相當於直接在**中加了一句++i,直接作為左值,而這修改的是i本身(這時i為7),再將這個i作為引數(所以後面對i修改,這裡引數的值也會變);然後是i++,不能直接做實參,所以會開闢一塊新記憶體,儲存i++的返回值為7(這時i為8);之後又是i++,同理,開闢一塊新記憶體,儲存i++的返回值為8(這時i為9);最後是++i,相當與直接修改了i(這時i為10)。

然後執行到fun函式,按照上面相反的順序來取形參,引數a直接賦予i的最新結果10;引數b為上面第二次開闢記憶體的引用,結果是8;引數c為上面第一次開闢記憶體的引用,結果是7;而引數d是直接賦予i的最新值10。

大家可以試著改變mian中fun函式的實參列表,如fun(i++,++i,i,i++,++i);看看按照上述理解的結果是否正確。

C語言 陣列引數傳遞問題

陣列傳遞引數的話,如果直接傳指標過去。對陣列引數的操作會改變原始變數的值。如果不想影響原始變數的話,需要在函式裡面定義新的區域性陣列變數。賦值給區域性陣列變數,對區域性陣列變數進行操作。include include include int setarray char array int setar...

c 引數傳遞

引數型別分為int,ref,out三種,預設為int.int型別在字方法中修改了對應變數後,主方法中的值不會發生變化.ref型別在方法中修改了對應變化後,主方法中的值也會發生變化.out主方法中對應的變數不需要初始化.例子 using system using system.collections....

C 引數傳遞

2.指標與引用區別 3.引數為指標的指標或指標的引用 將實參複製乙份給形參,形參為函式的區域性變數,因此函式對形參操作對實參沒有影響。若傳遞物件會產生物件副本,會呼叫拷貝建構函式,操作完後要呼叫析構函式。形參為指向實參位址的指標,其也算一種按值傳遞,只不過是將實參的位址作為引數傳遞給形參,因此函式對...