一.环境介绍
- Win10 64位 + Clion
- 编译器:x86_64-posix-seh-rev0, Built by MinGW-W64 project
- Cmake
二.strlen()功能和原理
strlen()原型:*size_t strlen(const char str)
头文件:#include <string.h>
功能:计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
实现:
1 | size_t strlen(const char *s) |
可以看出strlen的形参类型是const char*,那就意味着每次只处理一个byte。
三.strlen的一些限制和实际问题分析
*Remember, C-style strings are by definition null-terminated.*
使用限制:
- strlen的传入参数必须是字符串
- 如果是字符数组,必须有空结束字符
那么接下来我们就根据如上两条限制分别举例:
strlen求int类型数组长度
从printf的结果来看,strlen(arr)的长度是1,可能有的同学觉得计算出来的长度应该是3。我们从arr的内存布局来看。首先arr占据12个字节这没什么好说的,其次我的平台内存里存储的数据是是小端的,那么数据1(0x00 00 00 01),由于是小端则数据的低位存在内存的低位,如图所示内存中存的1就为01 00 00 00,arr里的2和3同理。strlen的原理就是根据传入的指针,一个字节一个字节去遍历,直到遇到空结束字符。很显然,如图strlen遍历完第一个字节0x01后遇到了0x00,那此时strlen就停止遍历,向调用者返回计算结果1。说明如果用strlen来计算int类型数组大小时,结果是未定义的!

2.strlen求非空字符数组结尾长度
从printf的结果来看,str的长度为5,这显然与预期不符。还是一样,我们str的内存布局来分析问题。’a’的ascii码为0x61,’b’的ascii码为0x62,strlen函数遍历了0x61和0x62字节之后,由于没有遇到空结束字符,所以继续往下走,遍历完0xb0,0x14,0x15之后终于遇到了一个空结束字符,这时候strlen结束遍历,向调用方返回结果。但实际上str数组内存地址结束后存放了什么值,这完全由编译器决定,所以字符数组如果没有以空结束字符结尾的话,strlen计算结果完全是未定义的!

3.strlen求字符串的长度和求以空字符结尾的字符数组长度
strlen求字符串长度
从printf的结果来看,ptr字符串的长度为4。我们从ptr的内存布局来看,当我们定义了一个字符串的时候,编译器会自动往字符串末尾加一个空结束符,ascii值为00H。此时我们使用strlen求字符串的长度值肯定是预期之内的。

strlen求空字符结尾的字符数组长度
从printf的结果来看,str字符数组长度确实为2,因为我们显式的往字符数组末尾加了空结束符。

四.总结
本文介绍了C语言里字符串求长度函数strlen的原理、使用注意事项,最后结合实例分析了一些遇到的问题,加深对strlen原理的理解。