第十一章 枚举、结构体、联合体

§11.1 枚举类型

【定义】

一类相关的标志符组合起来形成的整体,枚举实质上是整型数据。使用enum关键字修饰。

【枚举变量声明方式】

1、声明枚举类型的同时声明枚举变量

enum 枚举类型名{
​枚举成员变量1,
​枚举成员变量2,
​……
​
}枚举变量名;

eg:

enum Week{​SUN,
​MON,
​TUES,
​WED,
​THURS,
​FRI,
​SAT
​
}week;

2、先声明枚举类型, 后声明枚举变量

enum 枚举类型名{
​枚举成员变量1,
​枚举成员变量2,
​……
​
};
enum 枚举类型名 枚举变量名;

eg:

 enum Week{​SUN,
​MON,
​TUES,
​WED,
​THURS,
​FRI,
​SAT
​
};
​
enum Week week;

3、省略枚举类型名,直接声明枚举变量

enum{
​枚举成员变量1,
​枚举成员变量2,
​……
​
}枚举变量名;

eg:

enum{​IDLE,
​WALK,
​RUN,
​ATTACK,
​DEFEND,
​DIE,
​
}HeroState;

【特性】

1、枚举的实质是整型变量, 其取值范围是整数取值范围的一个子集

2、枚举成员数值默认从0开始, 依次递增1,若枚举成员被初始化,则从当前枚举成员开始, 后面所有成员数值将在当前枚举成员数值的基础上依次递增1

3、枚举变量定义位置可放置在所有函数体之外,也可放置在函数体内

4、枚举成员变量之间使用【,】隔开, 最后一个枚举成员变量后可省略,不写

5、枚举成员变量取值范围是其对应的所有枚举成员

eg:

#include <stdio.h>
​
/************* 枚举 *************/
//周状态枚举
enum Week{SUN = 1,MON,TUES = 10,WED,THURS,FRI,SAT
}week = SUN;
​
//任务状态枚举
enum TaskState{NONE,PROCESSING,SUCCESSFULLY,FAILED,
};
​
//英雄状态枚举
enum{IDLE,WALK,RUN,ATTACK,DEFEND,DIE,
}HeroState;
​
//枚举作为函数形参
void JudegTaskState(enum TaskState task_state){switch (task_state) {case PROCESSING:printf("Task is proccessing!n");break;case SUCCESSFULLY:printf("Task is Done!n");break;case FAILED:printf("Task is failed!n");break;default:printf("Sorry, You can fire me!n");break;}
}
​
int main(int argc, const char * argv[]) {/************* 枚举 *************///    省略枚举类型名,直接声明枚举变量HeroState = IDLE;printf("HeroState = %dn", HeroState);//    先声明枚举类型, 后声明枚举变量enum TaskState task_state;task_state = NONE;JudegTaskState(task_state);//声明枚举类型的同时声明枚举变量week = TUES;//初始化操作week = 123;//超出枚举范围, 缺少实际意义printf("week = %dn", week);/*printf("SUN = %dn", SUN);printf("MON = %dn", MON);printf("TUES = %dn", TUES);printf("WED = %dn", WED);printf("THURS = %dn", THURS);printf("FRI = %dn", FRI);printf("SAT = %dn", SAT);*/return 0;
}
​

§11.2 结构体类型

【概念】

一系列已有的数据类型定义的变量的集合。(用已有的数据类型的组合结合struct关键字组成的新的数据类型,新类型被称为结构体)

注意:

struct关键字修饰。

【结构体变量声明方式】

1、先声明结构体类型, 再声明结构体变量

struct 结构体类型名{
​结构体成员变量1;
​结构体成员变量2;
​……
​
};
struct 结构体类型名 结构体变量名;

eg:

struct Person{​long id;
​char name[20];
​char gender;
​int age;
​char remuse[100];
​
};
​struct Person person;

2、声明结构体类型的同时, 声明结构体变量

