C约定-如何在结构的数组字段上使用memset

C约定-如何在结构的数组字段上使用memset,c,coding-style,conventions,C,Coding Style,Conventions,我想解决一个关于在结构(语言是C)中将数组字段归零时正确使用memset的问题 假设我们有以下结构: struct my_struct { int a[10] } 以下哪种实现更正确 备选案文1: void f (struct my_struct * ptr) { memset(&ptr->a, 0, sizeof(p->a)); } 备选案文2: void f (struct my_struct * ptr) { me

我想解决一个关于在结构(语言是C)中将数组字段归零时正确使用memset的问题

假设我们有以下结构:

  struct my_struct {
        int a[10]
    }
以下哪种实现更正确

备选案文1:

void f (struct my_struct * ptr) {
    memset(&ptr->a, 0, sizeof(p->a));
}
备选案文2:

void f (struct my_struct * ptr) {
        memset(ptr->a, 0, sizeof(p->a));
}
注:

如果字段是基元类型或另一个结构(如“int”),选项2将不起作用,如果是指针(int*),选项1将不起作用


请告知,

对于非复合类型,您根本不会使用
memset
,因为直接赋值更容易,而且可能更快。它还允许对函数调用不允许的编译器进行优化

对于数组,变量2起作用,因为数组隐式转换为大多数操作的指针

对于指针,请注意,在变量2中使用指针的值,而不是指针本身,而对于数组,则使用指向数组的指针

变量1生成对象本身的地址。对于指针来说,这是指针的类型(如果这“有效”取决于您的意图),对于数组来说,这是数组的类型-碰巧总是它的第一个元素的地址-但是这里的类型不同(不相关,因为
memset
采用
void*
并在内部转换为
char*

所以:这要视情况而定;对于一个数组,我实际上看不到太大的区别,除了address操作符可能会将不太熟悉的读取与操作符precedence混淆(而且更容易键入)。作为个人观点:我更喜欢简单的语法,但不会抱怨其他语法


请注意,
memset
使用除
0
以外的任何其他值实际上没有多大意义;它甚至可能无法保证指针数组被解释为空指针。

IMO,选项1更可取,因为相同的模式适用于任何对象,而不仅仅是数组:

memset(&obj, 0, sizeof obj);
您可以从这条语句中看出,它不会导致缓冲区溢出,也就是说,不会访问越界。这仍然可能不符合预期(例如,如果
obj
是一个指针,并且它旨在设置指针指向的对象),但至少可以控制损坏


但是,如果您意外地在指针上使用
memset(p,0,sizeof p)
,那么您可能会写入指向的对象的末尾;或者,如果对象大于p的大小,则会使对象处于奇怪的状态。

使用正确的符号表示要归零的元素类型。您已经确定了所需的两个符号;没有一种符号适用于所有情况。对于数组,不使用
;如果
a
是指针,那么这两个选项都不起作用,它们都会默默地给出错误的行为。