关于调试的应用场景及如何编写优秀代码

  • 通过调试我们可以知道代码编写错误的原因。
  • 我们不断积累经验,就能够避免很多错误。

调试的应用场景 

 关于数组越界的计算机错误:(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。

接下来,我们调试,分析原因:

关于调试的应用场景及如何编写优秀代码_第1张图片

之后我们发现arr12的值与i的值一样变化。

关于调试的应用场景及如何编写优秀代码_第2张图片

关于调试的应用场景及如何编写优秀代码_第3张图片

 数组越界并没有报错

关于调试的应用场景及如何编写优秀代码_第4张图片

关于调试的应用场景及如何编写优秀代码_第5张图片

接下来,我为大家分析这个数组越界导致无限循环的原理:

  • 内存分为栈区,堆区和静态区
  • 我们的局部变量储存在栈区中
  • 局部变量就是main函数里面的变量(也就是 i 和 arr[ i ] )

关于调试的应用场景及如何编写优秀代码_第6张图片

  • 1. 栈区内存的使⽤习惯是从⾼地址向低地址使⽤的,所以变量i的地址是较⼤的。arr数组的地址整体是⼩于i的地址。
  • 2. 数组在内存中的存放是:随着下标的增⻓,地址是由低到⾼变化的。
  • (这两句话非常重要,需要理解一下)

 关于调试的应用场景及如何编写优秀代码_第7张图片

  • 数组越界的arr[12] 由于会与 i 的地址重合,因此当arr[12]=0时,i 也会同时变为0。
  • 最后导致无限循环。

关于调试的应用场景及如何编写优秀代码_第8张图片


优秀的代码

  • 代码运行正常
  • bug很少
  • 效率高
  • 可读性高
  • 可维护性高
  • 注释清晰
  • 文档齐全

错误分类

1.编译型错误 

 编译型错误⼀般都是语法错误,这类错误⼀般看错误信息就能找到⼀些蛛丝⻢迹的,双击错误信息也能初步的跳转到代码错误的地⽅或者附近。编译错误,随着语⾔的熟练掌握,会越来越少,也容易解决。

2.链接型错误 

  • 标识符名不存在
  • 拼写错误
  • 头文件没包含
  • 引用的库不存在

 关于调试的应用场景及如何编写优秀代码_第9张图片

3.运行时错误

  •  运行时的错误是最经常发生的,我们常常无法避免这种情况。
  • 但是我们可以通过不断地调试,找到错误的原因,减少这种情况。

如何写出优秀的代码 

  •  积累经验。我们日常不断地积累,知道代码问题,分析原理之后,减少错误代码。

通过coding技巧减少运行时错误的发生

1.assert(断言)

  • 用法:assert(表达式)
  • 如果assert中的表达式为假,那么assert就会报错。
  • 避免运行时错误。

 关于调试的应用场景及如何编写优秀代码_第10张图片

 这里可以判断arr是不是为空指针。

关于调试的应用场景及如何编写优秀代码_第11张图片

判断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来控制一些变量的是否改变。

你可能感兴趣的:(C语言学习,算法,数据结构,c语言,开发语言)