C语言其实是一门很简单的学科,但是也是一门很神秘的学科,各类代码拼接到一起就能实现各种各样的功能。我们知道,由于硬件平台之间对存储空间的处理上是有很大不同的,一些平台对某些特定类型的数据只能从某些特定地址开始存取,如通常有些架构的CPU要求在编程时必须保证字节对齐,否则访问一个没有进行字节对齐的变量的时候会发生错误。
然而,有些平台可能没有上述的情况,但是通常的情况是如果我们编程的时候不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如我们操作一个int型数据,如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,两个周期读取出来的字节我们还要对它们进行高低字节的拼凑才能得到该int型数据,从而使得我们的读取效率较低,这也从侧面反映出了一个问题,就是我们很多时候是在牺牲空间来节省时间的。
可能通过上面的讲解您还是不太明白C语言,那我们再来看一下什么是字节对齐呢?我们现在的计算机中内存空间都是按照字节来进行划分的,从理论上来讲的话似乎对任何类型的变量的访问可以从任何地址开始,然而值得注意的就是,实际情况下在访问特定变量的时候经常在特定的内存地址访问,从而就需要各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
在此之前,不得不提的一个操作符就是sizeof,其作用就是返回一个对象或者类型所占的内存字节数。我们为什么不在此称之为sizeof()函数呢?看看下面一段代码:
[html] view plaincopy#include
void print()
{
printf("hello world!\n");
return ;
}
void main()
{
printf("%d\n",sizeof(print()));
return ;
}
这段代码在linux环境下我采用gcc编译是没有任何问题的,对于void类型,其长度为1,但是如果我们在vc6下面运行的话话就会出现illegal sizeof operand错误,所以我们称之为操作符更加的准确些,既然是操作符,那么我们来看看它的几种使用方式:
1、sizeof( object ); // sizeof( 对象 );
2、 sizeof( type_name ); // sizeof( 类型 );
3、sizeof object; // sizeof 对象; 通常这种写法我们在代码中都不会使用,所以很少见到。
下面来看段代码加深下印象:
[html] view plaincopy#include
void main()
{
int i;
printf("sizeof(i):\t%d\n",sizeof(i));
printf("sizeof(4):\t%d\n",sizeof(4));
printf("sizeof(4+2.5):\t%d\n",sizeof(4+2.5));
printf("sizeof(int):\t%d\n",sizeof(int));
printf("sizeof 5:\t%d\n",sizeof 5);
return ;
}
运行结果为:
[html] view plaincopysizeof(i): 4
sizeof(4): 4
sizeof(4+2.5): 8
sizeof(int): 4
sizeof 5: 4
Press any key to continue
从运行结果我们可以看出上面的几种使用方式,实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一样的。从给出的代码中我们也可以看出sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,但是一般不会对表达式进行计算或者当表达式为函数时并不执行函数体。如:
[html] view plaincopy#include
int print()
{
printf("Hello bigloomy!");
return 0;
}
void main()
{
printf("sizeof(print()):\t%d\n",sizeof(print()));
return ;
}
运行结果为:
[html] view plaincopysizeof(print()): 4
Press any key to continue