首先我们先看下 strcpy这个库函数的返回值以及参数,返回值是char* 类型的是个地址,参数有两个,一个是char*另一个是const修饰的char*,先来看下这个库函数是如何使用。
#include<stdio.h>
#include<string.h> //strcpy库函数头文件
int main()
{
char ch1[20] = { 0 };
char ch2[] = "abcdef"; //前面说到strcpy会返回值是char*的,这里用一个char*的变量来接收,
char* flag = strcpy(ch1, ch2); //strcpy包含的两个参数,前面的是目标字符串,后面是源字符串
printf("%s\n", flag); //只要拿到这个拷贝后的字符串的首地址就可以打印整个字符串
return 0;
}
如果想模拟出strcpy这个库函数,要知道以下几点:
1.源字符串必须以 '\0' 结束。
2.会将源字符串中的'\0'拷贝到目标空间。
3.目标空间必须足够大,确保可以存放下源字符串。
3.目标空间必须可变。
#include<stdio.h>
#include<assert.h> //assert断言头文件
char* My_strcpy(char* s1,const char* s2)
{
assert(s1 && s2); //断言一下,防止s1并且s2有一个是空指针,如果它的条件返回错误,则终止程序执行
char* flag = s1; //先记录下s1这个字符串的起始位置,防止后面程序改变位置,找不到起始位置
while (*s2!='\0') //判断*s2指向的是否是'\0',不是则进行拷贝,是则跳出循环
{
*s1 = *s2; //把*s2指向的字符拷贝到*s1的位置
s1++; //拷贝后移动到目标空间下一个要被拷贝的位置
s2++; //拷贝后移动到源字符串下一个位置
}
*s1 = *s2; //strcpy会将源字符串中'\0'也移动过去,但上面循环遇见'\0'就会跳出,所以要再赋值一次把'\0'也拷贝进去
return flag; //strcpy返回值是char*的,所以直接返回拷贝后的字符串的首地址即可
}
int main()
{
char ch1[20] = { 0 };
char ch2[] = "abcdef";
My_strcpy(ch1, ch2);
printf("%s\n", ch1);
return 0;
}
最后还可以再优化下函数内部,
char* My_strcpy(char* s1, const char* s2)
{
assert(s1 && s2);
char* flag = s1;
while (*s2 != '\0')
{
*s1 = *s2;
s1++;
s2++;
}
*s1 = *s2;
return flag;
}
char* My_strcpy(char* s1, const char* s2)
{
assert(s1 && s2);
char* flag = s1;
while (*s1++ = *s2++) //只要这个表达式的值不为0;就会执行*s2赋值给*s1,后置++来移动拷贝的位置,
{ //最后的'\0'也会被先赋值给s1,再跳出循环,这样就不用额外再把'\0'拷贝到目标字符串了
;
}
return flag;
}