通过模拟strcpy函数学习编程思想
Posted 东条希尔薇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过模拟strcpy函数学习编程思想相关的知识,希望对你有一定的参考价值。
目录
strcpy函数简介
strcpy是c语言库中的一个函数,需要包含<string.h>头文件。它可以实现数组的拷贝。将src数组中的所有元素(包括末尾的\\0)拷贝在另一个dst数组中。
以下是cplusplus网站中对strcpy函数的介绍
我们通过介绍,可以先尝试自己模拟strcpy的实现
最初版代码
我们需要传进两个常量字符串在这个函数中,然后对每个字符进行操作
void my_strcpy(char* dst,char* src)
{
while(*src!='\\0')//检测到字符串终止后结束复制
{
*dst = *src;//这里是复制操作
dst++;//每复制一个字符后,复制下一个字符
src++;
}
*dst = *src;//放置\\0
}
复制出来后的dst数组就应该为以下的输出结果
但这个函数,虽说确实可以完成复制的功能,但是仍然存在大量的问题,也不够简洁。
以下几步会对代码进行逐步优化。
第一次优化:简化代码
我们可以直接将代码这样放置
void my_strcpy(char* dst, char* src)
{
while (*src != '\\0')
{
*dst++ = *src++;//简化
}
*dst = *src;//放置\\0
}
代码中的++运算符是后置的,可以做到先使用此次的变量,也就是先替换增加之前的字符,再进行++操作,找到下一个字符。
也可以进一步简化
void my_strcpy(char* dst, char* src)
{
while (*dst++ = *src++)//表达式的结果为dst的字符,'\\0'ASC值为0,自动停止
{
;
}
}
这样的优化,不仅继承了前一段代码的优点,也少了替换'\\0'的一步
在while循环中,先把src替换到dst变量中,再判断dst是不是为0。
如果src已经遍历到'\\0'了,替换到dst中,而因为'\\0'的ASCii值为0,判断为假,这个while将会终止,也将会停止复制。
经过这一次优化后,代码会变的更加简洁。
第二次优化:代码有效性
经过了第一次优化,基本实现了将代码简化的功能,但是如果在传参过程中传入了空指针,可能会导致程序出现问题
这样程序如果在后期使用中如果意外传入了空指针,将会导致程序崩溃。
为了解决这一问题,我们可以使用断言来帮我们判断是否为空指针
断言(assert)的介绍
断言是c语言提供的一种函数,需要包含<assert.h>头文件,如果在assert里面的表达式为false,程序将会直接报错,随后退出程序
以下是使用示例
#include<assert.h>
int main()
{
int a = 0;
int b = 10;
printf("hehe\\n");//验证assert前后语句会不会被执行
assert(a>b);//显然此表达式为假
printf("hehe\\n");
return 0;
}
当判断到assert为假时,程序直接报错
并且会给我们提示在哪一行触发的断言 ,在断言后的语句将停止执行。
这个函数可以给我们代码的优化提供以下的提示:
我们可以使用assert断言检查传进的字符串是否是空字符串,如果是直接终止程序的运行。
这样我们就可以写出下面的代码。
代码实现
#include<assert.h>
void my_strcpy(char* dst, char* src)
{
//if (src == NULL||dst==NULL)//防止传入空指针,保护程序
//{
// return;
//}
/*assert(src != NULL);
assert(dst != NULL);*///为假报错
//assert(src);
//assert(dst);
assert(dst && src);
while (*dst++ = *src++)//表达式的结果为dst的字符,'\\0'ASC值为0,自动停止
{
;
}
}
这样我们就程序有效性的优化就完成了。
第三次优化:字符串的安全性
我们在编写程序的时候,可能会出现在上面的代码中将dst和src写反位置的情况
这样将会造成src被意外修改,程序的安全性较低
也可能会有其他外界因素,造成src被意外修改
于是,我们考虑可以使用const来修饰src,防止src被意外修改
关于const修饰符
const是c语言的一种修饰符,它限定了一个变量不能被随意改变
int main()
{
const int num = 0;
num = 10;
return 0;
}
但虽然使用const修饰了,但是num的本质却仍然是变量。
那么num能不能被修改呢
你别说还真有
我们可以使用指针间接修改num
int main()
{
const int num = 0;
int* p = #
*p = 10;
printf("%d\\n", num);
return 0;
}
程序不会报错,但是这种写法其实并不支持,它违背了const的初衷。
我们可以使用const的特性,修饰我们的src字符串,使其无法被修改
代码实现
#include<assert.h>
void my_strcpy(char* dst, const char* src)
{
assert(dst && src);
while (*dst++ = *src++)
{
;
}
}
这样保证了程序的健壮性。
第四次优化:靠近标准库函数
将返回值设为char*
char* my_strcpy(char* dst, const char* src)//保护src
{
char* ret = dst;//模拟库函数,第一个字符地址
//if (src == NULL||dst==NULL)//防止传入空指针,保护程序
//{
// return;
//}
/*assert(src != NULL);
assert(dst != NULL);*///为假报错
//assert(src);
//assert(dst);
assert(dst && src);
while (*dst++ = *src++)//表达式的结果为dst的字符,'\\0'ASC值为0,自动停止
{
;
}
return ret;
}
至此,代码全部优化完毕
总结与提示
- 使用assert断言检查程序的通用性
- 使用const保护一些常量字符串,常量数据等,使程序更加健壮。
- 注释的重要性
本期内容到此结束啦!由于作者水平有限,文章中如有不足与疏漏之处在所难免,希望各位大佬提出你们宝贵的意见!笔芯~
以上是关于通过模拟strcpy函数学习编程思想的主要内容,如果未能解决你的问题,请参考以下文章