sizeof的一点见解

sizeof的一点见解


其实在很多语言中都可以见到sizeof的影子,今天我只探讨sizeof在C语言中用法。
在C语言中sizeof是判断数据类型或者表达式的长度符,请记住sizeof不是一个函数,它是在编译时进行计算的。当然C99也支持在运行时计算。(本文中姑且认为在编译时计算),sizeof的返回值类型为size_t,返回的就是对象所占的内存字节数 。
1.先来看看sizeof在判断基本数据类型是的用法:
看如下的例子

	int a=1;
	char b=2;
	float c=2.50

sizeof(int)是4;sizeof(1)也是4;就是说在判断时sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。那么sizeof(char)和sizeof(b)和sizeof(2)是一样的。注意像int ,float,char,long等这些基本类型是和编译系统相关的,系统不一样它们的取值也是不一样的。
2.sizeof在数组中的用法:
例子如下

int  str[10];
char str1[]={"qwer"};

sizeof(str)是多少呢?答案是10*4=40;sizeof(str[1])是多少呢?答案是4;sizeof(str1)是多少呢?答案是5,因为str1是字符串,字符串末尾还有一个"\0"。如果要求一个数组的元素个数怎么办呢?可以这么做sizeof(str)/sizeof(str[0]),即用数组所占的内存长度除以它的第一个元素的长度。也可以用sizeof(str)/sizeof(int),即用数组所占的内存长度除以数组类型的长度。因为在数组中所有元素的类型一样。
但是在发生函数调用时,数组做形参时,它的长度就不是这样了
例子如下

int  creat(int a[5]){
	printf("%d",sizeof(a));
}
main(){
	int b[5]={1,2,3,4,5};
	creat(b);
}

运行后在屏幕上打印是多少呢?答案是4,为什么不是20呢?其实在这里a指的不是a[5]这个数组了,它指的是指针。在数组做函数形参时,当发生函数调用时实参只是把数组的首地址传递给形参数组,通过传递首地址形参就得到实参传递的数据了,他们指的是同一个数组,编译系统根本就没有给形参分配内存单元,即使是在发生函数调用时。当然在此例子中,结果就为4,得到的仅仅是指针所占的内存单元的大小,即为4.
3.sizeof在指针中的用法:
例子如下

char *p={"abcde"};
int a=2;
float b=3.1415;
int *q=&a;
float *r=&b;

sizeof§,sizeof(q),sizeof®分别是多少呢?答案是4,4,4;为什么呢?因为在这里指针变量的sizoef的值和指针变量所指的对象的类型没有任何关系,仅仅就是指针变量所占得内存,指针变量在32位的操作系统中占4个内存单元,所以为4.
4.sizeof在结构体中的应用:
例子如下

struct create{
       char a;
       int b;}a={'q',20};
		
main(){
	printf("%d %d",sizeof(struct create));
	getch();
}

运行结果为8,为什么不是5呢?这就涉及到了字节对齐,字节对齐有助于加快计算机的取数速度,要不然就要花费指令周期(计算机组成原理有介绍到)。字节对齐具体细节与编译器的实现相关,但是总满足以下三个原则:

  • 结构体首地址能够被其最宽的基本数据类型成员大小所整除。
  • 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,所以在需要的情况下会在成员之间加填充字节。
  • 结构体的总大小为结构体最宽基本成员大小的整数倍。所以在需要的情况下会在结构体末尾加填充字节。
    我们通过sizeof得到的结构体大小是 满足以上三个条件的情况下得到的,但在使用时只需要直接使用,不需要管它是怎么得到了,只是明白对结构体求所占内存大小时不是简单的成员大小相加就行了。

注释:
1.文中参考了百度百科中的一点内容
2.本文中例子中的代码都是在visual studio 2010中检测得出的结果,这些结果不是绝对的,有时还受编译器的具体实现影响。

猜你喜欢

转载自blog.csdn.net/clever_programmer/article/details/86715972