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),分两种情况讨论:
  1.  数据从0字节开始:直接将0~3四个字节完全读取到寄存器,完成,这时候没有任何影响
  2.  数据从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”),可以使用联合体:

试题:假设网络节点A和网络节点B中的通信协议涉及四类报文,报文格式为“报文类型字段+报文内容的结构体”,四个报文内容的结构体类型分别为Struct1~ Struct4,请编写程序以最简单的方式组织一个统一的报文数据结构。
分析:
报文的格式为“报文类型+报文内容的结构体”,在真实的通信中,每次只能发四类报文中的一种,我们可以将四类报文的结构体组织为一个union(共享一段内存,但每次有效的只是一种),然后和报文类型字段统一组织成一个报文数据结构。
//报文内容联合体
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的更多相关文章

  1. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  2. C++-结构体,联合体,枚举,的区别

    结构体: struct  NUM { int number; }a; 结构体是声明只是一个模型,没有分配内存空间.当进行定义结构体变量后才分配内存空间 联合体: union  data { int a ...

  3. android109 结构体,联合体,枚举,自定义

    #include <stdio.h> #include <stdlib.h> void study(){ printf("吃饭睡觉打李志\n"); } // ...

  4. C#中的元组(Tuple)和结构体(struct)

    在正常的函数调用中,一个函数只能返回一个类型的值,但在某些特殊情况下,我们可能需要一个方法返回多个类型的值,除了通过ref,out或者泛型集合可以实现这种需求外,今天,讲一下元组和结构体在这一方面的应 ...

  5. C和C++中结构体(struct)、联合体(union)、枚举(enum)的区别

    C++对C语言的结构.联合.枚举 这3种数据类型进行了扩展. 1.C++定义的结构名.联合名.枚举名 都是 类型名,可以直接用于变量的声明或定义.即在C++中定义变量时不必在结构名.联合名.枚举名 前 ...

  6. 【UE4 C++ 基础知识】<4> 枚举 Enum、结构体 Struct

    枚举 UENUM宏搭配BlueprintType可以将枚举暴露给蓝图,不使用的话,仅能在C++使用 //定义一个原生enum class enum class EMyType { Type1, Typ ...

  7. Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别

    Swift有许多种存储数据方式,你可以用枚举(enums),元组(tuples),结构体(structs),类(classes),在这篇文章中我们将比较枚举.元组.结构体之间区别,首先从最简单的开始- ...

  8. C语言进阶——结构体,联合,枚举

    ----------------------------------------------------------我是一条划分线----------------------------------- ...

  9. 【 转】 C/C++结构体和联合体的区别

    联合体用途:使几个不同类型的变量共占一段内存(相互覆盖) 结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-------自定义数据类型 总结: 声明一个联合体: union abc { i ...

随机推荐

  1. mysql修改root用户的登录密码

    修改mysql root用户登录密码的方法有很多,网上可以查找到相关的资料 我通过上网查询以后实验成功的方法是使用下面的sql语句进行修改 UPDATE user SET Password = PAS ...

  2. 异步启动solidworks

    两种方法: SldWorks App = new SldWorks(); App.Visible = true; //SldWorks.Application.24是2016 // App = (Sl ...

  3. py库: flask笔记

    http://flask.pocoo.org/ http://flask.pocoo.org/docs/0.12/api/#api API http://docs.pythontab.com/flas ...

  4. 59.纯 CSS 创作彩虹背景文字

    原文地址:https://segmentfault.com/a/1190000015352436 修改后地址:https://scrimba.com/c/cqK3LaTQ 感想: 又一次见识到CSS的 ...

  5. How to solve “Dynamic Web Module 3.1 requires Java 1.7 or newer” in Eclipse

    How to solve “Dynamic Web Module 3.1 requires Java 1.7 or newer” in Eclipse Last updated on June 20t ...

  6. SQL 查询数据库中包含指定字符串的相关表和相关记录

    declare @str varchar(100)set @str='我要找的' --要搜索的字符串 declare @s varchar(8000)declare tb cursor local f ...

  7. Android应用开发中,第三方集成新浪微博(sinaWeiboSDK)的过程记录

    作为一个android开发人员,不可避免的要学会使用和集成第三方API的能力 而新浪微博作为现在最主要的新闻速递媒体,使用十分普遍,并且提供了较为详细的API接入方法,故此选择集成sinaWeibiS ...

  8. 尚硅谷springboot学习33-整合mybatis

    引入mybatis依赖(还要引入mysql和jdbc依赖) <dependency> <groupId>org.mybatis.spring.boot</groupId& ...

  9. suse linux安装lrzsz

    1.从下面的网站下载 lrzsz-1.12.20.tar.gz http://www.filewatcher.com/m/lrzsz-0.12.20.tar.gz.280938.0.0.html 2. ...

  10. 27.Hibernate-缓存和懒加载.md

    目录 1.一级缓存 2.缓存的有效性 3.list和iterator缓存的区别 4.懒加载 4.1get 4.2load 1.一级缓存 Hibernate中一级缓存是Session缓存,有效范围在Se ...