C语言平方根答题程序小数截断与无限循环bug修复方案
问题根因
你遇到的两个问题都是基础语法和逻辑错误导致的:
- 保留两位小数逻辑失效原因
- 随机数生成行
c = 10 rand() % 100 + 1;存在语法错误,10和rand()之间缺少运算符,本身就无法正常编译 if (b == "%d")是无效写法,浮点数不能直接和字符串用==比较,后续的("%0.2f", n);没有调用printf,根本不会执行输出- 你把用户输入答案的变量定义为
int类型,无法接收带小数的输入,就算平方根是小数,用户输入的小数部分会被直接截断
- 随机数生成行
- 无限循环原因
- C语言多分支判断必须用
else if,你直接写else (n == b)属于语法错误,分支逻辑完全失效 - 重试循环里只做了
n++操作,没有重新读取用户的新输入,n的值只会自增,永远满足不等于正确答案的条件,自然会无限打印重试提示 - 浮点数不能直接用
==判断相等,受存储精度影响,就算值看起来相等,内存里的存储值也可能存在微小误差,必须用差值范围判断
- C语言多分支判断必须用
修正后可运行代码
#include <stdio.h> #include <cs50.h> #include <stdlib.h> #include <math.h> #include <time.h> int main() { // 读取用户姓名 string nome = get_string("olá, qual é o seu nome? "); int c; // 初始化随机数种子,生成1-100的随机整数 srand(time(NULL)); c = rand() % 100 + 1; printf("Olá, %s. Qual é a raiz quadrada de %d? \n", nome, c); // 计算正确平方根,四舍五入保留两位小数 float resposta_correta = sqrt(c); resposta_correta = round(resposta_correta * 100) / 100; float resposta_usuario; // 循环接收输入直到答对 while (1) { resposta_usuario = get_float("Digite sua resposta: "); // 浮点数比较允许0.01以内的误差,匹配两位小数精度 if (fabs(resposta_usuario - resposta_correta) < 0.01) { printf("parabéns, vc tem dois neurônios.\n"); break; } printf("tente de novo.\n"); } return 0; }
编译命令和你之前用的一致,还是gcc loop2.c -o loop2teste20 -lm -lcs50即可。
关键修改点
- 删掉了冗余的只跑一次的for循环,修正了随机数生成逻辑,正确生成1-100的随机整数
- 把用户输入变量类型从
int改为float,用CS50库自带的get_float读取输入,自动处理非法输入问题,不会出现输入截断 - 用
round(值*100)/100的逻辑真正实现平方根四舍五入保留两位小数,不是仅在输出时做格式截断 - 重写了判断分支和循环逻辑,每次答错提示后都会重新等待用户输入新答案,答对后直接跳出循环,不会出现无限打印的问题
- 浮点数相等判断改用差值比较,规避精度误差导致的判断错误
内容的提问来源于stack exchange,提问作者Sanogo
相关产品推荐
相关产品推荐

