代码能跑起来就够了吗【代码优化/模拟实现库函数strcpy()/C语言】
目录
如何写出优秀的代码
我们常常感叹大佬写出的代码,她像心中的女神那样悠亚......
以strcpy()为例
▶️写一个函数实现字符串复制功能
//source字符串-->destination字符串
void my_strcpy(char* dest, char* src)
{
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
}
这样虽然实现了字符串复制的功能,但能不能更精简一些呢?
▶️循环中的三条语句按照顺序,先赋值,然后各自+1,下面的写法能更精简
void my_strcpy(char* dest, char* src)
{
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = *src;
}
这里的++/--操作符虽然优先级比*高,但这句是先将原先的的src赋值给原先的dest,然后再各自+1
▶️还可以再简化
void my_strcpy(char* dest, char* src)
{
while (*dest++ = *src++)
{
;
}
}
这里括号内的值是src赋值给dest的符号对应的ASCII值,当赋值\0后,刚好跳出循环
嗯大神写的代码就是不一样
缺陷
空指针问题
假如src为空指针,会导致程序错误
▶️我们让assert宏来帮忙:
#include <assert.h>
void my_strcpy(char* dest, char* src)
{
//assert(dest != NULL);//断言
//assert(src != NULL);//断言
assert(dest && src);//断言
while (*dest++ = *src++)
{
;
}
}
它需要包含头文件<assert.h>,assert是一个宏,在这里姑且当作函数。
当括号内的值为假,程序就会"报错",提醒我们预设的情况发生了
▶️错误提示如下
指针使用顺序问题
假如coder将destination字符串复制给了source字符串
#include <assert.h>
void my_strcpy(char* dest, char* src)
{
assert(dest && src);//断言
while (*src++ = *dest++)//顺序反了
{
;
}
}
编译器不会报错,但无法运行,有时候这种错误也是难以避免的。
▶️如何规避指针使用顺序错误的问题?
我们使用const修饰,使之成为不可修改的常变量
关于const修饰指针:const int *和int * const的区别
char* my_strcpy(char* dest, const char* src)//用const修饰
{
assert(dest && src);//断言
char* ret = dest;
while (*src++ = *dest++)//顺序反了
{
;
}
return ret;
}
▶️在这里为将函数返回类型改为指针,并将destination字符串首地址保存于return字符串名中,以便最后返回整个复制后数组
编译器报错:
当我们不希望某些东西被修改,我们就用const修饰它
总结
在写strcpy函数的时候,我们从最开始的:基本实现函数功能、到不断优化、简化代码,再到差错,规避可能发生错误的情况,最终写出了一段优美的、实用的、高效的代码。
这是写一个函数的过程,更是以后每次写代码的过程。在修炼的路上,我们按这些步骤思考代码,不断学习优秀coder写的代码,写出优美实用的代码就如喝水一样自然。
结语
冰冻三尺非一日之寒,没有人生下来就能写代码。想成为一个优秀的程序员,想写出大神级别优美的代码,我们需要不断积累经验。我们应该庆幸出生在这个时代,大佬就在我们眼前,学无止境!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!