- 先看下例子
#include <stdio.h>
#include <string.h>
void f(int *a)
{
memset(a,0,sizeof(a));
}
int main(void)
{
int arr[5]={1,2,3,4,5};
f(arr);
for(int i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
- 輸出:
0 2 3 4 5
上面的輸出竟然是 0 2 3 4 5,也就是只清空了第一個元素,這顯然不是想要的結果。
為什么呢??
- 引用別人的話來解釋一下
靜態數組作為參數傳入某個函數的時候,就會退化成指針,也就是該數組的首地址,其數組的長度信息就丟掉了,這就是在這個語境下退化的概念。
這也是為什么在將數組作為參數傳遞時,同時要將數組的長度也一并傳入的原因。
-
所以將數組當作參數傳遞的時候,不要用memset,memset應該和數組在同一塊代碼區。
- 上面例子這樣改之后就可以正確輸出:
#include <stdio.h>
#include <string.h>
void f(int *a,int len)
{
memset(a,0,sizeof(int)*len);
}
int main(void)
{
int i;
int arr[5]={1,2,3,4,5};
f(arr,5);
for(i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
- 輸出:
0 0 0 0 0
這樣就正確了。
用memset將 int 類型的數組置為 0 或者 -1 是可以的,但置為1或者其他數是不行的;將char數組置為任何數都是可以的。
原因:
- memset是按字節賦值,char是1字節,int是4個字節,所以char是可以的,int是不行的。(可以輸出sizeof(char), sizeof(int)查看)
- memset第一個參數是開始填充的地址,第二個參數是填充的byte,第三個參數要填充的字節數。
比如置為1,那么賦值的結果應該是二進制數00000001000000010000000100000001,為16843009- 通俗的講,就是將1變為00000001,然后從數組頭開始,每8位填充一個00000001,直到填充的次數等于第三個參數。最后如果是int,那就按int的位數取出來,得到16843009。