当你必须设置静态数组的元素时,我对作为memset的第一个参数传递的内容感到有点困惑。我一直在寻找,但我找不到一些具体问题的答案。
如果我有一个声明为:
的数组char arr[10];
我已经看到这两个调用有效并产生相同的效果:
memset( arr, 0, 10);
memset( &arr, 0, 10);
我的具体问题是:
1-为什么它们对arr有相同的效果?
2-这些电话有什么不同?
3-哪一个被认为是正确的?
谢谢!
答案 0 :(得分:4)
存储时间与它无关;数组是一个数组。这个表达式:
&arr
产生char (*)[10]
,即指向具有10个元素的char
数组的指针。但是,当arr
传递给类似的函数时:
memset(arr, 0, 10);
它降级为指向第一个元素的指针,即char*
。这些都不是一回事。 "正确" (惯用)电话是:
memset(arr, 0, 10);
但是,在这种情况下,它们在传递给void*
时都会转换为memset
,并在函数中解释为unsigned char*
。因为它们都指向同一个地方,所以它产生相同的结果。
然而,重要的是要意识到,当处理真正的相应类型(即,不是void*
)时,指向数组的指针不与指针相同到数组的第一个元素。
例如,递增char (*)[10]
将增加指针sizeof(char[10])
个字节,而递增char*
将只增加一个字节。
答案 1 :(得分:2)
为什么它们对arr有相同的效果?这些电话有什么不同?
因为数组的地址与第一个元素的地址相同(数组在传递给函数时会衰减成指向第一个元素的指针),只是它们有不同的类型。 arr
的类型为char[10]
,在传递给函数时会衰减到char *
。相反,&arr
具有类型char (*)[10]
,当作为函数参数传递时,它不会更改。
哪一个被认为是正确的?
只要该功能不期望特定类型,i。即它接受void *
,其中一个是好的。但是,如果被调用函数需要指定其中任何一种类型,那么不应该使用另一种类型,因为那样你的程序就会格式错误并调用未定义的行为。
答案 2 :(得分:0)
1-为什么它们对arr有相同的效果?
它们都包含相同的值,即数组开头的地址。
2-这些电话有什么不同?
arr
衰减到指向char的指针,即char*
(当您将数组的名称传递给函数时会发生此转换)并且&arr
是指向数组的char,即char (*)[]
。
3-哪一个被认为是正确的?
我会使用arr
。 memset
接受void*
,这是两者都有效的原因。
另请注意,char arr[10] = {};
可用于初始化数组。