高级光能
曲天歌在2020-06-16 19:12:23追加了内容
不是寒假J1的课程吗?
曲天歌在2020-06-16 19:13:04追加了内容
哦,我明白了。我一直以为你是个大佬,原来才J1.。。。
曲天歌在2020-06-16 19:14:05追加了内容
调试课程课后讲义(v2)
调试课程课后讲义
引言
我们平时在写程序时,会有各种各样的错误出现,出现错误不可怕,只要掌握调试改错的方法,就能把错误找出并改正。
一、程序常见错误类型
1. 编译错误
1)变量未定义就使用,或定义后使用位置超出了定义的作用域,如:
#include <iostream> using namespace std; int main() { cout << a; //未定义a return 0; }
或
#include <iostream> using namespace std; int main() { for(int i=1; i<=100; i++) cout << 1; cout << i; //i是在for循环中定义的,只能在for循环里使用 return 0; }
2)括号不匹配。 ( )、[ ]、{ }一定要有始就得有终,如:
#include <iostream> using namespace std; int main() { for(int i=1; i<=100; i++) { cout << 1; //缺少了for循环的右括号 return 0; }
3)缺少分号,如:
#include <iostream> using namespace std; int main() { cout << 1 return 0; }
4)缺少头文件,如:
#include <iostream> using namespace std; int main() { cout << abs(-1); //使用abs函数需要包含头文件cmath return 0; }
5)函数定义在main之后,未提前声明,如:
#include <iostream> using namespace std; int main() { int a; cin >> a; cout << f(a); //未声明f()函数 return 0; } int f(int X) { return 2 * X; }
6)函数的形参和实参不匹配(包括参数类型、参数个数不匹配),如:
#include <iostream> using namespace std; int f(int n, int m) { return n * m; } int main() { int a; cin >> a; cout << f(a); //f函数有两个形参,使用时却只传了一个实参,参数个数不匹配。 return 0; }
还有很多。。。。。。
2. 逻辑错误
- 程序的逻辑错误千奇百怪,需要我们自己去检查。
可以回头读一遍代码,改掉一眼就能看出来的错误,对于不易发现的错误,我们可以使用一定的技巧去调试(下面介绍)。
二、调试程序的几个技巧
1、在关键位置输出关键信息,可以一步一步缩小出错的位置,便于检查(打印日志)
比如:计算输入n行字符串,输出这n行中最长字符串的长度,有同学写了以下的代码:
#include <iostream> using namespace std; int main() { int n,max=0; string s; cin>>n; for(int i=1;i<=n;i++){ getline(cin,s); if(s.size()<max) max=s.size(); } cout<<max; return 0; }
他提交总是有几个测试点错误,但是不知道原因。
找字符串长度的最大值应该没有问题,他猜测可能是输入字符串这部分代码出了问题,于是他在循环输入的代码中加了一行输出:cout<<s<<endl;
for(int i=1;i<=n;i++){ getline(cin,s); cout<<s<<endl; //输入一个就输出一个,检查是否正确输入 if(s.size()>max) max=s.size(); }
果然发现了问题:执行代码,每次都只能输入输出n-1个字符串。
他仔细思考了一下。想起来如果用getline输入字符串之前有别的输入(比如cin>>n 输入了一个整数),那么第一次getline会把换行当做字符串输入。
所以在cin>>n后面要多写一个getline语句。
2、自己编多组样例尝试,不要仅仅试验题目给出的一组样例(具有偶然性)
3、多写注释,知道自己的每个变量代表什么
三、本节知识点脉络