strlen()函数也是一个经常用到的函数,今天就来实现一下它。
照例,依旧先构建整体框架:
#include <stdio.h> int main() { char arr[] = "hello world !"; int len = my_strlen(arr); printf("%d\n", len); return 0; }
下面就来具体实现了:
第一种:
第二种:int my_strlen(const char * src) { int len = 0; while (*src++ != '\0') ++len; //前置++(--)的效率不会低于后置++(--) return len; }
int my_strlen(const char * src) //因为不需要对src的内容进行改变,所以加上const修饰 { char *tmp = (char *)src; assert(src); //断言src非空 while (*tmp) { //tmp指向src的结束标志的'\0' ++tmp; } return tmp - src; //地址相减,得到的实际是它们之间的元素个数 }
为了使用assert(),需要包含assert.h头文件。另外,说一下最后的两个指针相减为什么得到的是元素个数:
只有当两个指针都指向同一个数组中的元素时候,才允许一个指针减去另外一个指针。
![]()
strlen()函数自实现 1.两个指针相减是这两个指针之间元素的个数,而不是元素的长度。
2.如果两个指针指向不同的数组中的元素,那么它们之间相减的结果是未定义的。
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但不允许与指向数组第一个元素之前的那个内存位置的指针比较。
例如将一个数组进行初始化的代码:
这是可以的,再如下:for (vp = &values[0]; vp < &values[N_VALUES];) { *vp++ = 0; }
或者把它再简化一下:for (vp = &values[N_VALUES]; vp > &values[0];) { *--vp = 0; }
for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--) { *--vp = 0; }
对后边这两段代码(实际上是一样的)实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
第三种:
递归写法。int my_strlen(const char *str) { assert(str); if ('\0' == *str) return 0; return 1 + my_strlen2(str + 1); }