sizeof()解析

 最近发现,许多公司笔试题都有考查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
原因是这里面有隐式类型转换。
转换规则:(低级—>高级)
sizeof()解析

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值