[英]Why does memset work differently in functions?
我試圖弄清楚為什么當我從 function 內部調用 memset 時它不起作用。 當然,我可以使用 for 循環來重置所有值,但我是來學習的,這件事讓我沒有任何解釋。
/* First source code */
#include <stdio.h>
#include <string.h>
int main(void) {
int i, j, num;
printf("Digit a number :");
scanf("%d", &num);
int magic[num][num];
printf("First\n");
for(i = 0; i < num; ++i) {
for(j = 0; j < num; ++j) {
printf("%4d", magic[i][j]);
}
printf("\n\n");
}
memset(magic, 0, sizeof(magic));
printf("Before\n");
for(i = 0; i < num; ++i) {
for(j = 0; j < num; ++j) {
printf("%4d", magic[i][j]);
}
printf("\n\n");
}
return 0;
}
/* Second source code */
#include <stdio.h>
#include <string.h>
void create_magic_square(int n, int magic_square[][n]);
void print_magic_square(int n, int magic_square[][n]);
int main(void) {
int num;
printf("Digit a number :");
scanf("%d", &num);
int magic[num][num];
create_magic_square(num, magic);
return 0;
}
void create_magic_square(int n, int magic_square[][n]) {
int i, j;
printf("First\n");
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j) {
printf("%4d", magic_square[i][j]);
}
printf("\n\n");
}
//memset(magic_square, 0, n * sizeof(magic_square[0]));
memset(magic_square, 0, sizeof(magic_square));
printf("Before\n");
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j) {
printf("%4d", magic_square[i][j]);
}
printf("\n\n");
}
}
在第二個代碼(帶有函數)中,我應該輸入以下行: memset (magic_square, 0, n * sizeof (magic_square [0])); 對於要清除的二維數組,同時使用: memset (magic_square, 0, sizeof (magic_square)); 不起作用。 為什么會這樣?
當您將 arrays 傳遞給 C 中的函數時,即使您在 function 原型中指定了數組類型,它們也會衰減為指向數組中第一個元素的指針。 因此sizeof
將為您提供指針的大小,而不是數組的大小。
常見的做法是將數組大小與數組一起傳遞(可能作為size_t
)並使用它來編織你的魔法,例如:
int zeroArray(void *address, size_t sz) { // void* makes it clear
memset(address, 0, sz); // but int thing[][] would be same.
}
:
int xyzzy[42][7];
zeroArray(xyzzy, sizeof(xyzzy));
但是,您已經向當前的 function 傳遞了足夠的信息來執行此操作,特別是n
。 您應該能夠使用它來形成sizeof
運算符的類型(可以采用變量或類型),它將滿足您的需要:
memset(magic_square, 0, sizeof(int[n][n]));
(a)涵蓋在最新標准C11
的6.3.2.1 Lvalues, arrays, and function designators /3
部分下:
除非它是
sizeof
運算符、_Alignof
運算符或一元&
運算符的操作數,或者是用於初始化數組的字符串文字,否則類型為 "array of type" 的表達式將轉換為類型為 "指向類型的指針”指向數組 object 的初始元素,並且不是左值。
盡管您有c99
標簽,但我還是引用了該標准的最新迭代,唯一的區別是 C99 標准沒有提到Alignof
,因為它在該迭代中不存在。 除此之外,報價是相同的。
這可以追溯到 K&R 第一版、 5.3 Pointers and arrays
:
實際上,對數組的引用被編譯器轉換為指向數組開頭的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.