C语言学习笔记:sizeof详解

一、Sizeof的说明

sizeof是C/C++语言的一种单目操作符,它不是函数。sizeof操作符返回值为其操作数的存储大小,用字节数表示。操作数可以是一个表达式或括在括号内的类型名。 sizeof的结果是size_t,它被定义为unsigned int类型。该类型保证容纳显示所建立的最大对象的字节大小。

  • static变量在静态区,sizeof均不纳入计算
  • 在编译阶段处理,sizeof作用范围内的内容不能被编译,所以sizeof()内的运算不被执行
  • sizeof(函数)=sizeof(返回值类型)
  • sizeof和strlen:sizeof计算字符串容量,算’\0’,strlen计算字符串长度,到’\0’截止
  • 类:非static数据成员变量+虚函数指针+对齐;无论多少个虚函数,都只有一个指向虚函数表的指针(4字节)
  • 联合体:最长成员的大小对齐
  • 带位域:相邻位域字段的两个变量若类型相同,当两个字段位宽和小于此类型大小时,二者紧邻存储;若二者位宽和大于本类型大小,则第二个字段从新存储单元开始,偏移量为其类型大小整数倍。若相邻位域字段类型不同,则视编译器决定是否压缩存储,VC6不压缩,Dec-C++压缩。如果位域字段间穿插着非位域字段,不压缩。
  • 数组:数组占内存字节=元素个数*元素长度; 当数组作为函数参数传递时,蜕变成指针

需牢记sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,且会忽略其括号内的各种运算。

二、Sizeof的使用

 1、sizeof的使用形式:sizeof(var_name)或者sizeof var_name

 2、数据类型必须用括号括起来:sizeof(type)

变量、对象可以不用括号括住:sizeof a,但若是类型必须用括号

 3、sizeof可以对表达式求值:sizeof(2.5+3.14),实际是sizeof(double)

 4、sizeof可以对函数调用求值,实际上是对返回值类型求值

 int func(char s[5]);
 {
 cout<<endl;
 return 1;
 }
sizeof(func(“1234”))=4 //因为func的返回类型为int,所以相当于求sizeof(int)=4,sizeof(s)=4

 5、以下情况不能用sizeof进行求值

1)不能对函数名求值

2)不能对不确定返回值的类型求值,如void

3)位域成员不可以使用sizeof求值

4)不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

一般,在32位编译器下:

sizeof(char):1  

sizeof(short):2

sizeof(int):4

sizeof(long):4

sizeof(float):4

sizeof(double):8

sizeof(long long):8

sizeof(p):4,(p为指针)

32位系统下指针的sizeof是4字节,64位下是8字节

6.指针与静态数组的sizeof操作
      1) 指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。
        注意: int *p; sizeof(p)=4;(32位系统下始终不变)sizeof(*p)相当于sizeof(int),随着数据类型的改变而改变;     
      2) 对于静态数组,sizeof可直接计算数组大小;当数组动态分配时,int *a = new int[10]; sizeof = 4。
         例: int a[10];char b[]="hello";
                sizeof(a)等于4*10=40;
                sizeof(b)等于6;
          注意:数组做形参时,数组名称当作指针使用!!
               void  fun(char p[]) {sizeof(p)等于4}
如下程序:

#include <stdio.h>
void func(char p[])
{
    printf("in func args,p[] size %d\n", sizeof(p));
}
int main()
{
    int *p;
    int a[10];
    char b[] = "hello";
 
    printf("*p size %d\n", sizeof(p));
    printf("a[10] size %d\n", sizeof(a));
    printf("\"hello\" size %d\n", sizeof(b));
    func(b);
    return 0;
}


输出结果:*p size 4
               a[10] size 40
               "hello" size 6
               in func args,p[] size 4


经典问题:

//double* (*a)[3][6];
#include <stdio.h>
int main()
{
    double *(*a)[3][6];
    printf("        a size %4d\n",sizeof(      a));// 4 a为指针
    printf("      *a size %4d\n",sizeof(    *a));// 72 *a为一个有3*6个指针元素的数组
    printf("    **a size %4d\n",sizeof(   **a));// 24 **a为数组一维的6个指针
    printf("  ***a size %4d\n",sizeof(  ***a));// 4 ***a为一维的第一个指针
    printf("****a size %4d\n",sizeof(****a));// 8 ****a为一个double变量
    return 0;
}

问题解析:

  • a是一个很奇怪的定义,他表示一个指向 double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。
  • *a就表示一个元素为double*、大小为[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。
  • **a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof(double*)=24。
  • ***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。
  • ****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。


7、sizeof与strlen()比较,在计算字符数组大小时,sizeof包含'\0',strlen()不包含'\0',strlen()遇到’\0’就会返回

char c1[ ]={‘c’,‘ ’,‘p’,‘r’,‘o','g','r','a','m'};
char c2[ ]={‘c’,‘ ’,‘p’,‘r’,‘o','g','r','a','m','\0'};
strlen(c1)未定义,strlen(c2)=9;

sizeof(c1)=9,sizeof(c2)=10

注意,sizeof("\0")=2

8、对引用的sizeof,其实是对其所绑定的对象的sizeof

9、对于C字符串,需要牢记C/C++中一个汉字占两个字节(Linux下3个字节),且字符串尾有空字符。

使用伪指令#pragma pack(n),编译器将按照n个字节对齐;

使用伪指令#pragma pack(n),将取消自定字节对齐方式。

10、 sizeof的参数为结构或类时,有两点需要注意:

第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。

第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。

还有结构体或者类中有虚函数的,大小会加4个字节,因为有虚函数表的指针。

Class Test{int a;static doublec};//sizeof(Test)=4.
Test *s;//sizeof(s)=4,s为一个指针。

Class test1{ };//sizeof(test1)=1;

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值