1. 程式人生 > >C/C++語言 二維陣列作為函式的引數總結

C/C++語言 二維陣列作為函式的引數總結


C/C++語言二維陣列作為函式的引數總結

一、  情況1:實參為二維陣列

比如    int a[3][3];

呼叫形式    print(a);

//指標形式

void print(int** a);      //ERROR
void print(int* a[3]);    //ERROR;這是一個數組,不能將陣列直接傳值;因此錯誤
void print(int (*a)[3]);  //OK  二維陣列轉陣列指標
//純陣列形式
void print(int a[3][3]);  //OK    等同於void print(int(*a)[3]);
void print(int a[4][3]);  //OK    等同於void print(int(*a)[3]);
void print(int a[3][4]);  //ERROR 等同於void print(int(*a)[4]);
void print(int a[][3]);   //OK    等同於void print(int(*a)[3]);
void print(int a[][]);    //ERROR  類似於,但卻不是void print(int** a);
void print(int a[3][]);   //ERROR  類似於,但卻不是void print(int (*a)[3]);
//這本身就是傳參過程中的一個錯誤寫法;即不可能先知道高維維度,不知低維維度


二、  情況2:實參為指標陣列

比如    

int* a[3]
int b[3][3] = { 0 };
for(int i = 0; i < 3; ++i){ a[i] = b[i]; }

呼叫形式    print(a);

//指標形式

void print(int** a);      //OK
void print(int* a[3]);    //OK 
void print(int (*a)[3]);  //ERROR
//純陣列形式
void print(int a[3][3]);  //ERROR    等同於void print(int (*a)[3]);
void print(int a[4][3]);  //ERROR    等同於void print(int(*a)[3]);
void print(int a[3][4]);  //ERROR    等同於void print(int(*a)[4]);
void print(int a[][3]);   //ERROR    等同於void print(int(*a)[3]);
void print(int a[][]);    //ERROR   無法將其轉化為void print(int** a);
void print(int a[3][]);   //ERROR  這本身就是傳參過程中的一個錯誤寫法;即不可能先知道高維維度,不知低維維度


三、  情況3:實參為陣列指標

比如    int (*a)[3];

       int b[3][3] = {0};

       a = b;

呼叫形式     print(a);

//指標形式

void print(int** a);      //ERROR
void print(int* a[3]);    //ERROR 
void print(int (*a)[3]);  //OK
//純陣列形式
void print(int a[3][3]);  //OK    等同於void print(int(*a)[3]);
void print(int a[4][3]);  //OK    等同於void print(int(*a)[3]);
void print(int a[3][4]);  //ERROR    等同於void print(int(*a)[4]);
void print(int a[][3]);   //OK    等同於void print(int(*a)[3]);
void print(int a[][]);    //ERROR   無法將其轉化為void print(int**a);
void print(int a[3][]);   //ERROR 這本身就是傳參過程中的一個錯誤寫法;即不可能先知道高維維度,不知低維維度
 


四、  情況4:實參為二維指標

比如   

int** a;
int b[3][3] = { 0 };
int* c[3];
for(int i = 0; i < 3; ++i){ c[i] = b[i]; }
a = c;

呼叫形式    print(a);

//指標形式

void print(int** a);      //OK
void print(int* a[3]);    //OK 等價於void print(int** a);
void print(int (*a)[3]);  //ERROR
//純陣列形式
void print(int a[3][3]);  //ERROR    等同於void print(int(*a)[3]);
void print(int a[4][3]);  //ERROR    等同於void print(int(*a)[3]);
void print(int a[3][4]);  //ERROR    等同於void print(int(*a)[4]);
void print(int a[][3]);   //ERROR    等同於void print(int(*a)[3]);
void print(int a[][]);    //ERROR   無法將其轉化為void print(int**a);
void print(int a[3][]);   //ERROR 這本身就是傳參過程中的一個錯誤寫法;即不可能先知道高維維度,不知低維維度


五、  總結

序號

              實參形式





形參形式

二維陣列
int a[3][3];

指標陣列
int* a[3];

陣列指標
int (*a)[3]

二維指標
int** a;

1

void print(int** a);

2

void print(int* a[3]);

3

void print(int (*a)[3]);

4

void print(int a[3][3]);

5

void print(int a[4][3]);

6

void print(int a[3][4]);

7

void print(int a[][3]);

8

void print(int a[][]);

9

void print(int a[3][]);

備註:√表示呼叫成功;ⅹ表示呼叫失敗。

通過表格,可知:

(1) 1與2的形式完全等價;

(2) 3、4、5和7的形式完全等價

(3) 8和9屬於非法形式

(4) 通過4,5,6,7,可知:

對於傳陣列,低維階數一致是一個必要條件。6必然非法。

對於高階維數的維度其實沒有傳遞給函式,只是象徵意義上的顯示,沒有實際意義。

意思就是說,每次都可以將陣列降為指標,但每次只能降一次。對於每次函式呼叫只能順次降一級,多次下降必然報錯;也就是說,對於二維陣列,可以用陣列指標傳值,但是如果用二維指標傳遞就會報錯。

記住,實參形參之間進行傳遞的實質:始終傳遞的是指標,不可能是陣列

對於二維陣列實參,傳遞引數的時候,它已經將為陣列指標;對於形式引數裡面的[],每次轉換隻能轉換其中的一個為指標,如果轉換之後的指標,與傳遞過來實參引數的指標一致,則引數之間可以進行引數傳遞。

--------------------------------------------------------------------

PS:真正在傳遞二維指標的時候,還需要考慮到二維陣列的維度。

比如:int a[10];    正確的函式引數形式應該為void print(int* a, int n);

二維指標也是同理。三維指標也是。如果掌握以上知識,做到正確傳引數,應該不是問題。