sizeof()解析

    xiaoxiao2021-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)