1、盡量顯式地指定數組的邊界
#define MAX 10
…
int a[MAX]={1,2,3,4,5,6,7,8,9,10};
在 C99 標准中,還允許我們使用單個指示符為數組的兩段“分配”空間,如下面的代碼所示:
int a[MAX]={1,2,3,4,5,[MAX-5]=6,7,8,9,10};
在上面的 a[MAX] 數組中,如果 MAX 大於 10,數組中間將用 0 值元素進行填充(填充的個數為 MAX-10,並從 a[5] 開始進行 0 值填充);如果 MAX 小於 10,“[MAX-5]”之前的 5 個元素(1,2,3,4,5)中將有幾個被“[MAX-5]”之后的 5 個元素(6,7,8,9,10)所覆蓋。
2、對數組做越界檢查,確保索引值位於合法的范圍之內
傳遞數組參數的時候,一定要帶上傳入數組的長度,比如:
void Init(int arr[],size_t arr_len)
{
size_t i=0;
for(i=0;i<arr_len;i++)
{
arr[i]=i;
}
}
arr_len類型一定要無符號,避免負數的副作用。
3、獲取數組的長度時不要對指針應用 sizeof 操作符。
單地講,sizeof 是一個單目操作符,不是函數。其作用就是返回一個操作數所占的內存字節數
下面的函數中,使用sizeof,以為是對的,其實,arr傳進來的時候,已經退化為指針,所以等同於
void Init(int *arr)。
void Init(int arr[])
{
size_t i=0;
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
arr[i]=i;
}
}
4、除此之外,我們還可以通過指針的方式來解決上面的問題,示例代碼如下所示:
void Init(int (*arr)[10])
{
size_t i=0;
for(i=0;i< sizeof(*arr)/sizeof(int);i++)
{
(*arr)[i]=i;
}
}
int main(void)
{
int i=0;
int a[10];
Init(&a);
for(i=0;i<10;i++)
{
printf("%d\n",a[i]);
}
return 0;
}
現在,Init() 函數中的 arr 參數是一個指向“arr[10]”類型的指針。
需要特別注意的是,這里絕對不能夠使用“void Init(int(*arr)[])”來聲明函數,編譯器會報錯:error: sizeof applied to an incomplete type
而是必須指明要傳入的數組的大小,否則“sizeof(*arr)”無法計算。但是在這種情況下,再通過 sizeof 來計算數組大小已經沒有意義了,因為此時數組大小已經指定為 10 了。