如何写出优秀的代码
我们常常感叹大佬写出的代码,她像心中的女神那样悠亚......
以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写的代码,写出优美实用的代码就如喝水一样自然。
结语
冰冻三尺非一日之寒,没有人生下来就能写代码。想成为一个优秀的程序员,想写出大神级别优美的代码,我们需要不断积累经验。我们应该庆幸出生在这个时代,大佬就在我们眼前,学无止境!