如何初始化(或分配)具有特定默认值的结构(抽象数据类型)成员的值

Posted

技术标签:

【中文标题】如何初始化(或分配)具有特定默认值的结构(抽象数据类型)成员的值【英文标题】:How to initialized (or assigned) a value of an member of a structure (abstract data type) with particular default 【发布时间】:2021-12-26 17:56:26 【问题描述】:

这是我尝试制作的结构:

struct 
    char *name;
    int age;
    bool married;
 person;

如何使用 False 值初始化已婚,以便每个声明的人首先不是已婚,直到它被分配为其他人?

【问题讨论】:

在 C 中没有办法为结构成员定义默认值。您需要在变量初始化期间执行此操作。如果你有一个函数可以动态生成struct people 类型的新元素,这个函数应该注意这一点。 如果它是一个抽象数据类型(即可以在不知道其具体实现的情况下使用的数据类型),那么应该有一个专用函数来创建该数据类型的有意义/适当初始化的变量(因为否则会出现像这样的问题并破坏抽象数据类型的概念)。使用该功能。您可能是那个/那些函数的维护者或未来的创建者,在这种情况下填充它或相应地修改它。 跑题了,但people是复数,这显然是一个人(在很多方面,因为married == false),所以重命名为struct person 【参考方案1】:

C中动态分配的内存没有默认值,也没有内置构造函数的概念,所以需要自己实现设置默认值。您可以创建一个执行分配和初始化的“构造函数”函数,例如,

struct person *new_person(const char *name, int age) 
    struct person *p = malloc(sizeof(*p));
    if (p) 
        p->name = strdup(name); // (subject to availability of `strdup`)
        p->age = age;
        p->married = false;
    
    return p;

当然,在这种特殊情况下,默认值为零,因此您也可以将内存归零,但使用构造函数方法,您可以添加其他错误检查等。

【讨论】:

【参考方案2】:

写一个函数为例

void default_init( struct people *person )

    person->name = NULL;
    person->age = 0;
    person->married = false;

并且在声明结构类型的对象之后

struct people person;

调用函数

default_init( &person );

例如

struct people *person = malloc( sizeof( *person ) );
default_init( person );

当然,您可以在声明时初始化结构类型的对象,例如

struct people person =  .name = NULL, .age = 0, .married = false ;

【讨论】:

【参考方案3】:

如果您使用 calloc 动态分配内存,则字段 married 将为 false。

我还会在结构中使用一个灵活的数组成员,以允许单次分配、重新分配和释放数据。成员age 不能为负,所以更合适的类型是unsigned int

struct person
    unsigned age;
    bool married;
    char name[];
;

struct person *newPerson(const char *name, unsigned age)

    struct person *pr = calloc(1, sizeof(*pr) + strlen(name) + 1);
    if(pr)
    
        strcpy(pr -> name, name);
        pr -> age = age;
    
    return pr;

【讨论】:

【参考方案4】:

static 对象的自动默认值在 C 中是不可能的。

回想一下,C 中没有部分初始化:全有或全无。

替代方案:

只使用依赖零初始化的static objects

person p1; // All members filled with zero bits.

int foo() 
  static person p2;  // All members filled with zero bits.
  person p3; // No initialization.

0

int foo() 
  person p4 =  0 ; // First member 0, other members are 0.

.married = false

int foo() 
  person p5 =  .married = false ; // .married member false, other members are 0
  person p6 =  .married = 0 ; // .married member false, other members are 0

使用另一个对象

const person p_init1 =  .married = false ; // .married member false, other members are 0

int foo() 
  person p7 = p_init1

compound literal

int foo() 
  person p8 = (person) .married = false ;

分配

compound literal

int foo() 
  person p9;
  ...  
  p9 = (person) .married = false ; // All members copied

【讨论】:

以上是关于如何初始化(或分配)具有特定默认值的结构(抽象数据类型)成员的值的主要内容,如果未能解决你的问题,请参考以下文章

如何找到特定成员具有特定值的第一个结构?

如何仅在 recyclerview 中显示具有特定值的数据

获取从抽象类继承并在属性中具有特定值的类的实例

如何使用 jquery 或 javascript 计算具有特定值的行数?

如何在执行C ++期间动态查看堆

如何在 Go 中将 JSON 对象数组转换为具有默认值的结构数组?