刚学 C 语言求最大公约数的时候,是不是特别挫败?明明老师讲的辗转相除法原理听懂了,自己写代码却总是出问题。要么输入 12 和 18,算出个 3 来;要么程序一运行就卡住不动;更惨的是,编译的时候一堆红色错误,根本不知道哪错了。其实啊,新手犯的错就那么几种,今天兔子哥就把这些坑一个个扒出来,告诉你错在哪,该怎么改,看完保准你少走弯路,一起往下看吧!
错误一:没处理负数,结果跟着错
很多新手写代码的时候,直接拿输入的数开始算,根本没想过如果输入负数怎么办。比如输入 - 12 和 18,按道理最大公约数还是 6,但如果代码没处理负数,算出来可能是 - 6,或者干脆是错的。
为啥会错?
因为负数的取余运算结果可能是负数,比如 - 12 % 18 在 C 语言里结果是 - 12,这样辗转相除下去,余数永远变不成 0,最后得到的结果肯定不对。
怎么改?
在计算前先把两个数转成正数,用绝对值处理就行。代码可以这么加:
c运行
if (a < 0) a = -a;if (b < 0) b = -b;加上这两句,不管输入正数还是负数,都能当成正数来算,结果就对了。
错误二:循环条件写反,程序卡死
用辗转相除法的时候,循环条件是判断余数是否为 0。可有的新手会把循环条件写成
while (a != 0),结果程序跑起来就停不下来,只能强制关掉。举个例子:
求 18 和 12 的最大公约数,正确的步骤是:
18 ÷ 12 余 6
12 ÷ 6 余 0 → 结束,结果是 6
可如果循环条件是
a != 0,当余数变成 0 时,a 的值是 6,循环还会继续,这时候用 6 除以 0,程序就出错了,要么卡死要么崩溃。正确的循环条件应该是
while (b != 0),因为当 b(除数)变成 0 的时候,a(被除数)就是我们要的结果。记住,判断的是除数是不是 0,不是被除数。错误三:递归没写终止条件,栈溢出
用递归实现的时候,新手常犯的错是忘了写终止条件,或者终止条件写反了。比如把
if (b == 0) return a;写成if (a == 0) return b;,结果要么算错,要么递归次数太多,栈溢出。看看这个错误代码:
c运行
int gcd(int a, int b) {return gcd(b, a % b); // 没有终止条件!}这样写的话,函数会一直自己调用自己,根本停不下来,最后系统会提示 “栈溢出” 错误,程序直接崩溃。
正确的递归写法必须有终止条件:
c运行
int gcd(int a, int b) {if (b == 0) { // 当除数为0时,返回被除数return a;} else {return gcd(b, a % b);}}记住,递归一定要有 “出口”,不然就会无限循环。
错误四:变量交换时没用到临时变量
有时候需要交换 a 和 b 的值,让 a 大于 b 方便计算。新手可能会这么写:
c运行
if (a < b) {a = b;b = a;}你猜结果会怎样?比如 a=12,b=18,交换完之后 a 和 b 都会变成 18,原来的 12 就丢了。这就是没用到临时变量的缘故。
正确的交换方法得用一个临时变量存一下原来的 a:
c运行
if (a < b) {int temp = a; // 先把a的值存起来a = b;b = temp; // 再把存起来的a的值给b}这个小错误看着简单,新手却经常犯,尤其写得急的时候,很容易漏掉临时变量。
常见错误对比表
| 错误类型 | 错误代码示例 | 正确代码示例 | 错误原因 |
|---|---|---|---|
| 未处理负数 | int gcd(int a, int b) { ... } | if(a<0)a=-a; if(b<0)b=-b; | 负数取余导致结果错误 |
| 循环条件错误 | while (a != 0) | while (b != 0) | 除数为 0 时未终止循环 |
| 递归无终止条件 | return gcd(b, a%b); | if(b==0)return a; else... | 导致无限递归,栈溢出 |
| 变量交换错误 | a=b; b=a; | int t=a; a=b; b=t; | 覆盖了原来的值,交换失败 |
为啥明明改了错,结果还是不对?
可能你会遇到这种情况:上面的错误都改了,可算出的结果还是不对。这时候不妨打印一下中间过程,看看每一步的 a、b、余数是多少。
比如在循环里加一句
printf("a=%d, b=%d, 余数=%d\n", a, b, a%b);,运行的时候就能看到哪里出问题了。有时候可能是输入的时候输错了数,或者输出的时候变量名写错了,这些小细节也容易导致结果不对。兔子哥刚学的时候,犯过最傻的错是把
a % b写成了a / b,结果算出来的根本不是余数,调试了半天才发现。所以啊,写代码的时候别急着运行,先检查一下运算符对不对,变量名有没有写错。其实新手犯错很正常,关键是知道错在哪,怎么改。上面这些错误,你可能现在觉得简单,但写代码的时候一着急就容易犯。最好的办法是多练,写完代码自己先走一遍流程,看看步骤对不对。慢慢的,这些错误就不会再犯了,希望今天讲的这些能帮到你,下次写代码顺顺利利的!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
评论列表
基础算法辨错解惑,助力新手编程精进。