Tag: Call by pointer

  • C++ 來搞懂函數的傳值Call by value、傳址Call by pointer以及傳參考Call by reference。

    學生時代…
    作者在學這一章節時, 坦白講….腦袋一片空白, 幾乎是用死背阿!

    當出了社會後幾年(本行是玩PLC、Software platform、數位原理以及通訊拆解), 之後再來看CPP 這一章節, 變得很好從底層出發, 去了解這個語言獨有的一些 記憶體操作方法。

    在C++ 世界裡面, 我們常常會利用函數去做運算, 甚至是處理些重複性高的工作

    在講解函數之前,必須先把何謂函數的引數和參數弄個清楚。

    函數引數(argument)以及參數(parameter)

    以下介紹參考來源

    函數的引數(argument) v.s. 函數的參數(parameter)
    使用函數(或稱函式或副程式)時,常常會遇到這兩個名詞,本人也時常混淆,每個編輯的翻譯也不盡相同,但由於非常重要,必須做好釐清。

    1. 參數(parameter)用於「函數的宣告」,也就是在定義函數,或者宣告函數的原型時使用。由於必須要在函數的小括號內寫上參數的型態,故又稱為「形式參數」,可記為「參數的型式」。
      A. 在定義函數時:
      void swapfunction(int x, int y) // x , y稱為參數(parameter),小括號內要寫上參數的型態
      { 函數定義域的程式碼,以參數x、y來撰寫敘述 ………
      }
    2. 引數(argument)是用於「呼叫函式」,也就是「執行函數」時的「輸入值」。
      B. 呼叫(執行)函數時:
      swapfunction(a,b); // ()中的a , b稱為引數(argument),不需要寫上型態

    透過呼叫的方式來執行函數

    我們是在B.中設定兩個引數a、b來使用這個函數。當電腦看到引數a、b後,便會將a、b傳遞給A.內的參數x、y,以執行函數所定義的運算,所以傳遞的方向是:「由引數(a、b)傳遞給參數(x、y)」。


    傳值 Call by value

    如果你要簡單暴力的傳遞值的方式。

    • 把變數資料移動到記憶體裡面
    //函數定義
    int MathFun(int x, int y) {
        return x + y;
    }

    傳址 Call by pointer

    Call by pointer 在我看到的網站以及資料…. 很多人稱作 Call by addres,我比較喜歡用 Call by pointer 這名子,
    這邊以最簡單的swapfun作為範例
    其中在傳址時相當於 int *x = &a; int *y = &b; 這樣的寫法。

    檢測記憶體位置_會交換??

    
    
    int a = 6;
    int b = 10;
    
    // 觀察記憶體位置會不會變化?? 
    
    void swapfun(int* x, int* y) {
    
    	cout << x << endl;
    
    	cout << y << endl;
    
    	int tmp = *x;
    	*x = *y;
    	*y = tmp;
    
    	cout << x <<endl;
    
    	cout << y << endl;
    }
    
    int main(void) {
    	
    // 傳址* 型態 只會接受參考& 
    
    	swapfun(&a, &b);
    
    }
    
    
    不會!

    a、b、x、y 記憶體位址都不一樣!!!!

    *註釋:

    參數與引數 https://notfalse.net/6/arg-vs-param

    • void swapfun (參數)
    • swapfun (引數)
    • & (參考)

    傳址:

    *x = &y 經過這個address 等式指派給另一個地址, 這個傳址才算是完成!

    變數會交換??

    
    // 檢測 變數會不會交換??
    
    void swapfun(int* x, int* y) {
    	cout << *x << endl;
    
    	cout << *y << endl;
    
    	int tmp = *x;
    	*x = *y;
    	*y = tmp;
    
    	cout << *x <<endl;
    
    	cout << *y << endl;
    }
    
    int main(void) {
    
    	// 傳址* 型態 只會接受參考& 
    
    	swapfun(&a, &b);
    
    }
    
    
    它們交換了彼此!
    一旦接觸到記憶體交換的”用法” ,請在交換的陳述式裡面繼續使用這些方法

    傳參考Call by reference

    int a =0;

    int& Ref_variable =a;

    • 有趣的事情…. Ref_variable 沒有分配記憶體空間,而是Ref_variable 跟a共用了記憶體空間!
    • 這是很多語言都沒有的記憶體操作方法!

    參考連結

    
    int main(void) {
        // a 為字串變數
        string a = "There is pointer A.";
        cout << a << endl;
    
        // b 為對 a 的指標
        string* b = &a;
        cout << b << endl;
    
        // c 為對 a 的參考
        string& c = a;
        cout << c << endl;
    
        return 0;
    }