1

当您必须设置静态数组的元素时,我对将什么作为第一个参数传递给 memset 感到有些困惑。我一直在寻找,但我找不到一些特定问题的答案。

如果我有一个声明为的数组:

char arr[10];

我已经看到这两个调用是有效的并且产生相同的效果:

memset( arr, 0, 10);
memset( &arr, 0, 10);

我的具体问题是:

1-为什么它们对 arr 有相同的影响?

2-这些电话有什么不同?

3-哪一个会被认为是正确的?

谢谢!

4

3 回答 3

6

存储时长与它无关;数组是数组。这个表达式:

&arr

生成 a char (*)[10],即指向char具有 10 个元素的数组的指针。但是,当arr传递给这样的函数时:

memset(arr, 0, 10);

它降级为指向第一个元素的指针,即 a char*。这些不是一回事。“正确”(惯用的)调用是:

memset(arr, 0, 10);

void*但是,在这种情况下,它们在传递给函数时都转换为 amemset并在函数中解释为 a unsigned char*。由于它们都指向同一个地方,因此会产生相同的结果。

然而,重要的是要认识到,在处理真正的各自类型(即,不是 a void*时,指向数组的指针与指向数组第一个元素的指针不同。

例如,增加 achar (*)[10]将增加指针sizeof(char[10])字节,而增加 achar*将仅增加一个字节。

于 2013-03-17T20:36:44.373 回答
3

为什么它们对 arr 有相同的影响?这些调用之间有什么不同?

因为数组的地址与其第一个元素的地址相同(数组在传递给函数时衰减为指向其第一个元素的指针),只是它们具有不同的类型。arr具有 type ,当传递给函数时char[10]会衰减。char *相反,&arr具有char (*)[10]作为函数参数传递时不会改变的类型。

哪一个会被认为是正确的?

只要函数不期望特定类型,即它接受void *,任何一个都是好的。但是,如果被调用的函数期望指定其中一种类型,则不应使用另一种类型,因为这样您的程序将出现格式错误并调用未定义的行为。

于 2013-03-17T20:37:08.713 回答
1

1-为什么它们对 arr 有相同的影响?

它们都包含相同的值,即数组开头的地址。

2-这些电话有什么不同?

arr衰减为指向 char 的指针,即char*(当您将数组的名称传递给函数时会发生这种转换)并且&arr是指向char数组的指针,即char (*)[].

3-哪一个会被认为是正确的?

我会用arr. memset接受 avoid*这是两者都起作用的原因。

另外,请注意char arr[10] = {};可用于对数组进行零初始化。

于 2013-03-17T20:35:49.127 回答