C语言深入回顾讲解结构体对齐

 更新时间:2022年06月01日 10:41:18   作者:Bright-SKY  
C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许你存储不同类型的数据项,本篇让我们来了解C 的结构体内存对齐

结构体对齐问题

1、知识点的引入:

struct data1
{
    char a;//1B
    int b;//4B
};
void test01()
{
    printf("%d\n",sizeof(struct data1));//8B 为啥?
}

2、对齐规则(默认对齐)

第一步:确定分配单位(每行开辟多少字节)

结构体中最大的基本类型的长度 为分配单位。

第二步:确定成员的偏移位置。

偏移位置:成员自身类型的整数倍(0~n倍)

第三步:收尾工作:

结构体的总大小必须是分配单位的整数倍

struct data
{
	char c;//1B
	int i;//4B
};
void test05()
{
	struct data d;
	//结构体的大小 >= 成员大小之和
	printf("%d\n",sizeof(struct data));//8
	printf("&d.c = %u\n",&d.c );
	printf("&d.i = %u\n",&d.i );
}

运行结果:

案例:

typedef struct
{
	int a;
	char b;
	short c;
	char d;
}DATA;
void test06()
{
	DATA d;
	printf("%d\n", sizeof(DATA));
	printf("%u\n", &d.a);
	printf("%u\n", &d.b);
	printf("%u\n", &d.c);
	printf("%u\n", &d.d);
}

案例1:

struct data1
{
    char a;//1B
    int b;//4B
};

案例2:

struct data2
{
    char a;
    short b;
    char c;
    int d;
};

案例3:

struct data2
{
    char a;
    short b;
    short c;
    char d;
};

案例4:

struct data2
{
    char a[7];
    short b;
    int c;
};

结构体嵌套结构体

第一步:确定分配单位(每行开辟多少字节)

所有结构体中最大的基本类型的长度 为分配单位。

第二步:确定成员的偏移位置。

普通成员偏移位置:成员自身类型的整数倍(0~n倍)

结构体成员的偏移量:该结构体的最大基本类型的整数倍

第三步:收尾工作:

结构体成员:是该结构体的最大基本类型整数倍。

结构体的总大小必须是分配单位的整数倍

案例:

typedef struct
{
	short d;
	char e;
}DATA2;
typedef struct
{
	short a;
	int b;
	DATA2 c;
	char f;
}DATA;
void test08()
{
	DATA data;
	printf("%d\n",sizeof(DATA));
	printf("a:%u\n", &data.a);
	printf("b:%u\n", &data.b);
	printf("c中d:%u\n",&data.c.d);
	printf("c中e:%u\n",&data.c.e);
	printf("f:%u\n",&data.f);
}

案例:

typedef struct
{
	char a;
	int b;
	short c;
}DATA;
void test10()
{
	DATA data={'a',100, 20};
	char *p = &data;
	printf("c = %hd\n", data.c);
	//需求 借助p访问20
	printf("c = %hd\n", *(short *)(p+8));
}

运行结果:

案例:

struct A
{
    char b;
    short c;
};
struct B
{
    int a;
    struct A ob;//结构体成员的偏移量
    int d;
};

案例1:

struct A
{
    short b;
    char c;
};
struct B
{
    int f;
    char a;
    struct A ob;//结构体成员的偏移量
    char d;
};

强制内存对齐

#pragma pack (value)时的指定对齐值value

第一步:确定分配单位(每行开辟多少字节)

min(value,最大的基本类型的长度) 为分配单位。

第二步:确定成员的偏移位置。

偏移位置:成员自身类型的整数倍(0~n倍)

第三步:收尾工作:

结构体的总大小必须是分配单位的整数倍

#include <stdio.h>
#include<stdio.h>
#pragma pack (4)
struct stu
{
    char a;
    short b;
    short c;
};
void test01()
{
    printf("%d\n",sizeof(struct stu));//6
}

注意事项:

拓展求结构体成员的偏移量

struct stu1
{
    char a;
    int b;
    char c;
    int d;
};

#include <stdio.h>
#include<stdio.h>
struct stu1
{
    char a;
    int b;
    char c;
    int d;
};
#define  OFF_SET(TYPE, member) (int)&(((TYPE *)0)->member)
void test01()
{
    struct stu1 data;
    printf("偏移量:%d\n",   OFF_SET(struct stu1, b) );//8
}

到此这篇关于C语言深入回顾讲解结构体对齐的文章就介绍到这了,更多相关C语言结构体对齐内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 从汇编看c++中默认构造函数的使用分析

    从汇编看c++中默认构造函数的使用分析

    c++中,如果为一个类没有明确定义一个构造函数,那么,编译器就会自动合成一个默认的构造函数。下面,通过汇编程序,来看一下其真实情况
    2013-05-05
  • c语言中形参与实参的关系解读

    c语言中形参与实参的关系解读

    这篇文章主要介绍了c语言中形参与实参的关系,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • C语言链表实现通讯录系统课程设计

    C语言链表实现通讯录系统课程设计

    这篇文章主要为大家详细介绍了C语言链表实现通讯录系统课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++ LeetCode1775通过最少操作次数使数组和相等

    C++ LeetCode1775通过最少操作次数使数组和相等

    这篇文章主要为大家介绍了C++ LeetCode1775通过最少操作次数使数组和相等,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Ubuntu18.04下QT开发Android无法连接设备问题解决实现

    Ubuntu18.04下QT开发Android无法连接设备问题解决实现

    本文主要介绍了Ubuntu18.04下QT开发Android无法连接设备问题解决实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++多继承同名隐藏实例详细介绍

    C++多继承同名隐藏实例详细介绍

    多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类..本文将对C++多继承同名隐藏实例进行分析
    2012-11-11
  • C语言创建数组实现函数init,empty,reverse

    C语言创建数组实现函数init,empty,reverse

    这篇文章主要介绍了C语言创建数组实现函数init,empty,reverse,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • C++进程的创建和进程ID标识详细介绍

    C++进程的创建和进程ID标识详细介绍

    传统的C++(C++98)中并没有引入线程这个概念。linux和unix操作系统的设计采用的是多进程,进程间的通信十分方便,同时进程之间互相有着独立的空间,不会污染其他进程的数据,天然的隔离性给程序的稳定性带来了很大的保障
    2022-08-08
  • C++实现LeetCode(642.设计搜索自动补全系统)

    C++实现LeetCode(642.设计搜索自动补全系统)

    这篇文章主要介绍了C++实现LeetCode(642.设计搜索自动补全系统),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • VC++的combobox控件用法汇总

    VC++的combobox控件用法汇总

    这篇文章主要介绍了VC++的combobox控件用法,对VC++初学者来说尤为重要,需要的朋友可以参考下
    2014-08-08

最新评论