自定义类型:结构体、枚举、联合
来源:互联网 发布:js 相对路径 绝对路径 编辑:程序博客网 时间:2024/05/22 10:39
结构体
定义和初始化:
基本定义:结构体,通俗讲就是打包封装,把一些有共同特性(或属于同一类事物的属性)的变量放在其内部,通过一定方法访问修改内部变量。
结构体的定义方式还有很多种:
1、只有结构体:
struct stu{ char name[20]; int age; float height;};
2、附加结构体类型的变量的定义:
struct stu{ char name[20]; int age; float height;}S;
3、简略结构体后面的名字:
struct{ char name[20]; int age; float height;}S;
4、
添加指针指向结构体变量
struct stu{ char name[20]; int age;}S,*p;
初始化:
struct stu{ char name[20]; int age;}S;struct stu S = { "haha", 18 };
结构体嵌套初始化 :
struct node{ int data; struct point p; struct node *next;}n1 = { 10, { 4, 5 },NULL };struct n2 = { 20, {5,6} 18 };
结构体的自引用:
struct node{ int data; struct node* next;};
看到这个,是不是想起了数据结构中的链表呢?
知道第一个结点,通过指针可以找到后面所有的结点。
结构体的成员:
结构体的成员可以是标量、指针、数组、甚至是其他结构体
那么如何访问其成员呢?
》点操作符
struct stu{ char name[20]; int age;};struct stu s;strcpy(s.name, "haha");s.age = 19;
》指向操作符
struct stu{ char name[20]; int age;}S;void print(struct S* sp){ printf("name=%s age=%d", (*sp->name, *sp.age));}
结构体内存对齐:
1、对齐规则:
i)第一个成员无须偏移(但是他也具有对齐数)。
ii)其他成员变量要对齐到一个数的整数倍处(这个数是对齐数)
vs中默认为8,Linux默认为4
iii)结构体的大小是最大对齐数的整数倍。
iv)嵌套结构体时,嵌套的结构体对齐到自己最大对齐数的整数倍,所以整个结构体的大小就是所有最大对齐数(嵌套的结构体对齐数也在内)的整数倍。
例题:
1、
struct s1{ char c1; int i; char c2;};int main(){ printf("%d\n", sizeof(struct s1)); system("pause"); return 0;}
2、
3、
4、结构体嵌套问题
为什么存在内存对齐?
1、平台原因(移植原因)
不是所有的硬件平台都能访问任意地址上的任意数据;有些平台只能在某些地址处取某些特定类型的数据,否则抛出异常。
2、性能原因
数据结构(尤其是栈)应该尽可能在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器要两次访问;而对齐则只需一次访问。
**总体来说,结构体的内存对齐就是以空间来换时间的做法,所以我们在设计结构体时,要把占用空间小的量尽量放在前面。
结构体传参
结构体传参的时候要传结构体的地址
struct S{ int data[1000]; int num;};struct S s = { { 1, 2, 3, 4 }, 1000 };//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);//传地址 system("pause"); return 0;}
上面的两种传参方式,首选传地址,这就和我们函数传参形成栈帧有关了,如果直接传一个结构体对象,假如结构体很大,那么压栈开销就会很大,导致性能的下降,在这个例子中,他结构体中还有数组,所以传结构体对象时数组不会传过去,而是会一遍遍实例化数组,所以开销是非常大的。
结构体实现位段:
位段的声明和结构体类似,1、位段的成员必须是int、unsigned int、或者signed int。2、位段的成员名后面有一个冒号和一个数字。比如:
struct A{ int _a : 2; int _b : 5; int _c : 10; int _d : 30;};
所以A需要两个int,大小就是8字节
再例如:
位段的内存分配:
1、位段的成员必须是位段的成员必须是int、unsigned int、或者signed int或者char(整型家族)2、位段的空间是按照4字节(int)或者1字节(char)的方式来开辟的。3、位段涉及很多不确定因素,不跨平台
不跨平台的原因:
int 是有符号还是无符号是不确定的。
位段中最大位的数目不确定。(16位机器是16,32位机器是32)。
位段中成员在内存中从左向右分配,还是从右向左不确定
当一个结构有两个位段,第二个位段成员比较大,无法容纳第一个位段剩的位时,是舍弃剩余的位还是利用,也是不确定的。
枚举
一 一列举。
定义:
enum day{ sun, mon, tues, wed, thur, fri, sat,};
定义一个周从星期天到星期六是枚举。{}中的内容是枚举类型的可能取值,也叫枚举常量,这些取值都是有值的,默认从零开始,每次递增一
使用:
只能用枚举常量给枚举变量赋值:
enum day{ sun, mon, tues, wed, thur, fri, sat,};enum day d = sun;d = 0;
优点:
1、增加代码可读性和可维护性。 2、与define定义的宏相比他有类型检查。 3、防止明名污染(封装)。 4、便与调试。 5、使用方便,一次可定义多个常量。
联合(共用体)
定义:
联合定义的变量包含一系列的成员,特征是这些成员共用同一块空间。
使用:
联合的成员是共用一块空间的,所以一个联合变量的大小,至少是最大成员的大小(因为联合至少有能力保存最大的那个成员)。
下面的代码输出结果相同,可以看出,成员确实共用一块空间。
union Un{ int i; char c;};int mian(){ union Un un; printf("%d\n", &(un.i)); printf("%d\n", &(un.c)); printf("%d\n", &(un)); system("pause"); return 0;}
应用:
判断计算机的大小端存储:
#include<stdio.h>union Un{ int i; char c;};int mian(){ union Un un; un.i = 0x11223344; un.c = 0x55; printf("%x", un.i); system("pause"); return 0;}
输出结果为:0x11223355由于我的计算机是小端存储,而c占i4个字节的低位,低地址放在低位就是小端存储。
计算联合变量的大小:
联合的对齐:
~联合的大小至少是最大成员的大小。
~当最大成员不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。
#include<stdio.h>union Un1{ int i; char c[5];};union Un2{ short c[7]; int i;};int mian(){ printf("%d\n",sizeof(union Un1));//8 printf("%d\n", sizeof(union Un2));//16 system("pause"); return 0;}
- 自定义类型:结构体、枚举、联合
- 自定义类型:结构体,枚举,联合
- 自定义类型:结构体,枚举,联合
- 自定义类型:结构体,枚举,联合
- 自定义类型(结构体、位段、枚举和联合)
- 自定义类型——结构体、枚举、联合
- 自定义类型:结构体,位段,枚举,联合
- 自定义类型(结构体,枚举,联合,位段)
- 自定义类型(结构体,位段,枚举,联合)总结
- 自定义类型——结构体,枚举,联合
- Pace 12 (自定义类型:结构体 位段 枚举 联合)
- 结构体、联合、枚举
- 结构体,枚举,联合
- 自定义类型部分知识写一篇博客。 知识点: >结构体类型创建 >结构体初始化 >结构体内存对齐 >位段,位段计算机大小。 >枚举+联合。
- 自定义类型:结构体,枚举,联合体
- 自定义类型:结构体,枚举,联合体
- 自定义类型---->结构体,枚举,联合体
- 联合 枚举和结构体
- L版本上添加关机振动,定时开机振动会失效
- iOS 添加到购物车 小动画
- Vue.js学习---vue概念理解No.1
- 生成tfrecords文件(29)---《深度学习》
- 不使用vector<bool>的原因和替代方法
- 自定义类型:结构体、枚举、联合
- 关于git的撤销
- 自定义圆形QLabel控件
- windbg crashdump调试,自定义切换栈帧
- oracle静态注册,动态注册,共享服务器配置
- a
- user版本如何打开root权限
- 我在转岗产品过程中遇到的十大面试问题
- 关于 MySQL 慢日志,你想知道的都在这