理解陣列和引用作為引數和返回值傳遞

2021-08-15 08:42:15 字數 4570 閱讀 9724

根本:陣列不能拷貝,所以函式、返回值傳遞陣列變數只能通過陣列的指標或者是引用

一、函式返回值問題:指標(注:函式的返回值不能是陣列,只能是陣列的指標或是引用)

1、函式返回指標(包含動態陣列)

宣告:int * retarray(int i);

宣告:int * retarray(int i)[10];函式返回陣列,內部儲存為基本資料型別的指標

注:此種定義是錯誤的,函式返回值為陣列是被禁止的,只能通過陣列指標或是引用

2、函式返回值是個固定大小的陣列指標,陣列儲存的資料為基本資料型別

宣告:int (*retarray(int i))[10] ;  //此函式返回值為陣列內部為int的10大小陣列指標

定義:

int (*retarray(int i))[10]

;    return &a; //對於函式返回值固定元素數,需要返回&取位址符

}

3、函式的返回值固定大小的陣列指標,陣列儲存的資料為基本資料型別的指標

宣告:int *(* retarray(int i))[10];

定義:

int *(* retarray(int i))[10]

return &a;

}

二、函式返回值問題:引用

1、函式返回引用

宣告:int & retarray(int i);  此種宣告只能用作返回基本資料型別的變數,不能返回陣列

宣告  int & retarray(int i)[10];  函式返回陣列,內部儲存基本資料型別的引用

注:此種定義是錯誤的,函式返回值為陣列是被禁止的,只能通過陣列指標或是引用,且定義引用陣列是錯誤的

2、函式返回值是固定大小的陣列引用,陣列儲存資料為基本資料型別

宣告: int (& retarray(int i))[10];

定義:

int (& retarray(int i))[10]

;    return a;

return a;

}

2、定義:int &(* retarray(int i))[10];

報錯:不准定義內部為引用型別的陣列

四、函式返回值利用型別別名

1、型別別名定義返回值型別

using array = int [10];   typedef int array[10]    //定義array陣列

array * retarray(int i); //返回乙個指向含有10個整數的陣列指標

array & retarray(int i); //返回乙個含有10個整數陣列的別名

2、decltype定義返回值型別

int array = 

decltype(array) * retarray(int i); //返回乙個指向含有10個整數的陣列指標

decltype(array) & retarray(int i); //返回乙個含有10個整數的陣列別名

3、使用尾置型別

宣告:auto retarray(int i) -> int (*)[10];   //函式retarray接受整形引數i,返回int型陣列指標

宣告:auto retarray(int i) -> int* (*)[10];  //函式retarray接收整形引數i,返回int*型陣列指標

宣告:auto retarray(int 0) -> int [10];      //報錯,函式不能直接返回陣列

宣告:auto retarray(int i) -> int &;             //返回整形變數的引用

宣告:auto retarray(int i) -> int (&)[10];   //返回整形陣列的引用

宣告:auto retarray(int i) -> int &[10]      //返回引用陣列是不被允許的

宣告:auto retarray(int i) -> int* (&)[10];  //返回指標陣列的引用

宣告:auto retarray(int i) -> int& (*)[10];  //不允許返回引用陣列         

五、陣列作為引數傳遞

當宣告的陣列為指標陣列(int (*))或者引用陣列(int (&))的時候需要指定陣列的大小

1、指標

呼叫:

int *i = nullptr;

retarray(i);

宣告:int retarray(int (*i)[10]);   //形參顯式指定大小

宣告:

template //非型別引數,代表數值

void retarray(int (*i)[t],int (*j)[u])

呼叫:

int (*arr)[10];

retarray(arr);

宣告:int retarray(int *i);  //形參可以不必顯式指定陣列大小

呼叫:

int *arr[10];

for (int i;i<10;++i)

retarray(arr);

宣告:int retarray(int *(*i)[10])   //此處需要顯式指定陣列大小

宣告:

templateint ret(int *(*i)[t])
呼叫:

int * (*arr)[10] = nullptr;

retarray(arr);

2、引用:

定義:int retarray(int &a);    //陣列可以轉變為指標(精確匹配),所以實際上傳遞的是指標

呼叫:

int a =10;

retarray(a);

定義:int retarray(int (&a)[10]);   //此處引數必須顯式指定大小

定義:

template //非型別引數,代表數值

int retarray(int (&a)[t],int (&b)[u])

呼叫:

int arr[10] = ;

retarray(arr);

定義:int retarray(int& (&a)[10]);   

報錯:定義內部為基本資料型別引用的陣列是被禁止的

3、指標、引用混合

定義:int retarray(int *(&a)[10]));    //陣列指標或者是陣列引用必須指定唯獨大小

定義:

templateint ret(int * (&a)[t]);
呼叫:

int *arr[10];

retarray(arr);

定義:int retarrar(int &(*a));

報錯:定義基本資料型別的引用的陣列是被禁止的 

4、注意

指標作為指向記憶體的變數,當其作為實參變數傳給形參時;

記憶體中也會申請乙個指標形參變數的空間來儲存指向的變數空間位址,這就涉及到變數到變數拷貝問題;

只不過實參與形參所指向的記憶體空間一致,可以通過形參來修改實參所指向的空間數值;

所以函式內部修改形參儲存的變數值(即變數位址),任由形參指向那個新變數,都不會改變實參的指向的位址值,但修改形參指向空間變數時(前提是實參與形參指向同乙個位址)時,實參指向的空間變數值也會被修改。

int **p或者是 int *q[constant];
尤其要注意:

q陣列內部已經分配了空間,儲存全部為0x0000(指向0x0000),且其內部空間必須儲存為指向int *的變數,但是陣列內部指標指向的空間未指向;

p並沒有指向明顯空間,但是編譯器會讓其預設指向0x0000空間(保留空間,無權讀寫),其指標值儲存為0x0000。

注意要為p指向兩個空間值:

p = (int **)malloc(sizeof(int));

*p = (int *)malloc(sizeof(int));

int a = 1;

int *pointb = &a;

int *pointc = &a;

//pointb和pointc內部均儲存變數a的位址值,即指向的空間相同

cout << pointb;

cout << pointc;

//輸出的儲存變數位址值相同

//但是儲存pointb和pointc指向位址值的空間不是乙個空間,只不過他們的指向的空間相同

cout << &pointb;

cout << &pointc;

//輸出的儲存的指標變數值不同

指標和引用作為返回值

一 函式返回值 1.如果返回值小於4byte 用暫存器eax帶回返回值 2.如果返回值大於4byte小於8btye,用兩個暫存器eax edx帶回返回值 3.如果返回值大於8byte,在呼叫前main函式中產生臨時量接受返回值 二 臨時量生成的三種情況 1.函式呼叫之前產生,目的是為了接受函式的返回...

引用作為函式引數返回值

說明 1 以引用返回函式值,定義函式時需要在函式名前加 2 用引用返回乙個函式值的最大好處是,在記憶體中不產生被返回值的副本。例如 include float temp 定義全域性變數temp float fn1 float r 宣告函式fn1 float fn2 float r 宣告函式fn2 f...

「引用作為函式引數」與 「引用作為函式返回值」

一 引用作為函式引數 作為函式引數時引用有兩種原因 1 在函式內部會對此引數進行修改 2 提高函式呼叫和執行效率。關於第一點,都知道 c 裡提到函式就會提到形參和實參。如果函式的引數實質就是形參,不過這個形參的作用域只是在函式體內部,也就是說實參和形參是兩個不同的東西,要想形參代替實參,肯定有乙個值...