1. 函数传递值传不进去
参数名字命名跟其他名字冲突。修改函数传递值
2. 二维vector的assign函数赋值后,二维vector为空
Assign只能赋一维的vector
3. 定义一个变量,无论是结构体,还是,类,都要初始化。否则你不知道会出现什么奇葩的错误。
调试技巧:
以下方法来自于《程序设计实践》
1. 关键位置的关键变量输出,比单步调试速度更快,效果更好。
2. 检查最近的改动。意味着,修改前需要先把原来的代码保存。
3. 像侦探一样思考,通过结果反向推理。
4. 写程序自检测错误。只在调试时,有效。通过定义宏:#ifndef NDEBUG #endif。这个不一定对。
如何定位错误:
1.程序单步调试正常,但重复调试错误,并且不知道错在哪个位置,例如vector溢出。输出cout<< 位置<<endl;像二分查找一样定位哪个函数错。然后,思考是什么原因导致的错误。将怀疑的地方输出出来,像侦探一样溯源。为了验证是否正确,根据需要设置输入,看是否出现同样的错误。
测试:
调试和测试是有区别的。测试是在程序能够跑起来后,用来发现错误的。
1.边界错误。如数组的最大值,文件输入为空等。
2. 前条件和后条件。验证代码执行前,应该满足的条件。和执行后应该得到的结果。
3. 使用断言assert(); 括号内是断言条件。如果不满足断言,会返回位置。
4. 防御性程序。增加代码,不过最好只在调试阶段执行。加宏 #infdef DEBUG #endif; 如果是调试阶段,就执行之间的代码。
5. 检查返回值。exit(); 如,打开文件。
系统化测试:
1. 递增测试。先测试初始的简单的部分,然后不断增加测试的代码。
2. 分片测试。 各部分测试正确后,再组合到一起。
3. 弄清所期望的输出。如果不知道最终的答案。那么测试就是在浪费时间。因为不知道哪是正确的。
4. 检验保持不变的特征。插入和删除后,某些量应该是不变的。比如一共有100个点在容器A中,从中移除20个点,插入一个容器B中。那么,容器A和容器B中的总元素应该是一样的。
5. 比较相互独立的实现。对一个问题,使用两种不同的实现方式。如果结果是一致的,那么说明是正确的。
6. 度量测试的覆盖集。应保证程序中的每一行都被执行过。否则,不能保证程序的正确性。
测试自动化:
压力测试:
1.随机输入不合法的输入。看系统反应。
性能优化:
1. 将固定的值放在循环体外,防止多次计算。提高速度。
2. 除法和求余的速度比乘法慢的多。除法可以用乘倒数。
3. 用简单计算代替函数。
4. 铺开和删除代码。有限的循环,直接铺开运算。
5. 预先算出某些值。
6. 单精度比双精度快一些。