Rob*_*cco 2 c arrays function c99 memset
我试图弄清楚为什么当我从函数内部调用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;
}
Run Code Online (Sandbox Code Playgroud)
/* 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");
}
}
Run Code Online (Sandbox Code Playgroud)
在第二个代码中(带有函数),我应该把这一行放在:memset(magic_square,0,n * sizeof(magic_square [0])); 对于要清除的二维数组,使用:memset(magic_square,0,sizeof(magic_square)); 不起作用。为什么会这样呢?
当您将数组传递给C语言中的函数时,即使您在函数原型 (a)中指定了数组类型,它们也会衰减为指向数组中第一个元素的指针。因此,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));
Run Code Online (Sandbox Code Playgroud)
但是,您已经向当前函数传递了足够的信息来执行此操作,特别是n。您应该能够使用它来为sizeof运算符形成一个类型(可以使用变量或类型),它将满足您的需要:
memset(magic_square, 0, sizeof(int[n][n]));
Run Code Online (Sandbox Code Playgroud)
(a)在C11以下部分的最新标准中涵盖6.3.2.1 Lvalues, arrays, and function designators /3:
除非它是运算
sizeof符,_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则类型为“ array of type”的表达式将转换为类型为“ pointer to type”的表达式”,它指向数组对象的初始元素,而不是左值。
尽管有您的标签,我仍引用了该标准的最新版本c99,唯一的区别是C99标准没有提及,Alignof因为该版本中不存在该标准。除此之外,报价是相同的。
这又方式回来,甚至K&R第一版5.3 Pointers and arrays:
实际上,编译器将对数组的引用转换为指向数组开头的指针。