今天项目闲暇之余,突然想起来找工作的面试题目关于字节对齐方式和位域的问题,特意总结一下,给即将找工作和已经工作的人一个参考,同时也方便自己查阅,时间久了不用是很容易忘掉的!!!主要是通过代码和图解的方法,使大家更易理解
一,结构体中的字节对齐方式
在结构体中,编译器为结构的每个成员按其自然边界分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。为了便于cpu快速访问,同时节省存储空间,引入了字节对齐的概念。默认的字节对齐主要是参照处理器的类型和编译器的类型。在32为的机器下面,一般以4字节对齐,同时在vc中默认是4字节对齐的,GNU gcc 也是默认4字节对齐。如何更改字节的对齐方式,提高数据的读写性能呢?
主要有两种方式盖面字节的对齐方式:
· 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
· 使用伪指令#pragma pack (),取消自定义字节对齐方式。
另外,还有如下的一种方式:
· __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
· __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。(注意attribute的前后均是是两个下划线)
整个数据结构对齐的规则如下:
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float其自身对齐值为4,double为8个字节单位字节。
2.指定对齐值:#pragma pack (value)时的指定对齐值value。
3.数据成员对齐值为自身对齐值和指定对齐值中小的那个值,
4.在满足上面情况下,结构体和类的有效对齐值为指定对齐值的整数倍
// struct_bit.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #pragma pack(1) struct stu { char name[2]; int num; short score; double score1; char name1; }student; #pragma pack() #pragma pack(2) struct stu1 { char name; double score1; int num; short score; char n; char m; }student1; #pragma pack() int _tmain(int argc, _TCHAR* argv[]) { printf("stu zi jie shu is %d\n",sizeof(char)); printf("stu zi jie shu is %d\n",sizeof(int)); printf("stu zi jie shu is %d\n",sizeof(short)); printf("stu zi jie shu is %d\n",sizeof(double)); printf("stu zi jie shu is %d\n",sizeof(student)); printf("student.name address is %p\n",&(student.name)); printf("student.num address is %p\n",&(student.num)); printf("student.score address is %p\n",&(student.score)); printf("student.score1 address is %p\n",&(student.score1)); printf("stu zi jie shu is %d\n",sizeof(student1)); printf("student1.name address is %p\n",&(student1.name)); printf("student1.score1 address is %p\n",&(student1.score1)); printf("student1.num address is %p\n",&(student1.num)); printf("student1.score address is %p\n",&(student1.score)); printf("student1.m address is %p\n",&(student1.m)); return 0; }
从以上的测试结果可以看出,可以计算出字节对齐的规则。如有什么问题欢迎给我留言,大家一起探讨。转载请注明出处,谢谢!!!!!