struct 结构体类型名{
​结构体成员变量1;
​结构体成员变量2;
​……
​
}结构体变量名;

eg:

struct Person{​long id;
​char name[20];
​char gender;
​int age;
​char remuse[100];
​
}person;

3、使用typedef关键字直接对无结构体类型名的结构体取别名,再声明结构体变量

typedef struct{
​结构体成员变量1;
​结构体成员变量2;
​……
​
}结构体类型别名;

eg:

struct Person{​long id;
​char name[20];
​char gender;
​int age;
​char remuse[100];
​
}PERSON;
​
PESRON person;

【结构体变量初始化】

注意:定义的同时进行初始化。

【结构体成员访问】

成员访问运算符: .

格式:

结构体变量.结构体成员变量

【结构体指针】:指向结构体的指针, 称之为结构体指针。

注意:结构体指针指向结构体成员列表中第一个成员的内存地址,也就是结构体成员首地址。

struct Person{​long id;//结构体成员首地址
​char name[20];
​char gender;
​int age;
​char remuse[100];
​
}person = {110001232130, "张三", 'M', 120, "腾讯"};
​
struct Person * p_Person;
​
p_Person = &person;

【结构体指针访问运算符】:->

格式:

结构体指针变量 -> 结构体成员

【结构体数组】

struct Person persons[5] = {p1, p2, p3, p4, p5};

【结构体赋值】:使用相同结构体数据类型的结构体变量赋值另外一个结构体变量

注意:

1、只能是具有相同结构体数据类型的变量之间才能执行赋值操作

2、结构体变量之间相互赋值,一个变量内容的修改并不会影响到另外一个

eg:

#include <stdio.h>
​
/************* 结构体 *************/
//使用typedef关键字直接对无结构体类型名的结构体取别名,再声明结构体变量
​
typedef struct{int itemID;char itemName[20];float itemPrice;char itemDES[50];
}ITEM;
​
//声明结构体类型的同时, 声明结构体变量
struct Animal{long id;char name[20];char gender;int age;char remuse[100];
}animal;
​
//先声明结构体类型, 再声明结构体变量
//人物信息结构体
struct Person{long id;char name[20];char gender;int age;char remuse[100];
};
​
void PrintPerson(struct Person p){printf("id = %ld, name = %s, gender = %c, age = %d, resume = %sn", p.id, p.name, p.gender, p.age, p.remuse);
}
​
typedef struct{char a[10];int b;char c;double d;
}VALUE;
​
typedef union {short value;char ch;}TEST;
​
​
int main(int argc, const char * argv[]) {/************* 结构体 *************///结构体赋值struct Person p1 = {1110032423423, "liming"};//    PrintPerson(p1);struct Person p2 = {1121321312123, "zhangning", 'M', 12, "四年级"};//    PrintPerson(p2);p1 = p2;//    PrintPerson(p1);p1.age = 23;PrintPerson(p2);//结构体指针struct Person person = {110001232130, "张三", 'M', 120, "腾讯游戏天美工作室"};struct Person * p_Person;p_Person = &person;//    printf("id = %pnperson = %pnp_Person = %pn", &person.id,person, p_Person);//    printf("id = %ld, name = %s, gender = %c, age = %d, resume = %sn", (*p_Person).id, (*p_Person).name, (*p_Person).gender,(*p_Person).age, (*p_Person).remuse);printf("id = %ld, name = %s, gender = %c, age = %d, resume = %sn", p_Person -> id, p_Person -> name, p_Person -> gender, p_Person -> age, p_Person -> remuse);ITEM item = {1001, "紫魂碎片", 123.45, "拥有者无敌"};printf("itemID = %d, itemName = %s, itemPrice = %.2f, itemDES = %sn", item.itemID, item.itemName, item.itemPrice, item.itemDES);struct Person p = {110001232130, "张三", 'M', 120, "腾讯游戏天美工作室"};PrintPerson(p);return 0;
}
​

