首页
IT
登录
6mi
u
盘
搜
搜 索
IT
sizeof()解析
sizeof()解析
xiaoxiao
2021-03-25
184
最近发现,许多公司笔试题都有考查sizeof()的用法,所以借此机会,自己学习一下,做以总结。
sizeof是运算符,可用于任何变量名、类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号。
sizeof有两种用法:
(1)sizeof(object)或sizeof object
也就是对对象使用sizeof
(2)sizeof(typename)
也就是对类型使用sizeof,注意这种情况下写成sizeof typename是非法的
1.我们需要注意的是sizeof在编译时起作用,而不是运行时。所以sizeof不编译括号内的内容。sizeof在大多数情况下是编译时定值的,表达式中的任何副作用(包括有副作用的运算符、函数调用等)都不会发生。
例如:
(深圳长城科技股份有限公司的一道笔试题)
void main()
{
int i,j;
i=3;
j=sizeof((++i)+(++i));
printf("i=%d,j=%d\n",i,j);
}
运行结果:i=3,j=4
2.再看一个典型的例子:
cout<<sizeof(int)<<endl; //4 32位机上int长度为4
cout<<sizeof(1==0)<<endl; //4 ==操作符返回bool类型,长度为1,
//相当于cout<<sizeof(bool)<<endl;
printf("%d\n",sizeof(int));//4 int长度
printf("%d\n",sizeof(1==0));//4
C语言中并没有bool类型,sizeof(1==0)的结果是int型的大小
那如果我们写一个下面这样的程序,运行结果是怎样的呢?
short m;
int n;
double dn;
char c;
int j=sizeof(m+n);
int k=sizeof(n+n);
int l=sizeof(m);
int l2=sizeof(m*m);
int l3=sizeof(m+dn);
int l4=sizeof(m+m);
int l5=sizeof(dn+dn);
int l6=sizeof(dn*dn);
int l7=sizeof(c+c);
int l8=sizeof(c);
printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",j,k,l,l2,l3,l4,l5,l6,l7,l8);
运行结果为:4,4,2,4,8,4,8,8,4,1
原因是这里面有隐式类型转换。
转换规则:(低级—>高级)
3.指针
sizeof对任意类型的指针结果均为4
。
c++中一个常见例子:
char *str=new str[10];
cout<<sizeof(str)<<endl; //4 str为一个动态数组,但还是一个指针
4.数组举例
char str1[]="12\0345";
char str2[]="abc\0de";
char str3[20];
int data4[10];
printf("sizeof(str1)=%d\n",sizeof(str1)); //5
因为编译器认为
‘\034’,为一个字符,为八进制表示。所以,一共有
‘1’、‘2’、‘\034’、‘5’
这四个字符,但由于字符串会自动在末尾加上‘\0’,所以sizeof结果为5
printf("sizeof(str2)=%d\n",sizeof(str2)); //7
'\0'为一个字符。所以同上有sizeof结果为7
printf("sizeof(str3)=%d\n",sizeof(str3)); //20
printf("sizeof(str4)=%d\n",sizeof(str4));//40即10*sizeof(int)
5.共用体
联合体的大小
1、按最大的计算。
2、是所有类型大小的整数倍。
union un1
{
int a;
char b;
double c;
}u1;
union un2
{
char a[9];
double b;
}u2;
union un3
{
char a[13];
int b;
}
printf("sizeof(u1)=%d\n",sizeof(u1));
printf("sizeof(u2)=%d\n",sizeof(u2));
printf("sizeof(u3)=%d\n",sizeof(u3));
在VC下编译结果为;
sizeof(u1)=8
sizeof(u2)=16
sizeof(u3)=16
而在GCC编译器中结果为:
sizeof(u1)=8
sizeof(u2)=12
sizeof(u3)=16
这是为什么呢,按理说,u2中最大成员为9个字节,但是由于union遵循内存对齐,所以要为double的整数倍,故VC下sizeof(u2)=16,而在GUN GCC编译器中,遵循的准则有些区别,对齐模数不是像上面所述的那样,根据最宽的基本数据类型来定。
在GCC中,对齐模数的准则是:对齐模数最大只能是4,也就是说,即使共用体中有double类型,对齐模数还是4,所以结果为12。(
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常是4或8)的倍数,这就是所谓的内存对齐,而这个k则是被称为该数据类型的对齐模数
)。
6.结构体
struct su1
{
char a; //1
char b[9]; //9
int c; //4
double d; //8
}s1;
struct su2
{
char a;
double b;
char c[9];
int d;
}s2;
printf("sizeof(s1)=%d\n",sizeof(s1));
printf("sizeof(s2)=%d\n",sizeof(s2));
在VC下编译结果为;
sizeof(s1)=24
sizeof(s2)=32
而在GCC编译器中结果为:
sizeof(s1)=24
sizeof(s2)=28
在VC下 s1:1+9=10,根据内存对齐,与int类型对齐应该为4的倍数所以为12,然后加上4,结果为16。
在更具内存对齐,与double类型对齐应该为8的倍数,16刚好是8的倍数所以不用添加,然后再 加上8,结果为24。
s2:因为下个成员b为double类型,所以a要内存对齐为8,8+8=16,下个成员是char类型性,
所以16与1对齐不变化,16+9=25,下个成员是int要与4对齐,所以25+3=28,最后28+4=32。
在GCC下s1: 1+9+4=14,根据内存对齐,应该为4的倍数所以为16,然后加上8,结果为24。
s2:GCC下对齐模数最大只能是4,所以4+8+9+4=25,填充补齐为28
。
转载请注明原文地址: https://ju.6miu.com/read-22430.html
技术
最新回复
(
0
)