陣列作形參時的注意點

2021-09-10 22:54:05 字數 1524 閱讀 8490

1、對於一維陣列來說,陣列作為函式引數傳遞,實際上傳遞了乙個指向陣列的指標,在c編譯器中,當陣列名作為函式引數時,在函式體內陣列名自動退化為指標。此時呼叫函式時,相當於傳址,而不是傳值,會改變陣列元素的值。

例如:void fun(int a);    若在fun函式中有a[i]++;等語句,那麼對應的陣列元素會被修改,呼叫時直接用fun(a);即可。

2、對於高維陣列來說,可以用二維陣列名作為實參或者形參,在被呼叫函式中對形引數組定義時可以指定所有維數的大小,也可以省略第一維的大**明,如: 

void fun(int array[3][10]); 

void fun(int array[10]); 

二者都是合法而且等價,但是不能把第二維或者更高維的大小省略,如下面的定義是不合法的: 

void fun(int array); 

因為從實參傳遞來的是陣列的起始位址,在記憶體中按陣列排列規則存放(按行存放),而並不區分行和列,如果在形參中不說明列數,則系統無法決定應為多少行多少列,不能只指定一維而不指定第二維,下面寫法是錯誤的: 

void fun(int array[3]);

實參陣列維數可以大於形引數組,例如形引數組定義為: 

void fun(int array[3][10]); 

而實參陣列定義為: 

int array[5][10]; 

這時形引數組只取實參陣列的一部分,其餘部分不起作用。 

可以看到,將二維陣列當作引數的時候,必須指明所有維數大小或者省略第一維的,但是不能省略第二維或者更高維的大小,這是由編譯器原理限制的。學編譯原理的時候應該 知道編譯器是這樣處理陣列的:

對於陣列 int p[m][n]; 

從以上可以看出,如果我們省略了第二維或者更高維的大小,編譯器將不知道如何正確的定址,即這裡的n值是在形參定義的時候就要明確知道的。但是我們在編寫程式的時候卻需要用到各個維數都不固定的二維陣列 作為引數,這就難辦了,編譯器不能識別阿,怎麼辦呢?不要著急,編譯器雖然不能識別,但是我們完全可以不把它當作乙個二維陣列,而是把它當作乙個普通的指標,再另外加上兩個引數指明各個維數,然後我們為二維陣列手工定址,這樣就達到了將二維陣列作為函式的引數傳遞的目的,根據這個思想,我們可以把維數固定 的引數變為維數隨即的引數,例如: 

void fun(int array[3][10]); 

void fun(int array[10]); 

變為: 

void fun(int **array, int m, int n); 

在轉變後的函式中,array[i][j]這樣的式子是不對的(不信,大家可以試一下),因為編譯器不能正確的為它定址,所以我們需要模仿編譯器的行為把array[i][j]這樣的式子手工轉變為:

*(*array + n*i + j); 

在呼叫這樣的函式的時候,需要注意一下,如下面的例子: 

int a[3][3] = , , }; 

fun(a, 3, 3);

根據不同編譯器不同的設定,可能出現warning 或者error,可以進行強制轉換如下呼叫:

fun((int**)a, 3, 3);

陣列作為函式形參時應注意的問題

在利用google c testing framework gtest編寫test case 時,引起了乙個 奇怪的 問題 1 intdigitarray 2int size sizeof digitarray sizeof digitarray 0 將以上 包含在測試函式test 中時,size求...

C C 指標作為函式形參注意點

函式形參是指標變數,直接對其賦值 指標相互賦值 只是改變了它的指向,原先傳入的指標指向的內容並沒改變 若要想改動其指向的值,需要通過memcpy或通過指標呼叫賦值 include include include include include include include using namesp...

C 中二維陣列作函式形參

文章 在做資料結構迷宮實驗的時候,要生成乙個二維陣列儲存迷宮資料,為了保證程式的模組化,將生成部分單獨放進乙個函式migongsc 裡。大致 如下 問題的關鍵就集中在了如何將主函式中宣告的二維陣列migong 8 9 傳遞到自定義函式中去。方法1 模擬編譯器定址 本法來自csdn部落格,原文 大體意...