可能有不少读者会问,字节对齐有必要拿出来单独写一篇博客嘛?我觉得是很有必要,但是它却是被很多人所忽视的一个重点。那么我们使用字节对齐的作用和原因是什么呢?由于硬件平台之间对存储空间的处理上是有很大不同的,一些平台对某些特定类型的数据只能从某些特定地址开始存取,如通常有些架构的CPU要求在编程时必须保证字节对齐,否则访问一个没有进行字节对齐的变量的时候会发生错误。而有些平台可能没有这种情况,但是通常的情况是如果我们编程的时候不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如我们操作一个int型数据,如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,两个周期读取出来的字节我们还要对它们进行高低字节的拼凑才能得到该int型数据,从而使得我们的读取效率较低,这也从侧面反映出了一个问题,就是我们很多时候是在牺牲空间来节省时间的。
可能看了上面的讲解你还是不太明白,那我们再来看一次什么是字节对齐呢? 我们现在的计算机中内存空间都是按照字节来进行划分的,从理论上来讲的话似乎对任何类型的变量的访问可以从任何地址开始,然而值得注意的就是,实际情况下在访问特定变量的时候经常在特定的内存地址访问,从而就需要各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
按照预先的计划安排,这次应该是写《C语言的那些小秘密之链表(三)》的,但是我发现如果直接开始讲解linux内核链表的话,可能有些地方如果我们不在此做一个适当的讲解的话,有的读者看起来可能难以理解,所以就把字节对齐挑出来另写一篇博客,我在此尽可能的讲解完关于字节对齐的内容,希望我的讲解对你有所帮助。
在此之前我们不得不提的一个操作符就是sizeof,其作用就是返回一个对象或者类型所占的内存字节数。我们为什么不在此称之为sizeof()函数呢?看看下面一段代码:
|
这段代码在linux环境下我采用gcc编译是没有任何问题的,对于void类型,其长度为1,但是如果我们在vc6下面运行的话话就会出现illegal sizeof operand错误,所以我们称之为操作符更加的准确些,既然是操作符,那么我们来看看它的几种使用方式:
1、sizeof( object ); // sizeof( 对象 );
2、 sizeof( type_name ); // sizeof( 类型 );
3、sizeof object; // sizeof 对象; 通常这种写法我们在代码中都不会使用,所以很少见到。
下面来看段代码加深下印象:
|
运行结果为:
|