偶然碰到乙個十分奇怪的問題,如下的**段。
#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.引數為指標的指標或指標的引用 將實參複製乙份給形參,形參為函式的區域性變數,因此函式對形參操作對實參沒有影響。若傳遞物件會產生物件副本,會呼叫拷貝建構函式,操作完後要呼叫析構函式。形參為指向實參位址的指標,其也算一種按值傳遞,只不過是將實參的位址作為引數傳遞給形參,因此函式對...