#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。