§11.3 结构体大小与内存对齐

【结构体内存大小及内存对齐规则】

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个 数据成员放在 offset 为 0 的地方,以后每个数据成员的对齐按照#pragma pack 指定的数值和这个数据成员自身长度中,比较小的那个进行。

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合) 本身也要进行对齐,对齐将按照#pragma pack 指定的数值和结构(或联合)最 大数据成员长度中,比较小的那个进行。

3、结合 1、2 可推断:当#pragma pack 的 n 值等于或超过所有数据成员长度 的时候,这个 n 值的大小将不产生任何效果。

结构体类型在默认情况下,为了方便结构体内元素的访问和管理,当结构体内的元素的长度(内存大小)都小于处理器(CPU)的位数时,便以结构体里面最长的数据元素为对齐单位。也就是说,结构体的长度一定是最长的数据元素的整数倍。如果结构体内存在长度大于处理器位数的元素,那么就以处理器的位数为对齐单位。但是结构体内类型相同的连续元素和数组一样,将在连续的内存空间内。

eg:

#include <stdio.h>
​
#pragma pack(8) //n = 1, 2, 4, 8, 16
​
typedef struct{char a[10];int b;char c;double d;
}VALUE;
​
int main(int argc, const char * argv[]) {printf("VALUE = %ldn", sizeof(VALUE));return 0;
}

案例分析:

注意:

结构体中的值从上往下依次分配,先找到最大字节的变量,然后依次从上往下分配内存,当分配到相应类型 时,图中的数字编号一定要能整除当前类型的字节数,比如第2个类型的变量占4个字节,要从12开始让它占 位。

实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:

结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍);

结构体大小必须是所有成员大小的整数倍。

§11.4 共用体(联合体)

共用体看起来很像结构体,只不过关键字由struct变成了union。共用体和结构体的区别在于:结构体定义了一个由多个数据成员组成的特殊类型,而共用体定义了一块为所有数据成员共享的内存。

格式:

union 共用体名{成员列表
}变量列表;

【共用体变量声明】

eg:

union DataUnion{int iNum;char aChar;
}data;//声明共用体变量

【共用体变量初始化】

注意:

对共用体变量初始化时,只需要一个初始化值就足够了,其类型必须和共用体的第一个成员的类型相一致。

eg:

union DataUnion{int iNum;char aChar;
}data = {97};//声明共用体变量

【共用体成员访问】

【格式】

共用体变量.共用体成员名;

eg:

#include <stdio.h>
​
#pragma pack(8) //n = 1, 2, 4, 8, 16
​
union DataUnion{int iNum;char aChar;
}data = {97};//声明共用体变量
​
int main(int argc, const char * argv[]) {printf("iNum = %dn", data.iNum);printf("aChar = %cn", data.aChar);return 0;
}

