=========================================================================
相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)
=========================================================================
接上期:学C的第十八天【指针初阶:5. 指针和数组、6. 二级指针、7. 指针数组;初识结构体:1. 结构体的声明、2. 结构体成员的访问、3. 结构体传参;练习:3道和整数二进制数相关的练习】_高高的胖子的博客-CSDN博客
=========================================================================
1. 调试
(1). 调试是什么?
调试(Debugging / Debug),又称出错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程(一系列动作)。
(2). 调试的基本步骤
- 发现程序错误的存在
- 以隔离、消除等方式对错误进行定位
- 确定错误产生的原因
- 提出纠正错误的解决办法
- 对程序错误予以改正,重新测试
(3). Debug 和 Release 的介绍
Debug:通常称为调试版本
它包含调试信息,并且不作任何优化,便于程序员调试程序。
(代码演示:)
#include <stdio.h> int main() { int arr[10] = { 0 }; int i = 0; //循环赋值 for (i = 0; i < 10; i++) { arr[i] = 10 - i; } //循环打印 for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0; }
Release:通常称为发布版本
它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户更好地使用。
#include <stdio.h> int main() { int arr[10] = { 0 }; int i = 0; //循环赋值 for (i = 0; i < 10; i++) { arr[i] = 10 - i; } //循环打印 for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0; }
Debug版本文件 和 Release版本文件 的大小对比
2. Windows环境调试介绍
(注:linux开发环境调试工具是gdb)
(1). 调试环境的准备
在环境中选择 Debug选项 ,才能使代码正常调试。
(2). 学会快捷键
F5
启动调试,经常用来直接跳到下一个断点处。
F9
创建断点和取消断点。
断点的重要作用,可以在程序的任意位置设置断点。
这样就可以使得程序在想要的位置随意停止执行,进而一步步执行下去。
(条件断点:)
F10
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者一条语句。
F11
逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(最常用,比F10更加细致,会进入函数观察函数执行的过程)。
CRRl + F5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
(3). 调试的时候查看程序当前信息
查看临时变量的值(监视)
在调试开始之后,用于观察变量的值。
查看内存信息(内存)
在调试开始之后,用于观察内存信息。
查看调用堆栈(调用堆栈)
通过调用堆栈,可以清晰地反应函数的调用关系以及当前调用所处的位置。
查看汇编信息
在调试开始之后,有两种方式转到汇编。
1. 第一种方式:右击鼠标,选择【转到反汇编】;
2. 第二种方式:
查看寄存器信息
可以查看当前运行环境的寄存器的使用信息。
3. 一些调试的实例
- 要熟练掌握调试技巧;
- 初学者:80%时间写代码,20%时间在调试;
- 程序员:20%时间写代码,80%时间在调试;
- 现在学的都是一些简单的调试,以后可能会有很复杂的调试场景:多线程程序的调试等;
- 多多使用快捷键,提升效率。
4. 一些调试的实例
(1). 实例一:实现代码:求 1!+2!+3! ...+ n! ;不考虑溢出
(需调试的问题代码:)
#include <stdio.h> //求 1!+2!+3! ...+ n! ; int main() { int i = 0; int sum = 0; //保存最终结果 int n = 0; int ret = 1; //保存n的阶乘 //输入 scanf("%d", &n); for (i = 1; i <= n; i++) { int j = 0; for (j = 1; j <= i; j++) { ret *= j; } sum += ret; } printf("%d\n", sum); return 0; }
调试思路:
1. 首先推测问题出现的原因,初步确定问题可能的原因。
2. 实际上手调试很有必要
3. 根据第1点,调试时心里有数(下一步应该是什么样的)
(2). 实例二:死循环
#include <stdio.h> 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; }
死循环原因:i 和 arr[12] 地址相同,
地址会相同的原因:
( 数组越界 可能就会出现这种问题)