今天我们来了解以下一些字符串函数的模拟实现:
strlen strcpy strcat strcmp
strlen函数的模拟实现
首先我们转到cplusplus中查找strlen的官方解释:
通过查找我们了解到,strlen是用来测量一个字符串长度的函数,函数的返回值就是字符的长度
字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )。
函数原型如下
size_t strlen ( const char * str )
下面我们来简单了解以下strlen函数的使用(strlen函数等字符串函数的头文件一般都是string.h)
例如:我们测量一下字符串“abcdef”的字符串长度
int main() { char arr[] = "abcdef"; int len = strlen(arr); printf("此字符串的长度是%d\n", len); return 0; }
运行结果如下:
下面我们就可以开始strlen函数的模拟实现了:
我们在之前已经知道,strlen就是从字符串的第一个元素开始往后找"\0",知道找到"\0",一旦找到,函数就立即停止,返回元素个数,这样理解,我们就可以更好地开始它的模拟实现了
方法一:以计数的方式实现
我们定义一个count,用while循环实现count的++,str为字符串的第一个元素的地址,也就是我们常说的首地址,如果解引用后(str)不是"\0",的话,count就++,也就是说元素个数+1,count++后str的位置也要往后移动,所以str++,当str=="\0"时循环停止,count就是字符串的长度了
代码如下:
int my_strlen(const char * str) { int count = 0; assert(str);//进行断言操作,防止str为空 while(*str) { count++; str++; } return count; }
方法二:以递归的方式实现(不能创建临时变量时)
有时候一些题目可能会要求咱们不能创建临时变量来模拟实现,这个时候我们就可以想到递归:
思路如下:
int my_strlen(const char * str) { assert(str); if(*str == '\0') return 0; else return 1+my_strlen(str+1); }
方法三:以指针的方式实现
在之前的指针学习中我们可以知道指针-指针=两个之间的元素个数,所以这里我们首先定义一个指针变量p为str(字符串首地址),然后用while循环将p移动到\0之前的位置,然后相减得出的值就是字符串str的长度了
代码如下:
int my_strlen(char *str) { assert(str); char *p = str; while(*p != ‘\0’ ) p++; return p-str; }
strcpy函数的模拟实现
老规矩,cplusplus查一下:
函数原型如下:
char* strcpy(char * destination, const char * source );
这里我们要注意:
• 源字符串必须以 ‘\0’ 结束
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间
• ⽬标空间必须⾜够⼤,以确保能存放源字符串
• ⽬标空间必须可变
例如,我们将abcde拷贝到des中去:
我们可以打开调试窗口调试一下,就可以看到des将src中的\0也拷贝过去了
下面我们开始strcpy函数的模拟实现,用指针可以轻松的解决问题:
这里我们要记得断言!如果不断言就是报警,因为*解引用了NULL
当 *src不等于\0时,while循环就继续进行,将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环跳出,拷贝完成
这里我们要将dest的首地址记录下来,因为官方的函数定义是要求这个函数返回dest的首地址的
char* my_strcpy(char* dest, const char* src) { char* ret = dest; assert(dest != NULL); assert(src != NULL); while (*src) { *dest=*src; dest++; src++; } return ret; }
也可以简化:
char *my_strcpy(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); while((*dest++ = *src++)) { ; } return ret; }
strcat函数的模拟实现
strcat的作用时将src链接到dest后面,并且这里也要返回dest的首地址
这里需要注意几点:
• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。
我们调试看一看:
我们发现,src的内容就是从dest的\0的位置开始追加的
下面我们就可以开始模拟实现了
同样的我们需要用ret保存dest的首地址,同时记得断言
我们首先将dest的位置右移到\0的位置,然后再将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环结束,追加完成
char *my_strcat(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); while(*dest) { dest++; } while((*dest++ = *src++)) { ; } return ret; }
strcmp函数的模拟实现
strcmp时用于比较两个字符串的,此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止 null 字符为止,如果str1大于str2(⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩),返回 一个大于0的值,str1小于str2,返回 一个小于0的值,如果完全等于,就返回0
例如:
abcde和abcee比较,由于d的acs码值要小于e所以会返回一个小于0的值
我们直接用while循环,如果相等,就继续往下走,不相等就就直接放回他们的差值,也就是asc码值相减,如果相等就为0,大于就时大于0,小于就小于0
代码如下:
int my_strcmp (const char * str1, const char * str2) { int ret = 0 ; assert(src != NULL); assert(dest != NULL); while(*str1 == *str2) { if(*str1 == '\0')//此时两个字符串都遍历完成,且相等,直接返回0 return 0; str1++; str2++; } return *str1-*str2; }
好了,今天的分享到这里就结束了,谢谢大家!