结构体+枚举+联合体
创始人
2024-05-23 19:42:30
0

目录

一、结构体的声明

(一)结构的基础知识 

(二)结构的声明 

(三)特殊的声明 

(四)结构的自引用 

1. 一个结构体内部包含一个类型为该结构本身的成员(不合法)

2. 一个结构体内部包含一个指向该结构体本身的指针(合法)

3. typedef和结构体非法的形式

4. typedef和结构体合法的形式 

(五) 结构成员的直接访问和间接访问

补充(结构体指针)

(六)结构体变量的定义和初始化 

(七)结构体内存对齐 

1. 结构体的对齐规则

2. 举例1 

3. 举例2

4. 为什么存在内存对齐? 

5. 在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到: 

(八) 修改默认对齐数 

(九)结构体传参 

二、枚举

(一)枚举类型的定义 

(二)枚举的优点 

三、联合(共用体) 

(一)联合类型的定义 

(二)联合的特点 

(三)联合大小的计算 


一、结构体的声明

(一)结构的基础知识 

  • 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量 

(二)结构的声明 

struct tag//tag是结构体标签
{成员列表;
}变量名列表;
  •  例如描述一个学生:

  

(三)特殊的声明 

  •  在声明结构的时候,可以不完全的声明

  • 上面的两个结构在声明的时候省略掉了结构体标签(tag) 
  • 注意:p = &x是不合法的,编译器会把上面的两个声明当成完全不同的两个类型

(四)结构的自引用 

1. 一个结构体内部包含一个类型为该结构本身的成员(不合法)

struct Node
{
int data;
struct Node next;
};
  • 这种类型的自引用是非法的,因为成员next是另外一个完整的结构,其内部还将包含它自己的成员next,这第2个成员又是另外一个完整的结构,它将包括它自己的成员next,这样重复下去永无止境。

2. 一个结构体内部包含一个指向该结构体本身的指针(合法)

struct Node
{
int data;
struct Node* next;
};
  • next现在是一个指针而不是结构,编译器在结构的长度确定之前就已经知道指针的长度,所以这种类型的自引用是合法的

3. typedef和结构体非法的形式

typedef struct
{
int data;
Node* next;
}Node;
  • 这个声明的目的是为这个结构创建类型名Node,但是类型名直到声明的末尾才定义,所以在结构声明的内部它尚未定义 

4. typedef和结构体合法的形式 

typedef struct Node
{
int data;
struct Node* next;
}Node;

(五) 结构成员的直接访问和间接访问

  • 直接访问是通过操作符(.)访问的。点操作符可以接受两个操作数,例如stu.age,其中左操作数stu就是结构体变量的名字,右操作数age就是需要访问的成员的名字
  • 间接访问是首先就是对指针执行间接访问操作,然后获得这个结构;然后使用点操作符(.)来访问它的成员。例如:(*p1).age后来为了方便c语言提供了箭头→,但是箭头的左边必须是一个指向结构的指针,右边是一个指定的结构成员
#include
struct student
{int age;char name[20];
};
struct student* p1;
int main()
{struct student stu = { 12,"lisi" };p1 = &stu;//p1指向stuprintf("%d\n", stu.age);//输出12printf("%d  %d", (*p1).age, p1->age);//输出12 12return 0;
}

补充(结构体指针)

结构体指针就是指向结构体变量的指针,表示的是这个结构体变量在内存中的起始位置,如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就指向该结构体变量 

(六)结构体变量的定义和初始化 

//代码举例一:
#include 
struct S
{char c;int a;double d;char arr[20];
}; 
int main()
{struct S s={'c',100,3.14,"hello world"};return 0; 
}
//代码举例二:
struct student
{char name[20];char sex;//性别int tele;} stu3,stu4={"zhangsan","man",123456};
//代码举例三:嵌套初始化
struct Node
{int data;struct point p;struct Node*next;
}n1={10,{4,5},NULL};//结构体嵌套初始化
struct Node n2={20,{5,6},NULL}; //结构体嵌套初始化

(七)结构体内存对齐 

1. 结构体的对齐规则

  • 第一个成员在与结构体变量偏移量为0的地址处。
  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
  • 对齐数 = 编译器默认的一个对齐数与该成员大小的较小值 ,VS中默认的值为8
  • 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
  • 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍 

2. 举例1 

#include
struct S1
{char c1;int a;char c2;
};struct S2
{char c1;char c2;int a;
};int main()
{struct S1 s1 = { 0 };printf("%d\n", sizeof(s1));//12struct S2 s2 = { 0 };printf("%d\n", sizeof(s2));//8return 0;
}

 

 

3. 举例2

#include
struct S3
{double d;char c;int i;
};struct S4
{char c1;struct S3 s3;double d;
};int main()
{printf("%d\n", sizeof(struct S3));//16printf("%d\n", sizeof(struct S4));//32return 0;
}

4. 为什么存在内存对齐? 

1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特
定类型的数据,否则抛出硬件异常。
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说:结构体的内存对齐是拿空间来换取时间的做法

5. 在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到: 

