[软件资料] 结构体的声明与定义

[复制链接]
 楼主| OKAKAKO 发表于 2024-4-7 12:31 | 显示全部楼层 |阅读模式

1、声明

结构体的声明使用struct关键字,如果我们想要把我们的学籍信息组织一下的话,可以这样表示:

  1. struct Info
  2. {
  3.     unsigned long identifier;//学号,用无符号长整数表示
  4.     char name[20];//名字,用字符数组表示
  5.     unsigned int year;//入学年份,用无符号整数表示
  6.     unsigned int years;//学制,用无符号整数表示
  7. }

这样,我们就相当于描绘好了一个框架,以后要用的话直接定义一个这种类型的变量就好了。

2、定义
我们刚刚申请了一个名叫Info的结构体类型,那么理论上我们可以像声明其他变量的操作一样,去声明我们的结构体操作,但是C语言中规定,声明结构体变量的时候,struct关键字是不可少的。

  1. struct 结构体类型名 结构体变量名


不过,你可以在某个函数里面定义:

  1. #include <stdio.h>

  2. struct Info
  3. {
  4.     unsigned long identifier;//学号,用无符号长整数表示
  5.     char name[20];//名字,用字符数组表示
  6.     unsigned int year;//入学年份,用无符号整数表示
  7.     unsigned int years;//学制,用无符号整数表示
  8. };

  9. int main(void)
  10. {
  11.     /**
  12.      *在main函数中声明结构体变量
  13.      *结构体变量名叫info
  14.      *struct关键字不能丢
  15.      */
  16.     struct Info info;
  17.     ...
  18. }


也可以在声明的时候就把变量名定义下来(此时这个变量是全局变量):


  1. #include <stdio.h>

  2. struct Info
  3. {
  4.     unsigned long identifier;//学号,用无符号长整数表示
  5.     char name[20];//名字,用字符数组表示
  6.     unsigned int year;//入学年份,用无符号整数表示
  7.     unsigned int years;//学制,用无符号整数表示
  8. } info;
  9. /**
  10. *此时直接定义了变量
  11. *该变量是全局变量
  12. *变量名叫info
  13. */

  14. int main(void)
  15. {
  16.     ...
  17. }
 楼主| OKAKAKO 发表于 2024-4-7 12:32 | 显示全部楼层

3、访问结构体成员

结构体成员的访问有点不同于以往的任何变量,它是采用点号运算符.来访问成员的。比如,info.name就是引用info结构体的name成员,是一个字符数组,而info.year则可以查到入学年份,是个无符号整型。

比如,下面开始录入学生的信息:

  1. //Example 01
  2. #include <stdio.h>

  3. struct Info
  4. {
  5.     unsigned long identifier;//学号,用无符号长整数表示
  6.     char name[20];//名字,用字符数组表示
  7.     unsigned int year;//入学年份,用无符号整数表示
  8.     unsigned int years;//学制,用无符号整数表示
  9. };

  10. int main(void)
  11. {
  12.     struct Info info;

  13.     printf("请输入学生的学号:");
  14.     scanf("%d", &info.identifier);
  15.     printf("请输入学生的姓名:");
  16.     scanf("%s", info.name);
  17.     printf("请输入学生的入学年份:");
  18.     scanf("%d", &info.year);
  19.     printf("请输入学生的学制:");
  20.     scanf("%d", &info.years);

  21.     printf("\n数据录入完毕\n\n");

  22.     printf("学号:%d\n姓名:%s\n入学年份:%d\n学制:%d\n毕业时间:%d\n", \
  23.         info.identifier, info.name, info.year, info.years, info.year + info.years);
  24.     return 0;
  25. }

运行结果如下:

  1. //Consequence 01
  2. 请输入学生的学号:20191101
  3. 请输入学生的姓名:Harris
  4. 请输入学生的入学年份:2019
  5. 请输入学生的学制:4

  6. 数据录入完毕

  7. 学号:20191101
  8. 姓名:Harris
  9. 入学年份:2019
  10. 学制:4
  11. 毕业时间:2023

 楼主| OKAKAKO 发表于 2024-4-7 12:33 | 显示全部楼层

4、初始化结构体
像数组一样,结构体也可以在定义的时候初始化,方法也几乎一样:

  1. struct Info info = {
  2.     20191101,
  3.     "Harris",
  4.     2019,
  5.     4
  6. };

在C99标准中,还支持给指定元素赋值(就像数组一样):

  1. struct Info info = {
  2.     .name = "Harris",
  3.     .year = 2019
  4. };

对于没有被初始化的成员,则「数值型」成员初始化为0,「字符型」成员初始化为‘\0’。

对齐
下面这个代码,大家来看看会发生什么:

  1. //EXample 02 V1
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5.     struct A
  6.     {
  7.         char a;
  8.         int b;
  9.         char c;
  10.     } a = {'a', 10, 'o'};
  11.    
  12.     printf("size of a = %d\n", sizeof(a));
  13.    
  14.     return 0;
  15. }

我们之前学过,char类型的变量占1字节,int类型的变量占4字节,那么这么一算,一个结构体A型的变量应该就是6字节了。别急,我们看运行结果:

  1. //COnsequence 02 V1
  2. size of a = 12

怎么变成12了呢?标准更新了?老师教错了?都不是。我们把代码改一下:

  1. //EXample 02 V2
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5.     struct A
  6.     {
  7.         char a;
  8.         char c;
  9.         int b;
  10.     } a = {'a', 'o', 10};
  11.    
  12.     printf("size of a = %d\n", sizeof(a));
  13.    
  14.     return 0;
  15. }

结果:

  1. //Consequence 02 V2
  2. size of a = 8

实际上,这是编译器对我们程序的一种优化——内存对齐。在第一个例子中,第一个和第三个成员是char类型是1个字节,而中间的int却有4个字节,为了对齐,两个char也占用了4个字节,于是就是12个字节。

而在第二个例子里面,前两个都是char,最后一个是int,那么前两个可以一起占用4个字节(实际只用2个,第一个例子也同理,只是为了访问速度更快,而不是为了扩展),最后的int占用4字节,合起来就是8个字节。

关于如何声明结构体来节省内存容量,可以阅读下面的这篇文章,作者是艾瑞克·雷蒙,时尚最具争议性的黑客之一,被公认为开源运动的主要领导者之一:

英文原版,中文版
中国龙芯CDX 发表于 2024-4-10 11:08 | 显示全部楼层
结构体的声明与定义、初始化等操作非常重要
szt1993 发表于 2024-4-10 13:25 | 显示全部楼层
结构体的声明与定义很详细,适合新手学习
小夏天的大西瓜 发表于 2024-4-10 13:42 | 显示全部楼层
学籍信息的案例解释结构体非常清晰
jf101 发表于 2024-4-14 15:28 | 显示全部楼层
访问结构体成员这个是一般经常使用的
小小蚂蚁举千斤 发表于 2024-4-16 09:00 | 显示全部楼层
其实访问结构体大大提升了数据的完整性
 楼主| OKAKAKO 发表于 2024-4-19 18:48 | 显示全部楼层
结构体的声明使用struct关键字
星辰大海不退缩 发表于 2024-4-21 11:40 | 显示全部楼层
结构体成员的访问有点不同于以往的任何变量,它是采用点号运算符.来访问成员的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

257

主题

2006

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部