这是一篇介绍模拟实现库函数strcpy的博客,包含每一步实现的思路,以及涉及到的相关小知识点,最后,对strcpy不检查目标字符串中是否有足够空间的问题,进行了优化。
一、MSDN中对strcpy的注解
功能:strcpy用于字符串拷贝,将源字符串拷贝到目标字符串中; 参数:指向目标字符串的指针dest,指向源字符串的指针src; 返回值:返回指向目标字符串的指针; 标注:strcpy会将结束标志null('\0')从源字符串中复制到目标字符串。
二、基本功能的实现
1、拷贝功能实现
首先实现基本功能,采用循环拷贝字符串,并以源字符串是否出现'\0'作为循环结束标志;
#include<stdio.h>
void mystrcpy(char* dest, char* src)
{
while (*src != '\0')
{
//拷贝
*dest = *src;
//往后指向下一个位置
dest++;
src++;
}
*dest = *src;//拷贝结束标志'\0'
}
2、对代码书写进行优化
- dest以及src的++可以采用后置++替换,可以实现原功能的同时简短代码;
- 结束标志'\0'的ASCII码值为0,可作为while循环结束判断的条件;
- 赋值操作符=的返回值是左操作数。
void mystrcpy(char* dest, char* src)
{
// 后置++实现指针往后推进,
// 赋值操作=返回左操作值,达到while循环结束判断标志的同时,
// 对结束标志'\0'进行拷贝
while (*dest++ = *src++);
}
3、使用const对源字符串进行保护,利用assert防止传参为野指针
- const
-
- 在*左边,表示修饰 *p,也就是指针指向的内容,此时不可更改指针p指向 的地址中的值,但指针可以指向别的位置;
-
- 在*右边,表示修饰 p,只修饰指针,此时p只可指向当前所指向的地址, 而其中的值,可被更改。
- assrt
-
- ()中的条件不满足时,即为假时,执行代码时会报错,但在release版本中会被优化,仅在debug版本中存在。
void mystrcpy(char* dest, const char* src)
{
assert(dest && src);//防止dest与src为空指针
while (*dest++ = *src++);
}
4、返回值的满足
定义ret指针变量,用于保存目标字符串首地址; 注:不可直接返回dest,因为在对字符串拷贝的过程中,dest指向的地址已经发生变化,若返回dest,dest指向的将是目标字符串的末尾。
char* mystrcpy(char* dest, const char* src)
{
assert(dest && src);//防止dest与src为空指针
char* ret = dest;//保存源字符串首地址
while (*dest++ = *src++);
return ret;
}
三、优化
增加形参,用于标志目标字符串空间的长度,若源字符串长度大于目标空间长度,则报错。
char* mystrcpy(char* dest, const char* src, int dsz)
{
int i = 0;//用于测算源字符串长度是否满足条件,包含'\0'
assert(dest && src);//防止dest与src为空指针
char* ret = dest;//保存源字符串首地址
while (*dest++ = *src++)
{
i++;
assert(i < dsz);
}
return ret;
}