关于sizeof的一些理解

#include <stdio.h>
int main(void)
{
	struct stu
	{
	        int i;//4
		int a;//4
		char f;//8
		double q;//8
		float y;//4
	}s;
	struct std
	{
		int z;
		struct stu k;
		char o;
	}v; 
	printf("%d\n", sizeof(s));
	printf("%d\n", sizeof(stu));
	printf("%d\n", sizeof(v));
	printf("%d\n", sizeof(std));
	printf("%d\n", sizeof(v.k));
	//printf("%d\n", sizeof(s.f));
	return 0;
}
 
分析:结构体里面,两个变量比较,永远是前者跟后者比,然后取两者最大的字节给前者。 

所以求stu所占字节:

i跟a是一样大,i还是4。 

a比f大,a还是4。

然后f比q小,所以f变成了8。填充7个字节。 

然后q比y大,q还是8。

最后y没办法跟谁比较了,就当做跟空气比较吧,所以y不变,是4。 

最后加起来就是28。

但是还有个原则,就是结果一定要是最宽字节的倍数,这里最宽的是8.

所以Y后面还要填充4个字节。

这样stu整体就是32。 

求std所占字节:

如果是结构体里面再接结构体,则判断最宽字节8的时候要拆开这个内嵌的结构体,找里面的最宽字节,这里是8。

而在前者跟后者比较的时候,也要拆开,以结构体里面最宽的字节8为基准

最后加起来的时候,就要把结构体当成整体加起来了 8+32+1=41,化为8的倍数所以是48. 

下面是一些参考资料:

#include<stdio.h>
int main(void)
{ 
	int x[10];
	int y=1;
	short int i = 2;
	double f = 3;
	char a1[] = "abc";
	printf("%d\n",sizeof(a1));//字符末尾还存在一个NULL终止符
	printf("%d\n",sizeof(x)/sizeof(int));//总长度/单个元素的长度,输出x数组的元素个数,此程序输出10。
	printf("%d\n",sizeof(x)/sizeof(x[0]));//总长度/第一个元素的长度 int型
	printf("%d\n",sizeof(int));
	printf("%d\n",sizeof(x));
	printf("%d\n",sizeof(i));
	printf("%d\n",sizeof(y==2?i:f));
	//对象可以进一步延伸至表达式,即sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。
	//而sizeof很牛逼,最终值被强制转换为表达式里面的占最大字节的类型。虽然结果值是i,但是此时的i已经是double类型了。 
	return 0;
}

sizeof是计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示(当然用在字符数组计算"\0"的大小)。

在32位的系统中,sizeof(int)的值为4.

如果x是int型的数组,则sizeof(x)/sizeof(int)代表x的位数。

sizeof有三种语法形式,如下:

sizeof(object);//sizeof(对象);

sizeof(type_name);//sizeof(类型);

sizeofobject;//sizeof对象;

所以

int i;
sizeof(i);//ok
sizeof(int);//ok
<pre name="code" class="cpp">sizeof i;//ok
sizeofint;//error
 

既然写法3可以用写法1代替,为求形式统一以及减少我们大脑的负担,第3种写法,忘掉它吧!

实际上,sizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。

这里,对象可以进一步延伸至表达式,即sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。

如:

sizeof(2);//2的类型为int,所以等价于sizeof(int);

sizeof(2+3.14);//3.14的类型为double,2也会被提升成double类型,所以等价于sizeof(double);

sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,我们来看一个完整的例子:

char foo()
{
<span style="white-space:pre">	</span>printf("foo() has been called.\n");
<span style="white-space:pre">	</span>return 'a';
}
int main(void)
{
<span style="white-space:pre">	</span>size_tsz = sizeof(foo());
<span style="white-space:pre">	</span>//foo()的返回值类型为char,所以sz=sizeof(char),foo()并不会被调用
<span style="white-space:pre">	</span>printf("sizeof(foo())=%d\n",sz);
}

C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的:

sizeof(foo);//error
void foo2(){}
sizeof(foo2());//error
struct S
{
<span style="white-space:pre">	</span>unsigned int f1:1;
<span style="white-space:pre">	</span>unsigned int f2:5;
<span style="white-space:pre">	</span>unsigned int f3:12;
};
sizeof(S.f1);//error

所以在32位计算机中,一个指针变量的返回值必定是4字节,但是,在64位系统中指针变量的sizeof结果为8。
char *pc = "abc";
int *pi;
string *ps;
char **ppc = &pc;
void(*pf){};//函数指针
sizeof(pc);//结果为4
sizeof(pi);//结果为4
sizeof(ps);//结果为4
sizeof(ppc);//结果为4
sizeof(pf);//结果为4

void foo3(char a3[3])
{
<span style="white-space:pre">	</span>intc3 = sizeof(a3);//c3==?
}
void foo4(char a4[])
{
<span style="white-space:pre">	</span>intc4 = sizeof(a4);//c4==?
}

也许当你试图回答c4的值时已经意识到c3答错了,是的,c3!=3。

这里函数参数a3已不再是数组类型,而是蜕变成指针,相当于char* a3

仔细想想就不难明白,我们调用函数foo3时,程序会在栈上分配一个大小为3的数组吗.不会!

数组是“传址”的,调用者只需将实参的地址传递过去,所以a3自然为指针类型(char*),c3的值也就为4。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值