询问memset参数及数组表达式等价性:&na.array与na.array、na.array与&na.array[0]
首先先把你给出的代码片段格式化出来:
#include <string.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv){ struct name{ char array[8]; }; struct name na; memset(&na.array,0,8); }
接下来咱们逐个解答你的两个技术问题:
问题1:调用memset(&na.array, 0, 8)与调用memset(na.array, 0, 8)是否等价?
答案是:在这个场景下,两者的实际效果完全等价。
这里拆解一下背后的逻辑:
na.array是char类型数组,当你把它作为函数参数传递时,C语言会自动把它转换成指向数组第一个元素的指针,也就是&na.array[0],类型为char*。&na.array是指向整个数组的指针,类型是char (*)[8](可以理解为“指向长度为8的char数组的指针”)。但memset的第一个参数是void*类型,这个指针会被隐式转换为void*。
从内存地址来看,na.array转换后的指针和&na.array指向的是同一块内存的起始位置——也就是数组第一个元素的地址。再加上你要设置的字节数是8,刚好覆盖整个数组的大小,所以这两个调用最终都会把na.array的8个字节全部置为0,运行结果没有任何区别。
不过要注意:虽然效果一样,但它们的原始指针类型是不同的,只是因为memset接受void*,所以类型转换不会引发问题。
问题2:表达式na.array与&na.array[0]是否等价?
答案是:在绝大多数常用场景下,两者完全等价。
根据C语言的标准规则,当数组名出现在表达式中时(除了几种特殊情况),它会被自动转换为指向数组第一个元素的指针。na.array[0]是数组的第一个元素,&na.array[0]就是取这个元素的地址,而na.array转换后也是指向第一个元素的指针,所以它们的地址值完全相同,类型也都是char*。
那什么是特殊情况呢?比如:
- 当数组名作为
sizeof的操作数时:sizeof(na.array)得到的是整个数组的大小(8字节),而sizeof(&na.array[0])得到的是指针的大小(取决于平台,比如32位系统是4字节,64位是8字节)。 - 当数组名作为
&的操作数时:&na.array得到的是指向整个数组的指针,和&na.array[0]的类型不同。
但在普通的使用场景里——比如把数组名赋值给指针变量、作为函数参数传递、用来访问数组元素的时候,na.array和&na.array[0]的表现完全一致。
内容的提问来源于stack exchange,提问作者jhonnna
相关产品推荐
相关产品推荐