  • 让占用空间小的成员尽量集中在一起 
//未修改
#include
struct S1
{char c1;int i;char c2;
};//修改后
struct S2
{char c1;char c2;int i;
};int main()
{printf("%d\n", sizeof(struct S1));//12printf("%d\n", sizeof(struct S2));//8return 0;
}

(八) 修改默认对齐数 

//未修改
#include
struct S1
{char c1;double d;
};
int main()
{printf("%d\n", sizeof(struct S1));// 16(默认对齐数是8)return 0;
}//举例2:
#pragma pack(4)//修改默认对齐数为4
#include
using namespace std;
struct S1
{char c1;double d;
};
#pragma pack()//取消设置的默认对齐数,还原为默认int main()
{printf("%d\n", sizeof(struct S1));//12(默认对齐数是4)return 0;
}

(九)结构体传参 

#include
struct S
{int data[1000];int num;
};
struct S s = { {1,2,3,4}, 1001 };
//结构体传参
void print1(struct S s)
{printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print1(s);//传结构体print2(&s); //传地址return 0;
}

二、枚举

(一)枚举类型的定义 

enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
enum Color//颜色
{
RED,
GREEN,
BLUE
};
  • 以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。{}中的内容是枚举类型的可能取值,也叫 枚举常量 
  • 这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值
enum Color//颜色
{
RED=1,
GREEN=2,
BLUE=4
};

(二)枚举的优点 

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量  

三、联合(共用体) 

(一)联合类型的定义 

  • 联合也是一种特殊的自定义类型。这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)  
#include
//联合类型的声明
union Un
{char c;//1int i;//4
};
int main()
{//联合变量的定义union Un u;//计算变量的大小printf("%d\n", sizeof(u));//4return 0;
}

(二)联合的特点 

  • 联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)  
#include
//联合类型的声明
union Un
{char c;//1int i;//4
};
int main()
{//联合变量的定义union Un u;printf("%p\n", &u);//00B6F7B8printf("%p\n", &(u.c));//00B6F7B8printf("%p\n", &(u.i));//00B6F7B8return 0;
}

(三)联合大小的计算 

  • 联合的大小至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍 
#include
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{printf("%d\n", sizeof(union Un1));//8printf("%d\n", sizeof(union Un2));//16return 0;
}

相关内容

热门资讯

终极三国的经典台词 终极三国的经典台词  1.如此如此,这般这般~  2.我姓刘名备,字玄德,是中山靖王的儿子,因为家道...
团代会主持词 团代会主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。现今社会在不断向前发展,主...
《剑雨》经典台词盘点 《剑雨》经典台词盘点  1、生未必乐,死未必苦。  2、未来已成现在,现在已成过去,随心而去。  3...
幼儿园园长开园致辞 幼儿园园长开园致辞  在日常学习、工作和生活中,大家都不可避免地会接触到致辞吧,致辞是指在仪式上所讲...
辩论赛主持人主持词开场白 辩论赛主持人主持词开场白  辩论赛怎么能没有我们主持人呢?下面是小编搜集整理的辩论赛主持人主持词开场...
李白凤求凰特殊台词 李白凤求凰特殊台词  在王者荣耀中每个英雄人物都有台词,那么李白凤求凰特殊台词是什么呢?以下是小编整...
学生读书交流会主持词 学生读书交流会主持词  主持词要把握好吸引观众、导入主题、创设情境等环节以吸引观众。在当下的中国社会...
晚会的闭幕词 晚会的闭幕词(精选16篇)  主持词是主持活动的必备稿子,是活跃气氛,引导活动进行的存在,下面是小编...
阿甘正传电影经典台词 阿甘正传电影经典台词大全  《阿甘正传》给我们展现了一个虽然智商只有75,却是忠诚、守信、执着、友善...
致青春经典台词 致青春经典台词  1、青春是有限的,不能在犹豫和观望中度过。  2、很多东西就像气球一样,看上去很美...
追悼会主持词 追悼会主持词  什么是追悼会  追悼会,为悼念死者而召开的会议。有些在死者遗体所在地举行,有些在殡仪...
幼儿园大班新年联欢会主持词   主持人:左XX  开场:  左:亲爱的老师、同学们:  合:大家好!  彭:20XX年马上就要过...
新春的主持稿 新春的主持稿  在日常生活和工作中,需要使用主持稿的情况越来越多,主持稿是主持人在会议或是节目当中串...
五四青年节的致辞 五四青年节的致辞(通用20篇)  在平日的学习、工作和生活里,大家总少不了要接触或使用致辞吧,致辞是...
新年年会简短优秀致辞 新年年会简短优秀致辞(通用8篇)  在生活、工作和学习中,大家都不可避免地会接触到致辞吧,致辞具有很...
告别仪式的主持词 告别仪式的主持词3篇  告别主持词篇一:  男:离别,是一个沉重的动词。  女:离别,一个让人一生难...
喜爱夜蒲2经典台词 喜爱夜蒲2经典台词  1、做要做到最好,玩要玩到最尽。  2、我们明知不能相爱,可还是相爱了,未曾绽...
领导年会致辞 领导年会致辞  无论在学习、工作或是生活中,大家对致辞都不陌生吧,致辞是指在举行会议或某种仪式时具有...
关于保险公司年会主持词 关于保险公司年会主持词  公司的类型有哪些  根据《中华人民共和国公司法》公司的主要形式为无限责任公...