C++中sizeof,strlen(),size(),length()的区别

strlen(),size(),length()用于求字符串的长度,sizeof用于求对象的字节大小

sizeof本质上是一个运算符,它会返回保证能容纳所建立的最大对象的空间大小,其值在编译时便计算好了,所以不能用于计算动态分配的内存。在计算基本类型的字节大小时,基本不会出现问题,但发现在计算结构体和共用体的大小时发现,结构体和共用体大小并不是它们成员的字节大小的简单相加

sizeof
sizeof是一个运算符,获得保证能容纳实现所建立的最大对象的字节大小。因为sizeof的值在编译时就计算好了,因此sizeof不能用来返回动态分配的内存空间的大小。在运用sizeof计算,发现结构体的大小并不是其各个成员的字节大小简单相加,共用体的大小也不是只取决于其最大的成员所占的空间大小。

在计算结构体的大小时会涉及到字节对齐机制

结构体变量的首地址能够被其最宽基本类型成员大小所整除
结构体每个成员相对于结构体首地址的偏移量都是该成员大小的整数倍,如有需要,编译器会在成员之间填充字节,使其满足这个要求
结构体总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最后一个成员之后加上末尾填充字节
基本数据类型为:short,int,long,float,double,char等

当结构体中的成员都为基本数据类型时

struct student
{
char sex;
short socre;
int age;
};

成员sex的大小为1字节,成员score的大小为2字节,因此成员score相对于结构体首地址的偏移量为1,成员score为short类型,大小为2字节,所以此时成员score的偏移量并不满足上述准则2的要求,需要在成员score和成员sex之间填充1字节,使其满足准则2。填充后,此时结构体的大小为1+1+2=4字节,接下来看成员age,它是int类型,大小为4字节,它相对于首地址的偏移量为4字节,已经满足准则2,所以此时无需填充字节,此时结构体大小为1+1+2+4=8字节。最后,我们还需要看此时结构体的大小是否满足准则3,这个结构体中最宽的基本类型为int,大小为4字节,结构体一共8字节,因此满足准则3要求,该结构体的大小就是8字节

接下来扩展两种特殊的情况

当一个结构体中内嵌有另外一个结构体时,准则2应该在原有基础上添加,复合成员相对于结构体首地址的偏移量是复合成员中最宽基本类型成员大小的整数倍并且该复合成员还需要满足准则3

struct student
{
char sex;
struct score
{
double math;
short chinese;
int english;
}S1;
int age;
};

当遇到一个结构体中内嵌有其他结构体时,我们应该先从内嵌的结构体出发,先看结构体score,成员math为8字节,成员chinese为2字节,根据准则2,此时无需在它们之间填充字节,此时结构体score大小为8+2=10字节。成员english为4字节,根据准则2,此时应该在成员chinese后填充2个字节,结构体大小为8+2+2=12字节,最后加上成员english的4字节,得到16字节,最后再看此时score结构体是否满足准则3,score结构中最宽的基本类型为double,8字节,所以满足了准则3的要求,score的最终大小为16字节。接下来再看结构体student,成员sex为1字节,复合成员score相对于结构体首地址的偏移量为1字节,并不满足出现内嵌结构体时特殊的准则2,,且内嵌的结构体中最宽的基本类型的大小为8字节的double,所以需要在sex后填充7字节,大小为1+7+16=24字节,接下来看成员age,它大小为4字节,此时age相对于结构体首地址的偏移量为24字节,已经满足了准则2,无需进行字节填充。此时整个student的结构体的大小为1+7+16+4=28字节,最后再看此时结构体的大小满不满足准则3,发现28并不是8的整数倍,所以还需要再填充4个字节才能满足要求,28+4=32字节。结构体student的最终大小为32字节

另外一种特殊情况是,当结构体内部出现数组的时候,此时的准则2应为在原有的准则2的基础上加上,数组相对于结构体首地址的偏移是该数组成员大小的整数倍

struct student
{
char sex;
short score[4];
int age;
};
结构体student的首个成员sex大小为1字节,成员score是由4个大小为2字节的short类型组成的数组,它相对于首地址的偏移为1字节,根据准则2,此时成员score的偏移与short类型大小2字节不相等,所以需要填充一个字节,结构体大小为1+1+24=10字节。此时成员age相对于首地址的偏移为10字节,根据准则2,需要填充2个字节,所以1+1+24+2+4=16字节,最后再核对准则3,发现此时已经满足准则3,所以该结构体的最终大小为16字节

对于一个共用体,它的大小应为占据最多内存的成员的长度,但是此时字节对齐准则3依旧成立

union myunion
{
char name[10];
int age;
char ch;
};

该共用体中,占据最多内存的成员是name,为10字节,最宽的基本类型为int,大小为4字节,所以需要满足字节对齐准则3,该共用体大小为10+2=12字节

strlen()
strlen()是一个函数,它的参数必须是一个字符指针,它返回的是字符串的长度,它跟sizeof在编译时就计算好不同,它是在运行之后才计算出来的。该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符’\0’。返回的长度大小不包括’\0’

size()和length()
size()和length()这两个函数是用来计算string类对象的长度,假如有一个string对象str,则str.size()和str.length()会返回它们的长度,它们的作用是相同的
————————————————
版权声明:本文为CSDN博主「OneTapMan」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/OneTapMan/article/details/82420950

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值