【C语言】结构体初始化方式总结

【C语言】结构体初始化方式总结

本文详解C语言的结构体初始化的7大类型,基础永远直接花85%时间去好好学习,小而汇多,建议收藏!

总的来说,如下:

类型①老祖宗:最传统的使用②简化 1:变量名紧贴类型后③简化 2:集中初始化④简化 3:结构体中直接初始化⑤简化 4:使用 typedef 脱离 struct⑥简化 5:匿名结构体⑦结构体数组初始化

下面详细讲解之:

1.最传统的使用

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

};

struct person_ person;

这里struct person_写在一起,作为一个类型名(person_也称为类型标签),去声明变量,如struct person_ person;声明了一个struct person_类型的变量person

(就类似于int a)。

2.简化1——变量名紧贴类型后

上面的声明语句struct person_ person;是不是有点麻烦?可以简写!即在结构体类型名后面直接声明变量即可!

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person;

如上,这里的写法和①中是完全等价的,但是简洁了不少!

同时,变量名可以声明多个、多种类型!如下:

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person, person1[40], *person2;

这里声明了结构体、结构体指针、结构体数组!

3.简化2——集中初始化

平时我们初始结构体的方式常常如下:

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person;

person.age = 12;

sprintf(person.name, "%s", "Alice");

sprintf(person.hobby[0], "eating");

sprintf(person.hobby[1], "running");

显然这里的成员初始化使用了3个语句,略显繁杂,有没有简便的方式?比如化为一条语句?还真有!

在C99中,允许这样初始化结构体:

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

};

struct person_ person1={.age=12,.name="Alice",.hobby={"eating","running"}};

注意这里的精髓,使用.成员运算符来完成的,将多条语句化为一条了,很简洁,当然,你也可以省略.age等成员,直接像下面这样:

person = {12, "Alice", {"eating", "running"}};

但是不太明显,并且必须把每一个按照顺序来完成,个人推荐使用上面的显式的写法!

4.简化2——结构体中直接初始化

上面的各种都只是声明,不是初始化,这意味着在后面还要单独初始化,略显麻烦。

可不可以直接初始化呢?当然可以!

类似于int a;a=5;显然这很麻烦!这里这里讲解的就是int a=5;在结构体中的应用。

如下,这就是直接初始化的样式,注意一定使用=。

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person =

{

"EthanYankang",

100,

{"run", "cycle", "code"},//注意这里指针指向的.rodata中的数据,所以并不是野指针!

},

person1, *person2,

person3 = {

.age = 23,

.name = "Alice",

.hobby = {"writting", "take photos"}

};

本例应该是比较综合的了!

5.简化3——使用typedef脱离struct

注意到,上面的结构体类型必须使用struct person这两个(一个关键词、一个标签)的组合来完成变量的声明,写两个单词毕竟很繁琐,可不可以像int一样,变为一个单词的类型方便使用呢?当然可以——使用typedef等同即可。

如下,将P_person等同于struct person_,后面就可以使用P_person来声明变量了,例如P_person person。

typedef struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} P_person;

P_person person;

当然,我们也可以等价struct person_*为P_person,这种形式如下:

(事实上这也是我们使用频次最多的形式)

typedef struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} *P_person;

P_person person;

可以看到,仅仅是在P_person前面加上一个*即可!注意不是在struct person_后面加!

6.简化4——匿名结构体

显然,上面的所有声明、初始化都新增了一种类型struct person_(或者P_person),我们可不可以不新增类型完成结构体的声明、初始化呢?当然可以——使用匿名结构体。

如下,结构体phone1、2会在它的生命周期结束后终止!

struct

{

int price;

char *name;

} phone1 = {

8000,

"HUAWEI",

},phone2={

.price=3000,

.name="XIAOMI"

};

注意这种形式中,没有类型名,只有变量名!

这种形式常常用于只使用该结构体一次的情况!因为不需要复用,也就不必要新增类型!

7.结构体数组初始化

结构体数组的初始化只不过在增加一层维度罢了!其余的和上面的完全一致,只不过这里使用了数组罢了!这里仅不在赘述!

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person4[3]={

{.age=1,.name="A",.hobby={"h1","h2"}},

{.age=2,.name="B",.hobby={"h3","h4"}},

{.age=3,.name="C",.hobby={"h5","h6"}}};

完整源码

#include

#include

#include

#if 0

/**写法1

* data descp:传统的结构体写法

*/

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

};

struct person_ person1;

#endif

/*

其中,person_是结构体标签,要求和struct一起用,表明这是一个结构体类型,例如声明一个变量:struct person_ p

后面的person是一个结构体实例,这是一种简便写法。

*/

#if 0

/**写法2

* data descp: 简洁写法1-变量紧贴类型后

*/

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person2; /*这是一个变量,类型是struct person_

*/

/*可以看到,这样写,就省略了在单独来一次struct person_ person,方便了一些*/

#endif

#if 0

/**写法3

* data descp: 简洁写法2-变量紧贴类型后,并初始化

*/

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person3 =

{

"EthanYankang",

100,

{"run", "cycle", "code", NULL},

};

#endif

/*当然了,你也可以混着写,如下*/

struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} person4 =

{

"EthanYankang",

100,

{"run", "cycle", "code"},

},

person5, *person6,

person7 = {

.age = 23,

.name = "Alice",

.hobby = {"writting", "take photos"}},

person8[3] = {{.age = 1, .name = "A", .hobby = {"h1", "h2"}}, {.age = 2, .name = "B", .hobby = {"h3", "h4"}}, {.age = 3, .name = "C", .hobby = {"h5", "h6"}}};

#if 0

/**写法4

* data descp: 写法3——简化类型名

*/

/*注意到,我们前面要声明一个结构体,都必须使用struct person_这样的写法,是不是有时候太麻烦了?能不能像int a一样,仅仅使用一个标签就声明了呢?当然可以。*/

/*注意到,这里使用struct person_是因为struct是一个变类型大小的数据类型,不同的结构体有不同的大小,所以为了区分是哪一个结构体,必须在后面紧跟一个标签,例如struct person_表明,这是人结构体,大小为20B。int a可以成功的声明的原因是所有int都是4字节大小的,没有歧义。*/

/*我们通过typedef定义类型,将struct person_打包带走。声明P_person person就等同于struct person_,怎么样,是不是方便了很多!*/

// /*另外,还可以使用指针的方式,更加灵活,如下.事实上,这也是我们最多的时候使用的!*/

// typedef struct person_

// {

// char name[20];

// int age;

// char *hobby[20]; /*这是一个数组,而非指针*/

// } *P_person;

// P_person person;

typedef struct person_

{

char name[20];

int age;

char *hobby[20]; /*这是一个数组,而非指针*/

} P_person;

P_person person9;

#endif

void print(struct person_ person)

{

printf("size:%d\n", sizeof(person));

printf("name:%s\n", person.name);

printf("age:%d\n", person.age);

for (int i = 0; person.hobby[i] && i < 20; i++)

{

printf("%s\n", person.hobby[i]);

}

printf("\n");

}

int main()

{

#if 0

{

person1.age = 100;

sprintf(person1.name, "%s", "EthanYankang");

for (int i = 0; i < 20; i++)

{

/*为每一个指针分配100个字节,完全足够了*/

person1.hobby[i] = (char *)malloc(sizeof(char) * 100);

sprintf(person1.hobby[i], "%s%d", "hobby-", i);

}

// person1.hobby=

/**

* data descp: 这里一定要为person2分配内存,因为指针没有指向的内容,是野指针。!

* (那为什么char*arr="NULL"可以呢?因为这是指向的rodate段里面的数据地址("NULL"编译器会为字面量默认分配内存)!)

*/

}

#endif

#if 1

person6 = (struct person_ *)malloc(sizeof(struct person_));

person6->age = 20;

sprintf(person6->name, "%s", "NIUMA");

// person6->hobby = {"A", "B", "C"}; /*数组除了初始化之外,不可以直接赋值!只能采用元素遍历的方式!这个你又别忘记了!*/

person6->hobby[0] = "xidian";

person6->hobby[1] = "985";

// person6->name = strdup("NIUMA");//为什么这里使用strdup不行?因为strdup是在堆上分配内存的,针对数组,但是这里的name是字符数组,不能通过strdup来分配内存!也不能通过直接=赋值,只能通过覆写的方式来完成。

#endif

// print(person1);

print(*person6);

struct

{

int price;

char *name;

} phone = {

8000,

"HUAWEI",

},

p = {.price = 3000, .name = "XIAOMI"};

printf("price:%d,name:%s\n", phone.price, phone.name);

printf("price:%d,name:%s\n", p.price, p.name);

struct person_ person;

person.age = 12;

sprintf(person.name, "%s", "Alice");

person.hobby[0] = "eating";

person.hobby[1] = "running";

struct person_ person1 = {.age = 12, .name = "Alice", .hobby = {"eating", "running"}};

print(person);

print(person1);

}

结尾

好了这就是结构体常见的7种类型的初始化方式,让我们再来回顾回顾:

结构体初始化回顾1.结构体初始化方式从传统的老祖宗,历经了5大简化,分别是哪五大简化?2.给出简化1-变量名紧贴类型后的代码形式3.给出简化2-集中初始化方式的代码形式4.给出简化3-结构体中直接初始化的代码形式5.给出简化4-使用typedef脱离struct的代码形式6.给出简化5-匿名结构体的代码形式如果您不能对着这个表格给出每一项的讲解,那么,再把上面的内容好好复习一遍吧!

答案见评论区,欢迎大家讨论~

关于小希

😉嘿嘿嘿,我是小希,专注C语言、Linux内核和云计算领域。

下面是我的微信,期待与您学习交流!

(加微信请备注哦)~

小希的座右铭:别看简单,简单也是难。别看难,难也是简单。我的文章都是讲述简单的知识,如果你喜欢这种风格:

不妨关注、评论、转发,让更多朋友看到哦~~~🙈

下一期想看什么?在评论区留言吧!我们下期见!

相关推荐

PSP机器人大战系列合集_PSP机战大全
约彩365苹果在线安装

PSP机器人大战系列合集_PSP机战大全

⌛ 2025-07-01 👁️ 6833
如何取消信用卡?一文看清各大銀行 Cut 卡方法+罰則
家庭版microsoft365

如何取消信用卡?一文看清各大銀行 Cut 卡方法+罰則

⌛ 2025-07-07 👁️ 9546
十八年,秦武王与孟说举龙文赤鼎,绝膑而死 原文全文及出处