结构体struct、联合体union、枚举类型enum
1.c语言中的类型
1)内置类型——char,short,int,float,double;
2)用户自定义类型(UDT)——struct结构体,union联合体,enum枚举类型
2.内存对齐
2.1概念
1)内存对齐就是编译器为程序中的每个“数据单元”安排在适当的位置上
2)对于内存对齐问题,主要存在于struct和union等复合结构在内存中的分布情况
2.2规则
1)对于结构的各个成员,第一个成员位于偏移为0的位置,以后的每个数据成员的偏移量 = min ( #pragma pack(n) 指定的n值, 这个数据成员的字节数 ) 的倍数,#pragma pack(n)可以设置, Windows中默认为8,Linux中默认为4;
2)结构或联合体本身也要进行对齐,其字节大小=min( #pragram pack(n) , 长度最长的数据成员 )的倍数
struct MyStruct //MyStruct的内存分布:*xxx | **** | ** (*代表使用,x代表未使用)
{
char a; //偏移量为0
int b; //偏移量为4
short c; //偏移量为8
};
//windows下MyStruct的字节大小为:1+4+2=7,变成4的倍数:12
2.3为什么要内存对齐
1)平台原因:不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2)性能提升:经过内存对齐之后,CPU的内存访问速度大大提升,原因:
- 内存读取粒度:cpu把内存当成是一块一块的,块的大小可以是2,4,8,16 个字节,因此CPU在读取内存的时候是一块一块进行读取的,块的大小称为(memory granularity)内存读取粒度
- 假设CPU要读取一个4字节大小的数据到寄存器中(假设此CPU内存读取粒度是4),分两种情况讨论:
- 数据从0字节开始:直接将0~3四个字节完全读取到寄存器,完成,这时候没有任何影响
- 数据从1字节开始:首先先将0~3的4个字节读到寄存器,并再次读取4~7字节的数据进寄存器,接着把0、5、6、7的数据剔除,最后合并1,2,3,4字节的数据进寄存器,这些额外操作大大降低了CPU的性能
2.union联合体
2.1概念
1)联合体union类似于结构体struct(struct概念:不同类型数据的集合体)
2)联合体用同一段内存单元存放不同数据类型的成员,在使用时,一次只能使用其中的一个成员
3)它的所有成员相对于基地址的偏移量都为0
4)union的大小取决于它所有的成员中,占用空间最大的一个成员的大小,并且union的大小要能被其他成员的大小所整除
union U1
{
char s[];
}; union U2 //s占11字节,n占4字节,d占8字节,所以至少需11字节的空间,但11不能被8整除,所以补充字节到16
{
int n;
char s[];
double d;
}; int main()
{
cout << sizeof(U1) << endl; //输出:11
cout << sizeof(U2) << endl; //输出:16 return ;
}
2.2应用
1)当多个类型的变量要占用同一片内存时,可以使用联合体:检测当前机器是采用大端还是小端
2)当多个事物只取其一时(“n选1”),可以使用联合体:
//报文内容联合体
union PacketContent
{
Struct1 pkt1;
Struct2 pkt2;
Struct3 pkt1;
Struct4 pkt2;
}; //统一的报文结构
struct Packet
{
unsigned char pktType;//报文类型
PacketContent pktContent;//报文内容
};
4.enum枚举类型
4.1概念
1)枚举可以让一些数字符号化
2)c语言中枚举常量是按照int来处理
3)c语言的枚举变量可以++,c++的枚举变量不可以
4.2定义的格式
enum 枚举类型名 {枚举常量0=int常量(可无,默认值为0),枚举常量1=int常量(可无,默认值为1),枚举常量2,枚举常量3=int常量(可无,默认值为3),…};
enum Color { red, blue };
enum Color cfq;
cfq = red;
++cfq; //c语言的枚举变量可以++
enum Color { red, orange, blue };
Color hehe;
hehe = red;
++hehe; //错误,c++的枚举变量不可以++
结构体struct、联合体union、枚举类型enum的更多相关文章
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- C++-结构体,联合体,枚举,的区别
结构体: struct NUM { int number; }a; 结构体是声明只是一个模型,没有分配内存空间.当进行定义结构体变量后才分配内存空间 联合体: union data { int a ...
- android109 结构体,联合体,枚举,自定义
#include <stdio.h> #include <stdlib.h> void study(){ printf("吃饭睡觉打李志\n"); } // ...
- C#中的元组(Tuple)和结构体(struct)
在正常的函数调用中,一个函数只能返回一个类型的值,但在某些特殊情况下,我们可能需要一个方法返回多个类型的值,除了通过ref,out或者泛型集合可以实现这种需求外,今天,讲一下元组和结构体在这一方面的应 ...
- C和C++中结构体(struct)、联合体(union)、枚举(enum)的区别
C++对C语言的结构.联合.枚举 这3种数据类型进行了扩展. 1.C++定义的结构名.联合名.枚举名 都是 类型名,可以直接用于变量的声明或定义.即在C++中定义变量时不必在结构名.联合名.枚举名 前 ...
- 【UE4 C++ 基础知识】<4> 枚举 Enum、结构体 Struct
枚举 UENUM宏搭配BlueprintType可以将枚举暴露给蓝图,不使用的话,仅能在C++使用 //定义一个原生enum class enum class EMyType { Type1, Typ ...
- Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别
Swift有许多种存储数据方式,你可以用枚举(enums),元组(tuples),结构体(structs),类(classes),在这篇文章中我们将比较枚举.元组.结构体之间区别,首先从最简单的开始- ...
- C语言进阶——结构体,联合,枚举
----------------------------------------------------------我是一条划分线----------------------------------- ...
- 【 转】 C/C++结构体和联合体的区别
联合体用途:使几个不同类型的变量共占一段内存(相互覆盖) 结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-------自定义数据类型 总结: 声明一个联合体: union abc { i ...
随机推荐
- Spark+Scalar+Mysql
包:mysql-connector-java-5.1.39-bin.jar 平台:Win8.1 环境:MyEclipse2015 hadoop-2.7.3.tar.gz + winutils.exe ...
- 搭建基于MySQL的读写分离工具Amoeba
搭建基于MySQL的读写分离工具Amoeba: Amoeba工具是实现MySQL数据库读写分离的一个工具,前提是基于MySQL主从复制来实现的: 实验环境(虚拟机): 主机 角色 10.10.10.2 ...
- 调用免费的web service(天气预报)
”免费WebService”, 找到提供天气预报Webservice的网络地址 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 在url ...
- 06python上
product_list=[ ('Mac',9000), ('kindle',800), ('tesla',900000), ('python book',105), ('bike',2000), ] ...
- powerdesigner 基本概念
PowerDesigner是Sybase的企业建模和设计解决方案,采用模型驱动方法,将业务与IT结合起来,可帮助部署有效的企业体系架构,并为研发生命周期管理提供强大的分析与设计技术.PowerDesi ...
- 20165304 2017-2018-2《Java程序设计》学习总结
20165304 2017-2018-2<Java程序设计>学习总结 一.每周作业及实验报告链接汇总 1.我期望的师生关系 2.20165304学习基础和C语言基础调查 3.linux系统 ...
- 一篇面经(BAT面试)(转)
0. 写在之前 首先呢我的面试经历和一些面霸和收割机的大神相比绝不算丰富,但我这三个月应该能代表很大一部分人的心路历程:从无忧无虑也无知的状态,然后遭遇挫败,跌入低谷,连续数天的黑暗,慢慢调整,逼着自 ...
- LeetCode OJ 129. Sum Root to Leaf Numbers
题目 Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a num ...
- C语言递归函数讲解
递归函数是什么? 是函数.................... 你可以把它理解成是for循环与死循环的结合的函数.简单的说:递归函数是有条件终止的死循环函数: 死循环函数这里是指在函数体中调用自身: ...
- java简单的文件读写工具类
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedRead ...