模拟实现库函数strcpy
函数的功能,停止条件
strcpy是包含在头文件string.h中的用来拷贝字符串的函数
查阅资料可知strcpy函数的功能是将源字符串的内容复制到目的地字符串中,结束标志是\0,且将\0也复制到目的地字符串。
例如
我们arr2中的hello和末尾的\0全部拷贝进arr1
这里可以看到我们在hello中人为的插入了字符串结束标志\0
assert断言和const修饰指针
根据上面的分析,我们可以简单的写出以下的代码
void my_strcpy(char* dest, char* src)
{
while (*src != '\0')//当src指针偏移到\0位置时,循环结束
{
*dest++ = *src++;//后置++,先使用后++
}
*dest = *src;//将最后的\0补充
}
但是我们的代码并不完善,和资料中库函数的定义还是有区别
首先,在源头字符串前面加了const修饰,第二是库函数中的strcpy返回值是char*而不是void
const修饰指针
我们要知道为什么要在源头字符串前加const而不是目的地字符串,就要先了解strcpy函数的功能,它是将源头字符串的内容拷贝到目标字符串中,所以在整个过程中源头字符串(src)是不会被改变的,而目标字符串(dest)会发生改变。所以在src前加const可以使函数更加健壮
assert断言
我们要想是函数更加健壮,还可以使用assert来断言指针的有效性,主要是用来防止传入空指针
assert断言的意思就是我认定他是xxxx,如果不是就会发生以下情况
代码如下
#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, const char* src)
{
assert(dest != NULL);//断言dest不是空指针
assert(src != NULL);//断言src不是空指针
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = *src;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxxxx";
char arr2[20] = "hel\0lo";
my_strcpy(arr1, NULL);//假设传入一个空指针
return 0;
}
我们在my_strcpy函数中断言了dest和src都不是空指针,然后在函数传参时传入一个空指针会发生什么呢?
我们发现这里程序无法运行,提示信息告诉我们对于src的断言错误,在第9行。
这样我们就可以避免传入空指针的情况发生,使函数更加健壮
函数返回值
最后就是处理函数的返回值,库函数中函数返回值是目的地的地址,处理方法很简单,在函数内部创建一个局部变量来储存dest的起始地址作为返回值就可以了
全部代码为
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))//这里表达式的结果就是src的值,如果遇到\0表达式为假,就会跳出循环
{
;
}
return ret;
}