一、关键字说明
C语言有32个关键字,C语言通过关键字的使用使编译器进行相关的操作
结构体对应关键字struct
共用体(联合体)对应的关键字是union
枚举类型对应的关键字是enum
二、结构体、共用体(联合体)、枚举定义
结构体的定义:一种或多种基本类型或构造类型的数据的集合(构造类型)。
共用体(联合体)的定义:所谓的共用体(联合体)就是其中的成员共用一段内存,内存的大小由最大的那个成员的大小确定。
枚举类型:C语言等计算机编程语言中是一种构造数据类型,它用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型。
三、结构体、共用体与内存分配的关系
结构体:内存对齐——最大以4字节对齐(32位机)
共用体:
四、结构体的使用
step1:结构体的定义
(1)先定义结构体类型,再去定义结构体变量
(2)struct 结构体类型名{
成员列表
};
(3)构造的数据类型是 struct 结构体类型名
(4)例子
struct stu{
int num;
char name[20];
char sex;
};
step2:结构体取成员操作
(1)采用.取结构体成员
(2)采用->取结构体成员
定义结构体指针,用结构体指针->成员变量进行取值操作
(3)基址 + 偏移 = 取成员
step3:结构体的初始化和使用
(1)直接定义时并初始化
(2)采用bzero和memset对结构体进行初始化,初始化后直接进行赋值操作
step4:结构体数组
(1)结构体数组的定义:结构体数组是个数组,由若干个相同类型的结构体变量构成的集合
(2)结构体数组(类似int a[10])的定义方法:
.NOTE:结构体数组从两方面来理解
(1)结构体和基本数据类型,原则上都是数据类型,一个是构造数据类型,一个是基本数据类型
(2)数组方面:基本数据类型int a[10], 构造数据类型struct stu student[10]
struct stu{
int num;
char name[20];
char sex;
};
struct stu student[10];
这个数组有10个元素分别是student[0] 、student[1]、student[2]..........student[9]
(3)数组元素的使用
1)student0].num =101;//用101给student数组的第0个结构体变量的num赋值
2)使用字符串操作函数:strcpy(student[1].name,"lucy");
step5:结构体指针
(1)结构体指针:即结构体的地址
(2)定义一个变量来存放这个地址,那这个变量就是结构体指针变量。
(3)结构体指针变量的定义方法:
.NOTE:结构体指针从两方面来理解
(1)结构体和基本数据类型,原则上都是数据类型,一个是构造数据类型,一个是基本数据类型
(2)指针变量方面:基本数据类型int *a, 构造数据类型struct stu *ps
(4)struct stu{
int num;
char name[20];
};
struct stu * p;//定义了一个struct stu *类型的指针变量,变量名是p,p占4个字节,用来保存结构体变量的地址编号
(5)使用: struct stu boy;
struct stu *p;
p=&boy;
访问结构体变量的成员方法:
(1)boy.num=101;//可以,通过结构体变量名.成员名
(2)(*p).num=101;//可以,*p相当于p指向的变量boy
(3)p->num=101;//可以,指针->成员名
通过结构体指针来引用指针指向的结构体的成员,前提是指针必须先指向一个结构体变量。
step6:结构体内存对齐机制——内存对齐,提高寻址效率
用空间来换时间,提高cpu读取数据的效率
规则1:结构体分配内存时哪个基本类型的成员占字节数多,就以它的大小为单位开辟内存,
在gcc中出现了double类型的,例外
1:成员中只有char型数据 ,以1字节为单位开辟内存。
2:成员中出现了short int 没有更大字节数的基本类型数据以2字节为单位开辟内存
3、出现了int float 没有更大字节的基本类型数据的时候以4字节为单位开辟内存。
4、出现了double类型的数据
情况1:
在vc里,以8字节为单位开辟内存。
情况2:
在gcc里,以4字节为单位开辟内存。
无论是那种环境,double型变量,占8字节。
注意:
如果在结构体中出现了数组,数组可以看成多个变量的集合。
如果出现指针的话,没有占字节数更大的类型的,以4字节为单位开辟内存。
在内存中存储结构体成员的时候,按定义的结构体成员的顺序存储。
例1:struct stu{
char sex;
int age;
}lucy;
lucy的大小是4的倍数。
规则2:字节对齐
1:char 1字节对齐 ,即存放char型的变量,内存单元的编号是1的倍数即可。
2:short int 2字节对齐 ,即存放short int 型的变量,起始内存单元的编号是2的倍数即可。
3:int 4字节对齐 ,即存放int 型的变量,起始内存单元的编号是4的倍数即可
4:long int 在32位平台下,4字节对齐 ,即存放long int 型的变量,起始内存单元的编号是4的倍数即可
5:float 4字节对齐 ,即存放float 型的变量,起始内存单元的编号是4的倍数即可
6:double
1.vc环境下
8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量占8字节
2.gcc环境下
4字节对齐,即存放double型变量的起始地址,必须是4的倍数,double变量占8字节。
注意3:当结构体成员中出现数组的时候,可以看成多个变量。
注意4:开辟内存的时候,从上向下依次按成员在结构体中的位置顺序开辟空间
例1:
struct stu{
char a;
short b;
int c;
}temp;
五、共用体(联合体)的使用
step1:共用体的定义
(1)几种不同类型的变量存到同一段内存单元中,几个变量所使用空间相互重叠
(2)这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构
(3)共用体所有成员占有同一段地址空间
step2:共用体的大小
(1)共用体的大小是其占内存长度最大的成员的大小
typedef union data{
short int i;
char ch;
float f;
}DATA;
DATA temp2;
共用体temp2占4个字节,即i、ch、f共用4个字节
step3:共用体与大小端序
step6:共用体的本质
根据union固定首地址和union按最大需求开辟一段内存空间两个特征,可以发现,所有表面的定义都是虚的,所谓联合体union,就是在内存给你划了一个足够用的空间,至于你怎么玩~它不管~!(何止是union和struct,C不就是玩地址么,所以使用C灵活,也容易犯错)
给你首地址 + 内存空间,剩下的自己操作
六、枚举类型的应用
step1:枚举类型的定义
在C语言等计算机编程语言中是一种构造数据类型,它用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型
step2:枚举类型的特征
(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。
(5) 枚举型是预处理指令#define的替代。
(6) 类型定义以分号;结束。
step3:枚举声明变量——枚举构造数据类型,与基本数据类型一致,都是数据类型
(1)枚举类型的定义和变量的声明分开
(2)类型定义与变量声明同时进行
(3)用typedef关键字类型重定义
.NOTE:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量
step4:使用枚举类型的变量
(1)先声明变量,再对变量赋值
(2)声明变量的同时赋初值
(3)定义类型的同时声明变量,然后对变量赋值
(4)定义类型的同时声明变量,然后对变量赋值
step5:enum与sizeof的千丝万缕
枚举就是在其相应作用域内的一个标识符而已,编译器根本不知道什么是枚举这个东西,枚举对于编译器来说就是int类型的值而已,只不过是个常量int,枚举的一切行为表现都与一个普通的int值没有区别,所以sizeof的值为4(32位机)。