对库函数strcpy的解释
char *strcpy( char *strDestination, const char *strSource );
Return Value
Each of these functions returns the destination string. No return value is reserved to indicate an error.
以上摘自MSDN。在文档中我们可以了解到:
> strcpy是一个字符串拷贝函数
> 函数有两个参数,参数的类型为char*,第一个参数为目标空间的首地址,第二个参数为源字符串 的首地址
> 函数的返回类型为 char*
> 函数返回值为目标空间首地址(Each of these functions returns the destination string)
> 源字符串必须以‘ \0 ’结束
> strcpy函数会将' \0 '拷贝到目标空间
> 目标空间必须足够大,确保能放下源字符串
> 目标空间必须可变
实现库函数strcpy
在实现库函数strcpy之前,先说说实现库函数的基本思路------模仿库函数。
参考库函数的几个重要参数,包括参数类型,参数个数,函数的返回值等。
这里,将自己实现的strcpy函数命名为my_strcpy,下面开始实现,请看代码:
代码1.0版本 :
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, char* src)
{
assert(dest && src);//确保这两个指针不为空指针,头文件为<assert.h>
char* ret = dest;//保存目标位置的首地址
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;//把‘\0’拷贝过来
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "hello world";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
以上代码虽然完成了库函数strcpy的功能,但是在代码上还可以做出一些优化,更简洁,并且把拷贝‘\0’ 和 非 ‘\0’一起处理。 下面请看代码 :
代码2.0版本:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;//保存目标空间的首地址
while (*dest++ = *src++)//如果有疑惑,请看篇末的解析
{
;//空语句
}
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "hello world";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
对 while(*dest++ = *src++)的解释
这里涉及到优先级的相关知识,首先,后置++为第一优先级,间接寻址符 * 为第二优先级,赋值符号在此处为最低优先级,后置++的优先级最高,所以 *dest++ = *src++ 等价于 (*(dest++)) = ( *(src++)),但因为是后置++,所以++的效果在表达式执行完后才会体现,
所以可以理解为src解引用并赋给dest后,dest和src才++指向下一个位置。
当指针src指向d时,解引用并赋给dest后,执行++,指向‘\0’,此时还未退出循环,接着src解引用把'\0'赋给dest,此时整个表达式的结果为0,即为假,退出循环,但在退出循环之前已经完成把‘\0’
赋给dest的操作。