在C++函數中返回多個數值的三種方法

預備知識

指針函數

C++ 中指針函數的基本形式:

函數類型 * 函數名 (參數數據類型 參數1, 參數數據類型 參數 2,...){
    執行體 1;
    執行體 2;
    ...
}

例如下面這個函數就是一個指針函數:

int * a(int b[], int c){
    cout<<"Hello";
    return b;
}

指針函數的返回值是一個指針,在 main() 函數中調用該指針函數的時候,可以使用一個同類型的指針來接收。指針函數的作用之一就是解決一個函數中存在多個返回值的時候,如何返回這多個數值的問題。

靜態變量

C++ 中的變量,大致可以分爲(該分類不嚴格,僅供參考)“全局變量”、“局部變量”、“靜態變量”、“全局靜態變量(或稱“靜態全局變量”)”、“局部靜態變量(或稱“靜態局部變量”)”和指針變量等。局部變量是存放在內存的堆區的,一旦一個函數執行完畢,則編譯器就會自動釋放這部分內存,該局部變量也隨之消失。全局變量和靜態變量都是存放在數據區(也稱“全局區”或者“靜態區”)的,該區域的內容可以被全局共享,在整個程序結束時,由系統自動釋放。

指針變量用來存放指針,而指針就是一塊內存的地址,因此,指針變量存放的就是一個內存地址。指針變量也是一個變量,是變量就需要使用內存空間存放,需要使用內存空間就需要分配內存並獲取內存地址,因此,指針變量本身也是有內存地址的,存放指針變量的內存地址又指向了它存放的內存地址。指針變量的定義形式一般如下:

基類型 *指針變量名稱;

在函數中定義的變量都是局部變量(在一個程序的所有函數之外定義的變量稱爲“全局變量”),但是我們要返回這個變量供其他函數(例如 main() 函數)使用,這個時候就需要使用“局部靜態變量”來達到這個目的。

局部靜態變量的定義方法就是在定義的局部變量之前加上 static 關鍵字。

具體實現方法

C++ 中不允許把一個數組或者多個數值作爲一個整體返回,也就是說,對於 C++ 中的任何一個函數,其返回值只能是 0 個或者 1 個單獨的數字,不能是一個數組或者多個數字。不過,我們可以結合使用指針和數組(由於數組在內存中是使用一塊連續的區域存儲的,因此,只要知道了一個數組中第一個元素的地址並且知道了這個數組的長度,那麼就可以找到和處理整個數組)來達到返回多個數值的目的。

概括地說,至少有以下三種方法:

方法一

返回一個指針指向數組中第一個元素的地址,在已知數組中第一個元素的地址和數組長度的情況下,可以唯一確定一個數組。

示例程序如下:

#include <iostream>
using namespace std;

/*
定義一個返回指針的函數用於返回數組
*/
int * ReturnMyArr(){
    static int MyArr[5] = {0,1,2,3,4};
/*
C++ 不支持在函數外面返回局部變量的地址
因此,這裏定義爲 static 變量
*/

    return MyArr;
}

int main(){
    int *p;
/*
定義一個整數型指針
*/

    p = ReturnMyArr();
/*
將數組的第一個元素值在內存中
的地址賦值給指針變量p
*/

/*
通過指針p打印數組
*/
    for(int i = 0; i < 5; i++){
        cout << *(p+i) << " ";
    }
}

方法二

方法二其實沒有返回數組,自然也沒有涉及 return, 但是方法二同樣可以對數組進行處理,並使 main() 函數獲取到處理後得到的新數組。

方法二的主要原理就是把待處理的數組的第一個元素的地址作爲參數傳入用於處理該數組的函數,被處理後的數組寫入到了內存中,main() 函數從內存中讀取經過處理後的數組,這樣就達到了返回多個數值的效果。

示例程序如下:

#include <iostream>
using namespace std;

/*
把指針變量作爲形式參數輸入函數
該指針指向的是數組 a[] 中第一
個元素的地址
函數 ReturnMyArr() 的作用是對數
組 a[] 進行操作,操作的結果就寫
入到了內存中,可以被 main() 函數
使用,不需要有返回值,因此使
用 void
*/
void ReturnMyArr(int *p){

/*
使用指針逐個指向數組 a[] 的每一
個元素,將她們都賦值爲 0
*/
    for(int j=0; j<3; j++){
        *(p + j) = 0;
    }
}

int main(){
    int i = 0;
    int a[3] = {1,2,3};

/*
將數組 a[] 以實參的形式傳入函數
ReturnMyArr()
*/
    ReturnMyArr(a);

/*
循環打印
*/
    while(i < 3){
        cout << a[i] << " ";
        i++;
    }
}

運行結果如下:

0 0 0
Process returned 0 (0x0)   execution time : 0.232 s
Press any key to continue.

方法三

這裏也可以不借助局部靜態變量和指針實現對數組的返回。我們可以把變量定義在 main() 函數中,之後將這些變量作爲參數傳入指針函數。由於這些變量是定義在 main() 函數中的,因此只要 main() 函數沒有結束,即使指針函數結束了,這些參數也不會由於內存回收而被銷燬。

示例程序如下:

#include <iostream>
using namespace std;

int * ReturnMyArr(int a[]){
    for(int i = 0; i < 3; i++){
        a[i] = 0;
    }
/*
對數組 a[] 重新賦值
*/

    return a;
}

int main(){
    int a[3] = {1,2,3};
    int *p;
    p = ReturnMyArr(a);

    for(int i = 0; i <= 2; i++){
        cout << *(p+i) << " ";
    }

    return 0;
}

運行結果如下:

0 0 0
Process returned 0 (0x0)   execution time : 0.207 s
Press any key to continue.

如果我們不想改變數組 a[] 的數值,也可以新增一個數組 b[] 用於保存數組 a[] 經過指針函數計算後的結果。

示例程序如下:

#include <iostream>
using namespace std;

int * ReturnMyArr(int a[], int b[]){
    for(int i=0; i <= 2; i++){
        b[i] = a[i];
    }
    return b;
}

int main(){
    int a[3] = {1,2,3};
    int b[3];
    int *p;
    p = ReturnMyArr(a,b);

    for(int i = 0; i <= 2; i++){
        cout << *(p+i) << " ";
    }
    return 0;
}

運行結果如下:

1 2 3
Process returned 0 (0x0)   execution time : 0.194 s
Press any key to continue.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章