strlen函数与sizeof单目运算符异同点的深度剖析

strlen函数与单目运算符sizeof的区别

相同之处

Strlen函数与sizeof单目运算符均可以计算字符型数组的长度,示例如下:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    cout << sizeof(str)-strlen(str) << endl; // 返回值为1  
} 

 

有朋友说,为什么我写strlen(str)-sizeof(str)得出的结果不是-1呢?这就涉及到我们要讲的两者的第二个相同之处。

返回值类型相同

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    cout << strlen(str) - sizeof(str) << endl;  
    // 结果为4294967295  
} 

 

我现在就讲解一下结果的由来:

Strlen函数的返回值是unsigned int型的结果占四个字节的存储空间,unsigned int所能表示的最大值是[0, 4294967295],这个范围就像一个封闭的环一样,-1就相当于4294967295

 

Sizeof一样返回值类型也为unsigned int型变量,无论如何计算均为>=0的值,例如:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    cout << sizeof(str)-15 << endl;  
    // 结果为4294967295-15=4294967280  
    // 原理如下:  
    // unsigned int i = 0;  
    // i -= 5; // 最终i的值还是大于0的数值  
}  

 

 

不同之处

原理不同

Strlen作为针对字符型数组的函数他有很强的针对性,它的功能就是计算字符型数组的长度,其他类型它不支持。

单目运算符sizeof 是一个单目单目运算符,而不是一个函数。与函数 strlen 不同,它的参数可以是数组、指针、类型、对象、函数等。

有些网友会问到:为什么指针变量 的sizeof()打印出来的都是 4?

大家注意,我这里说的是指针变量,不是数组名。因为sizeof单目运算符是对缓存区进行操作的,它从变量的开始地址开始读取,一直读取到变量结束。

对于数组,sizeof计算的是数组长度:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    cout << sizeof(str) << endl; // 结果为11,因为字符串结尾有结束符'\0'  
}  

 

对于地址变量,sizeof计算的是单个变量的大小:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    char *str1 = str;  
    cout << sizeof(str1) << endl; // 结果为4  
} 

 

大家思考一下,为什么下面两个程序会有所不同?

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    char *str1 = str;  
    cout << strlen(str1) << endl; // 结果为10  
} 

 

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char str[] = "超级霸霸强";  
    char *str1 = str;  
    cout << sizeof(str1) << endl; // 结果为4  
} 

 

以上结果为什么不同呢?

因为strlen是对变量存储的地址进行操作进而读取字符型数组的大小;而sizeof则是从变量的地址开始读取直至读取完变量所占的所有空间。看上面的例子可以知道,64位的电脑最多可以访问4个字节长的内存空间,因此地址变量无论指向何种类型的数据,存储空间均为4字节,即4 bytes。

Sizeof不能求得动态数组的大小,而strlen函数可以

Sizeof是个单目运算符在系统编译程序之前就已经执行,如果sizeof(a)中a为地址变量,拿结果返回4 bytes,在编译程序之前没人知道a是否动态申请了空间,只知道他是个地址变量。动态申请空间那是程序编译的时候执行的,但是sizeof单目运算符在程序编译之前就已经执行完了。

Sizeof的错误用法:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char *str = new char[2]{ 's','s' };  
    cout << sizeof(str) << endl;   
    // 结果为4,代表的是指针所占用内存的大小,而不是动态数组的长度  
}

​​​​​​​  

Strlen计算动态申请的空间:

#include <iostream>  
using namespace std;  
  
void main()  
{  
    char *str = new char[3]{'s','s','\0' }; // 必须带'\0'字符串结束符  
    cout << strlen(str) << endl;   
    // 结果为2,strlen是个函数,它是在编译时执行的,在此之前str已经动态申请了存储空间  
}  

 

我们注意到strlen求解数组的大小,其中数组必须最后一个元素是’\0’字符串结束符,strlen函数计算出的字符数组长度不包括’\0’,因此字符型数组真实的长度是strlen(str)+1。

Sizeof单目运算符与strlen函数被执行的次序不同

Sizeof是单目运算符它是在程序编译以前就已经执行完成,因此他与编译过程中执行的strlen函数有很大区别。由于new动态申请数组是在编译过程中执行,因此sizeof不能判断动态申请数组的长度。

// 以C语言中的malloc为例:  
char *str = (char*)malloc(sizeof(char) * 4); // 由于char变量大小为1 byte,因此在编译过程中,此语句等价为:char *str = (char)malloc(1 * 4)  
// 由于malloc申请的内存空间是void*型的,因此要强制类型转换至char*型的  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥胖胖是太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值