结构体的内存结构以及位域的认识
来源:互联网 发布:软件项目 文档 编辑:程序博客网 时间:2024/05/17 08:38
内存对齐:
内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。
内存对其原因:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
内存对齐的规定:
1.数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员自身大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐数。
2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
3.结构体成员相对首地址偏移量必须是成员大小的整数倍,也就是内存对齐。
4.结构体总大小必须是对齐模数的整数倍,举个例子,你最后加出来的值为30,但是你得对齐模数是8,这时候你就要补充两个字节,让结构体大小为32.
5.结构体的对齐模数其实还是自定义的 具体的格式就是我这样:
#pragma back(需要的对其模数)
对齐方式按照宏的定义来,比如在结构体前加#pragma pack(1),内存的布局就会完全改变,
有了#pragma pack(1),内存不会再遵循以上原则,按1字节对齐。
下表是常见类型的对齐模数:
例:struct A{
int a;
double b;
float c;
};
struct B{
char e[2];
int f;
double g;
short h;
struct A i;
};
sizeof(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
sizeof(B) = 48;
位域:
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
利用new运算符开辟空间时,调用构造函数;静态成员为类的每个成员所共有;
#include<iostream>
using namespace std;
class Sum
{
public:
Sum()//1.非静态成员函数内可以使用静态成员变量,调用静态成员函数
{
_n++;
_sum+=_n;
}
static int sum()
{
return _sum;
}
private:
int c;
static int _n;
static int _sum;
};
//2.类的静态成员必须要在类外进行初始化 [类型 类名::变量名=初始值]
int Sum::_n=0;
int Sum::_sum=0;
int main()
{
Sum* s=new Sum[100];
cout<<Sum::sum()<<endl;
delete[] s;
return 0;
}
实现一个Add函数,让两个数相加,但是不能使用+、-、*、/等四则运算符。ps:也不能用++、--等
#include <iostream>
#include <Windows.h>
using namespace std;
int Add(int& num1,
int& num2)
{
if (num1 == 0)
{
return num2;
}
if (num2 == 0)
{
return num1;
}
if (num1 == 0 && num2 == 0)
{
return 0;
}
int yyr = num1^num2;
int tty = (num1&num2) << 1;
return Add(yyr, tty);
}
int main()
{
int num1 = 6;
int num2 = 6660;
int ggy = Add(num1, num2);
cout <<"两个数的为和:"<< ggy << endl;
system("pause");
return 0;
}
- 结构体的内存结构以及位域的认识
- C语言结构体中的内存对齐以及位域和位域的应用
- 对结构体及位段的认识
- sizeof(结构体)和内存对齐以及位域
- 结构体的内存对齐问题与位域
- 结构体的内存对齐问题与位域
- 结构体的位域
- 结构体,联合的位域定义方法,以及结构体大小的计算
- 项目的结构,以及认识目标
- 结构体的基本认识
- 结构体、联合体和位断的内存对齐问题
- 结构体的内存对齐和位段
- 三层结构的认识
- 位域结构体的sizeof
- 结构体与位域的对齐
- 带有位域的结构体对齐
- c语言的位域结构体
- 结构体与位域的对齐:
- node.js window10上安装出现错误-“系统无法访问设备或文件error code 2755“
- 羊皮卷之二
- PAT 乙级 1037. 在霍格沃茨找零钱(20)
- ftp图片服务器搭建!ftp上传到图片服务器,通过http协议读取图片
- node.js学习之输出Hello World
- 结构体的内存结构以及位域的认识
- 面试题总结 —— JAVA高级工程师
- python实现翻转给定列表中的元素
- Windows核心编程之DLL基础
- B
- 化学品问题 oj137
- 当U盘启动时,出现grub>如果将启动项引导到硬盘?
- (一)maven 安装配置
- 算法学习资料