前言
我们应该如何避免写错误的代码以及将错误扼杀在摇篮里,我们一起看一下优秀的代码有什么特点以及一些常用的coding技巧。
一、优秀的代码特点
1.代码运行正常
2.bug很少
3.效率高
4.可读性高
5.可维护性高
6.注释清晰
7.文档齐全
二、常用的coding技巧
1.使用assert
2.尽量使用const
3.养成良好的编码风格
4.添加必要的注释
5.避免编码的陷阱
一、举个例子
示例:模拟实现库函数:strcpy
1.什么是strcpy
字符串复制函数,功能是将字符串2复制到字符串1。
在这里给大家推荐一个学习C语言库函数的网站:Reference - C++ Reference (cplusplus.com)http://www.cplusplus.com/reference/这就是这个网站的主页:
在搜索框中输入你想了解的函数,这个函数的信息就显示出来了,比如我想了解strcpy函数:
那么这个函数的基本信息就显示出来了,当然往下滑动还有更多的信息。
2.模拟实现strcpy
#include <stdio.h>
void my_strcpy(char* dest, char* scr)
{
while (*scr != '\0')
{
*dest = *scr;
dest++;
scr++;
}
*dest = *scr;
}
int main()
{
char arr1[20] = "xxxxxxxxxxx";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
return 0;
}
以上代码就通过函数调用自定义函数my_strcpy实现库函数strcpy函数,但是这个代码还可不可以优化了呢,答案是可以的,如以下代码:
#include <stdio.h>
void my_strcpy(char* dest, char* scr)
{
while (*scr != '\0')
{
*dest++ = *scr++;
}
*dest = *scr;
}
int main()
{
char arr1[20] = "xxxxxxxxxxx";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
以上两段代码就是将循环体中的语句进行了优化,意思是将数组arr2中的字符一个一个往数组arr1中复制,当进行到arr2数组的\0字符时,就停止循环,每循环完一次地址向后走一位进行复制下一个字符,直到遇到\0。
当然,还有值得优化的地方,如以下代码:
#include <stdio.h>
void my_strcpy(char* dest, char* scr)
{
while (*dest++ = *scr++) //即拷贝过去,又停止循环
{
;
}
}
int main()
{
char arr1[20] = "xxxxxxxxxxx";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
return 0;
}
这个代码的好处是更简介了,同时就可以将数组中的数据拷贝过去,又有终止循环的条件。以上代码就是将数组2中的h复制到数组1中,while括号中的条件表达式为h,为真,所以再进行下一次循环,直到将数组2中的\0复制到数组1中,while括号中的条件表达式为假,终止循环。
二、assert的用法
1.什么是assert
我们还可以用我上面给大家推荐的网站来查看一下,我已经翻译成中文了。方便大家阅读。使用assert还需要引头文件include <assert.h>。
2.还是引用以上例子:
如果圈住的arr1,arr2之一改成NULL,则这个程序就会出错,空指针不能直接进行内存访问,不能解引用。但是万一传过来的是空指针,我们应该让程序给我们一个提示。
此时就需要assert函数了,我们可以在my_strcpy函数中进行如下修改:
#include <assert.h>
#include <stdio.h>
void my_strcpy(char* dest, char* scr)
{
assert(scr != NULL); //断言
assert(dest != NULL); //断言
while (*dest++ = *scr++) //即拷贝过去,又停止循环
{
;
}
}
int main()
{
char arr1[20] = "xxxxxxxxxxx";
char arr2[] = "hello";
my_strcpy(NULL, arr2);
printf("%s", arr1);
return 0;
}
如果scr不是空指针,那么assert(scr != NULL); 则没有产生作用,如果dest为空指针,那么 assert(dest != NULL);就会报错。
报错如下:
这样会提示出哪一行发生的错误,我们就可以很方便的找到错误的来源。
三、const的用法
1.什么是const
const修饰的量为一个常量即不能被修改的量。
2.const和指针的结合
int main()
{
int num = 10; //定义变量
int* p = # //定义一个指针变量,存放num的地址
*p = 20; //解引用,更改num的值
printf("%d", num); //输出num的值
return 0;
}
以上代码可以通过指针来更改num的值。
注意:const的位置也有不同的放法,一个是放*左边,const修饰的就是*p,这样指针指向的内容不能通过指针来改变,但是指针变量可以改变。const放在*右边,const修饰的就是指针变量p,这样指针变量本身不能改变,指针指向的内容可以改变。如果const同时放在*的左边和右边,那么指针指向的内容和指针变量本身都不能修改。
看一下三段代码:
int main()
{
int n = 10;
int m = 100;
int const* p = &n; //const放在*左边
*p = 20; //指针指向的内容不能改变
p = &m; //指针变量本身可以改变
return 0;
}
int main()
{
int n = 10;
int m = 100;
int * const p = &n; //const放在*右边
*p = 20; //指针指向的内容可以改变
p = &m; //指针变量本身不能改变
return 0;
}
int main()
{
int n = 10;
int m = 100;
int const*const p = &n; //如果const同时在*的左边和右边
*p = 20; //指针指向的内容不能改变
p = &m; //指针变量本身也不能改变
return 0;
}
以上就是关于const的用法及不同位置的含义。