当前操作系统缺少黑体等字体_第十一章 枚举、结构体、联合体相关推荐

  1. 当前操作系统缺少黑体等字体_操作系统开发之——中断

    这里先提交一个代码的错误,之前运行过快,没看出刷屏的问题: // kernel/console.c...void init_console(void) {... // Before: // conso ...

  2. 当前操作系统缺少黑体等字体_从零开始开发一个操作系统

    在2019年的最后一天终于完成了整个系统的开发,并给它起名曰--Inios .就如同文章名字一样,完全是从内核编写,非二次开发,从最初的"hello os"到初次有了系统的样子.主 ...

  3. 当前操作系统缺少黑体等字体_2020世界互联网大会:360视觉、360守望领域、360城市运营操作系统齐亮相...

    来源:环球网 11月22日上午,2020年世界互联网大会"互联网之光"博览会在浙江乌镇开幕.期间,360数字城市集团携城市运营操作系统,与360视觉.360守望领域社区安全解决方案 ...

  4. java语言仅支持单重继承_java语言程序设计基础篇习题_复习题_第十一章

    java语言程序设计基础篇习题_复习题_第十一章 11.1 下面说法是真是假?一个子类是父类的子集. 11.2 使用什么关键字来定义一个子类 11.3 什么是单一继承?什么是多重继承?java支持多重 ...

  5. java程序设计基础_陈国君版第五版_第十一章例题

    java程序设计基础_陈国君版第五版_第十一章习题 class MyThread extends Thread { private String who;public MyThread(String ...

  6. java程序设计基础_陈国君版第五版_第十一章习题

    java程序设计基础_陈国君版第五版_第十一章习题 /*** 题目:假设某家银行可接受顾客的汇款,每进行一次汇款,便可计算出汇款的总额.现有两名顾客,每人分三次,每次一百元将钱汇入.试编程来模拟顾客的 ...

  7. ubuntu vscode 配置字体_第五章 Ubuntu搭建ESP32开发环境(vscode)

    Vscode安装 ubuntu软件中自带vscode的安装包,一键完成,不废话,没有的想办法解决. 编译链操作 下载 官方最新地址 有系统区别,下载对应的压缩到到电脑 · for 64-bit Lin ...

  8. linux crontab 每5分钟执行一次_第十一章:走进Linux世界——源码包管理and任务计划。...

    一.文件管理 (1)概述 Source Code 源代码经过GCC.C++编译环境编译才能运行 可以设定个人设置,开关功能 (2)源码包管理 获取源码包--官网下载到真机,然后 rz 命令上传到虚拟机 ...

  9. zynqpl端时钟_第十一章 ZYNQ-MIZ701 PS读写PL端BRAM

    本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将结果 ...

  10. thymeleaf rs 查询结果_第十一章 JDBC与MySQL数据库(10)——通用查询

    通用查询 本节的目的是编写一个类,只要用户将数据库名.SQL语句传递给该类对象,那么该对象就用一个二维数组返回查询的记录. 编写通用查询,需要知道数据库表的列(字段)的名字,特别是表的列数(字段的个数 ...

最新文章

  1. Java魔法堂:深入正则表达式API
  2. JavaScript 自定义对象
  3. fzu 2154 YesOrNo
  4. 怎样用计算机命令修复软件,电脑修复指令是什么
  5. 计算机语法分析,电子科技大学-计算机学院-编译原理实验-语法分析.pdf
  6. 训练及优化神经网络基本流程之第0到6步
  7. KL散度的通俗易懂理解
  8. 拉普拉斯算子属于卷积方法吗_论文笔记 - 图卷积神经网络综述
  9. SAS入门教程1---SAS系统简介
  10. 语音信号预加重与去加重(Matlab+Keil)
  11. 相机镜头等效焦距和实际焦距换算
  12. 线性回归使用的基本条件
  13. CG-23H 超声波风速风向传感器--易风(加热型)
  14. 原生js实现(别踩白块小游戏)
  15. Java Spire.Presentation 之PPT文本图片内容提取
  16. 外包公司,真的是互联网“二等公民”吗?
  17. java dvd 管理_Java学习案例一:DVD管理器
  18. Msp430 bsl program
  19. 图片转文字微信小程序
  20. 罗技F710使用笔记

热门文章

  1. 13.深入分布式缓存:从原理到实践 --- 缓存在社交网络Feed系统中的架构实践
  2. 7.Shell 编程从入门到精通 --- 流编辑
  3. 42. Element hasChildNodes() 方法
  4. 广东石油化工学院大学计算机基础,大学计算机基础习题集-北京石油化工学院文档.doc...
  5. php中字符串与数组的相互转化explode(separator,$str)与implode(separator,$arr)
  6. form表单上传文件
  7. 存储过程,是否有查看所有项目功能
  8. Flex中如何通过设置GridLines对象的horizontalAlternateFill样式交错显示LineSeries图表背景颜色的例子...
  9. oracle pl/sql发送邮件多个收件人问题
  10. hibernate Restrictions 用法