静态数组上的Memset

memset on static array

本文关键字:Memset 数组 静态      更新时间:2023-10-16

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

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

char arr[10];
我已经看到这两个调用是有效的并且产生相同的效果:
memset( arr, 0, 10);
memset( &arr, 0, 10);

我的具体问题是:

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

2-这些调用之间有什么不同?

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

谢谢!

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

&arr

生成一个char (*)[10],即指向包含10个元素的char数组的指针。但是,当将arr传递给如下函数时:

memset(arr, 0, 10);

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

memset(arr, 0, 10);

然而,在这种情况下,当传递给memset时,它们都被转换为void*,并在函数中解释为unsigned char*。因为它们都指向同一个地方,所以会产生相同的结果。

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

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

为什么它们对arr有相同的影响?这些呼叫有什么不同?

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

哪一个被认为是正确的?

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

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

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

2-这些调用之间有什么不同?

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

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

我将使用arrmemset接受void*,这是两者都工作的原因。

还要注意的是,char arr[10] = {};可以用来对数组进行零初始化。