您的位置:首页 > 其它

sizeof与strlen区别

2017-08-06 18:23 155 查看
1.本质上sizeof()是运算符,strlen是函数。

2.参数上,strlen只接收char*形参,sizeof()可以接受指针、数组名、结构体、类等多种形参。

3.sizeof在编译时确定,而strlen需要再运行才能计算确定。

4.sizeof()计算的是在编译时就确定的对象占据内存的大小,而strlen计算的是在运行时对象实际占据的大小,一直计数直到碰到'\0';

5.因为字符串常量比如"abcde",因为编译器会在后面自动添加一个'\0',此时,sizeof计算占据的内存大小时会将这个'\0'也计算进去,而strlen不会。






sizeof,看起来还真不简单,总结起来还是一大堆的东西,不过这是笔试面试中出现比较频繁的,我也是考过才觉得很重要,有些规则如果不注意,还真是拿到一道题目摸不着头脑,所有总结一下,方面忘记的时候瞄一瞄,其中重点是struct的空间大小部分。

关于sizeof的总结

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

  2、变量名可以不用括号括住:sizeof a

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

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

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

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

      1)不能对函数名求值

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

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

  7、sizeof的结果是size_t,它被定义为unsigned int类型。该类型保证容纳显示所建立的最大对象的字节大小。

  一般,在32位编译器下:

      sizeof(int):4

      sizeof(short):2

      sizeof(long):4

      sizeof(long long):8

      sizeof(float):4

      sizeof(double):8

      sizeof(char):1

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

  在不同的系统中这些值不一样。

  8、sizeof与strlen()比较,在计算字符数组时,sizeof包含'\0',strlen()不包含'\0'

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

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

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

  12、对数组sizeof可以计算数组的大小

  13、数组作为形参时,数组名的sizeof是4个字节

  14、32bit系统中,int **a[3][4];sizeof(a)=48

  15、关于struct的空间计算

    很多公司喜欢在考察struct的空间计算,是的,我深有感受。

  struct的空间计算比较复杂,总体遵循两个规则:

      1)在windows32环境下,整体空间是占用空间最大的成员(的类型)所占字节的整数倍,在Linux+gcc环境下,若最大成员类型所占字节数超过4,如double是8,则整体空  间是4的整数倍即可。

      2)在windows32环境下,数据对其原则——内存结构体成员的先后顺序排列,当排到该成员变量时,其前面已经摆放的空间大小必须是该成员类型大小的整数倍,如果不够  则补齐,以此类推。但在Linux+gcc环境下,若成员类型超过4,如double是8,则前面已经摆放的空间大小是4的整数倍即可,不够则补全。

  win32环境下:在摆放时,思路是:

        1、首先把第一个成员放在地址为0的地方

        2、然后再根据第二个成员的类型大小寻找其摆放的起始位置,摆放起始位置必须是类型大小的整数倍,依次类推。

        3、最后,再计算整体空间是不是最大类型大小的整数倍。

  而在Linux+gcc环境下:摆放的思路是

        1、首先把第一个成员放在地址为0的地方

        2、如果一个单元装不下,则另放在一个单元地址的起始位置。

        3、最后,如果最大类型带下超过4,再计算整体空间是不是4的整数倍。

  16、含有结构体的结构体的空间计算:

        1)在windows32环境下,整体空间是子结构体与父结构体中,占用空间最大的成员(的类型)所占字节的整数倍,在Linux+gcc环境下,若最大成员类型所占字节数超过4,如  double是8,则整体空间是4的整数倍即可。

        2)在windows32环境下,数据对其原则——父结构体内存按照结构体成员的先后顺序排列,当排到子结构体成员时,其前面已经摆放的空间大小必须是该子结构体成员中最  大类型大小的整数倍,不够则补全,一次类推。

  win32环境下:在摆放时,思路是:

        1、首先把第一个成员放在地址为0的地方

        2、然后再根据第二个成员的类型大小寻找其摆放的起始位置,摆放起始位置必须是类型大小的整数倍,如果是子结构体,则寻找摆放的起始位置是子结构体中最大类型大小  的整数倍,依次类推。

        3、最后,再计算整体空间是不是父子结构体中最大类型大小的整数倍。

  Linux+gcc比较省内存,类型大小超过4,起始位置要是4的整数倍即可。

  17、含有数组的结构体的空间计算:

  在结构体中,数组是按照单个变量一个一个进行摆放,而不是视为整体,故包含数组的结构体对齐的方式比较特殊。

  如:

  struct S1

  {

      char a[8];

      int b;

  };

  sizeof(S1)=12,而不是16。

  18、含位域结构体的计算

  位域成员不能单独被去sizeof值,但是含有位域的结构体可以。

  使用位域有如下规则:

      1)如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前面一个字段的存储,知道不能容纳为止。

      在vs2010下,一个int a:4,如果后面不是位域,则占4个字节,即其类型的大小。而在Dec-C++与gcc下,无论是不是位域,所占字节数以其实际占用字节数为准,即int   a:4,如果后面不是位域,仅占一个字节。

      2)如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍。

      3)如果相邻位域字段的类型不同,不同编译器的具体实现有差异,VC6不采取压缩,而Dec-C++与gcc采用压缩。

      4)如果位域字段之间穿插着非位域字段,则不进行压缩。

      5)整体结构体的总大小为最快基本类型成员大小的整数倍。
  19、使用"#pragma pack"时结构体空间计算

  一般可以通过下面的方法来改变默认条件的对其条件:

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

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

  以上两种指令通常应该搭配使用。

  #pragma pack(n),n为字节对齐数,其取值为1、2、4、8、16等,默认是8,如果这个值比结构体的sizeof值小,那该成员的偏移量应该以此为准,即结构体成员的偏移量应  该取二者的最小值。公式如下:

  offsetof(item)=min(n,sizeof(item))

  20、union的空间计算

  联合体的sizeof值是所有成员sizeof的最大值。

  21、枚举的空间计算

  enum只是定义了一个常量集合,里面没有“元素”,而枚举是当做int类型存储的,故枚举类型的sizeof值为4。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: