C语言用例子一次性讲清楚结构体和联合体区别,xdm看过来!

Posted SuchABigBug

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言用例子一次性讲清楚结构体和联合体区别,xdm看过来!相关的知识,希望对你有一定的参考价值。

一、结构体

1. 结构体声明

正常声明,特殊声明以及自引用

普通的声明方式一般为:

struct Car{
	char carBrand[20];
	int carEngineVolume;
	int year;
	char manufacturingCountry[20];
};

匿名声明方式:

struct {
	char carBrand[20];
	int carEngineVolume;
	int year;
	char manufacturingCountry[20];
}*Car;

结构自引用:

如链表的定义

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

2. 结构体初始化

以车为例子

struct Car volks = {"Volkswagen", 8, 2, "Germany"};

3. 结构体内存对齐

重点来了!!!
c语言中的结构体内存是如何对齐的呢?

根据一下几个原则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

(对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值)

  1. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  2. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所
    有最大对齐数(含嵌套结构体的对齐数)的整数倍。

⚠️注意:对齐数默认值在不同编译器下不相同,我们可以在文件的开头用#pragma pack(4)进行声明对齐数

内存对齐实际上能解决两个问题:

  1. 平台移植问题,不是所有硬件平台都能访问任意地址的任意数据
  2. 性能问题,如果不对齐,处理器可能需要两次访问内存而对齐后仅需要一次,以空间换时间

下面的结构体大小为12

struct S{
	int a; // 0 1 2 3 
	short b; //4 5 
	char c; // 6
	int d; // 7 浪费,8 9 10 11 
};

根据上面的规则进行运算:

  1. 首先第一个成员从偏移量0开始,占4个字节也就是 0,1,2,3
  2. 然后偏移量到4,判断short自身大小为2,对齐数是4,最小对齐数是2,偏移量4正好是2的整数倍,因此占两个字节4,5
  3. char占一个字节,偏移量目前为6,6是1的倍数,这里占1个字节 6
  4. 下一个int自身大小为4,对齐数为4,选择4,偏移量7不是4的整数倍因此偏移量浪费7,偏移量到8的时候对齐,占8,9,10,11
  5. 最后又规定结构体总大小为最大最齐数的整数倍,结构体总大小为12, 最大对齐数为4条件成立,因此结构体大小为12

3. 结构体位段

⚠️注意:位段和结构体类似,但位段的声明成员必须是int或 signed int,还有成员后面有一个冒号:和一个数字,也就是多少比特

举个例子

struct A{

    int __a__: 2;
    int __b__: 7;
    int __c__: 1;
    int __d__: 8;
    int __e__: 5;
};

int main(){

    struct A size = {0};
    size.__a__ = 5;
    size.__b__ = 4;
    size.__c__ = 10;
    size.__d__ = 12;
    size.__e__ = 8;

    //1 4 0 c 8
    printf("%2x %2x %2x %2x %2x  ", size.__a__, size.__b__, size.__c__, size.__d__, size.__e__);
    return 0;
}

二、联合体(共同体)

联合是一种特殊的自定义类型,和结构体不同的是这些成员共用一块空间,联合的大小至少是最大成员的大小,当最大成员大小不是最大对齐数的整数倍的时候,就需要对齐到最大对齐数的整数倍

union Un
{
	short s[7];
	int n;
};

这里的short本身大小为2,数组共14,int自身大小为4,所以这里的最大对齐数是14,又因为要最大成员int对齐到最大对齐数的整数倍那么就需要对齐到16,所以这里联合体大小为16

三、枚举

枚举就是列举,默认从0开始,依次增加

enum color{

	R, // 0
	G, // 1
	B, // 2
	Y= 255, // 255
	P  // 256
};

枚举的优点:
可以增加代码的可读性和维护性,尤其在case中
便于携带调试和使用方便,一次可以定义多个常量

创作不易,如果文章对你有帮助的话,留言、点赞、收藏牙牙:)

以上是关于C语言用例子一次性讲清楚结构体和联合体区别,xdm看过来!的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的结构体和共用体(联合体)

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

C和指针之结构体和联合体

C语言—联合体/共用体