- 通过调试我们可以知道代码编写错误的原因。
- 我们不断积累经验,就能够避免很多错误。
调试的应用场景
关于数组越界的计算机错误:(vs2020,X86,Debug环境下进行)
int main() { int i = 0; int arr[10] = {1,2,3,4,5,6,7,8,9,10}; for (i = 0; i <= 12; i++) { arr[i] = 0; printf("hehe\n"); } return 0; }
结果就是死循环,不断地打印hehe。
接下来,我们调试,分析原因:
之后我们发现arr12的值与i的值一样变化。
数组越界并没有报错
接下来,我为大家分析这个数组越界导致无限循环的原理:
- 内存分为栈区,堆区和静态区
- 我们的局部变量储存在栈区中
- 局部变量就是main函数里面的变量(也就是 i 和 arr[ i ] )
- 1. 栈区内存的使⽤习惯是从⾼地址向低地址使⽤的,所以变量i的地址是较⼤的。arr数组的地址整体是⼩于i的地址。
- 2. 数组在内存中的存放是:随着下标的增⻓,地址是由低到⾼变化的。
- (这两句话非常重要,需要理解一下)
- 数组越界的arr[12] 由于会与 i 的地址重合,因此当arr[12]=0时,i 也会同时变为0。
- 最后导致无限循环。
优秀的代码
- 代码运行正常
- bug很少
- 效率高
- 可读性高
- 可维护性高
- 注释清晰
- 文档齐全
错误分类
1.编译型错误
编译型错误⼀般都是语法错误,这类错误⼀般看错误信息就能找到⼀些蛛丝⻢迹的,双击错误信息也能初步的跳转到代码错误的地⽅或者附近。编译错误,随着语⾔的熟练掌握,会越来越少,也容易解决。
2.链接型错误
- 标识符名不存在
- 拼写错误
- 头文件没包含
- 引用的库不存在
3.运行时错误
- 运行时的错误是最经常发生的,我们常常无法避免这种情况。
- 但是我们可以通过不断地调试,找到错误的原因,减少这种情况。
如何写出优秀的代码
- 积累经验。我们日常不断地积累,知道代码问题,分析原理之后,减少错误代码。
通过coding技巧减少运行时错误的发生
1.assert(断言)
- 用法:assert(表达式)
- 如果assert中的表达式为假,那么assert就会报错。
- 避免运行时错误。
这里可以判断arr是不是为空指针。
判断a是否大于b。
- 我们之后的代码会越来越复杂,assert可以保证我们代码的正确,assert也可以帮助我们找到代码错误的位置。
- 在运行之前,就能报错,避免运行时错误。(运行时错误就是结果错误,需要我们一步一步去调试才能发现)
2.const
const放在 * 的左边
const int*p =int const* p int main() { int a = 10; int p = &a; const int* p=0; *p = 20;//这个表达式不可以运行。 }
p指向的对象不能通过p来改变,
但是p变量本身的值可以改变。
const放在 * 的右边
int* const p int main() { int a = 10; int b = 0; int p = &a; int* const p=0; p = &b; //这个表达式不可以运行。 }
p本身的值不可以改变,但是p指向的对象可以改变。
我们可以通过const来控制一些变量的是否改变。