鱼C论坛

 找回密码
 立即注册
查看: 1637|回复: 5

[已解决]C语言switch语句和分支嵌套

[复制链接]
发表于 2023-12-26 14:16:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 liyifeng295641 于 2024-1-3 15:48 编辑

@FishC,下面是小甲鱼的课后练习题,每个case后面不是可以跟一个常量,为什么(例如 1.2之类)的float类型的不行,int 的就可以
  1. #include <stdio.h>

  2. int main(){
  3.        
  4.         float i;

  5.         printf("请输入一个小数:");
  6.         scanf("%f", &i);

  7.         switch(i){
  8.                 case 1.2: printf("1.2\n"); break;
  9.                 case 2.2: printf("2.2\n"); break;
  10.                 case 3.2: printf("3.3\n"); break;
  11.                 case 4.2: printf("4.4\n"); break;
  12.                 case 5.2: printf("5.5\n"); break;
  13.         }

  14.         return 0;
  15. }
复制代码
最佳答案
2023-12-26 14:16:33
在C语言中,switch语句的case后面只能跟整数或字符常量,不能直接跟浮点数常量,所以在你的代码中,当你将float类型的变量作为switch语句的表达式时,编译器会报错。

这是因为浮点数在计算机中表示方式的特殊性。浮点数的每个比特位都有特定的含义,它们分别用来表示符号、指数和尾数。由于浮点数在内存中并不是精确保存的,所以对比浮点数常量进行判断时可能会出现精度问题。

一般来说,在C语言中,如果想要比较两个浮点数是否相等,我们应该使用浮点数之差的绝对值与一个误差范围进行比较。具体做法如下:
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(){
  4.     float i;
  5.     printf("请输入一个小数:");
  6.     scanf("%f", &i);
  7.     if (fabs(i - 1.2) < 0.000001){
  8.         printf("1.2\n");
  9.     } else if (fabs(i - 2.2) < 0.000001){
  10.         printf("2.2\n");
  11.     } else if (fabs(i - 3.2) < 0.000001){
  12.         printf("3.2\n");
  13.     } else if (fabs(i - 4.2) < 0.000001){
  14.         printf("4.2\n");
  15.     } else if (fabs(i - 5.2) < 0.000001){
  16.         printf("5.2\n");
  17.     }
  18.     return 0;
  19. }
复制代码

在上面的代码中,我们使用`fabs()`函数求取两个浮点数之差的绝对值,并将其与一个极小的误差范围(例如0.000001)进行比较,来判断两个浮点数是否相等。

当然,如果只是简单的判断浮点数是否在某个范围内,我们也可以将浮点数转化为整数进行判断,例如:
  1. #include <stdio.h>
  2. int main(){
  3.     float i;
  4.     printf("请输入一个小数:");
  5.     scanf("%f", &i);
  6.     int x = i * 10; // 将浮点数乘以10,转化为整数
  7.     switch (x){
  8.         case 12: printf("1.2\n"); break;
  9.         case 22: printf("2.2\n"); break;
  10.         case 32: printf("3.2\n"); break;
  11.         case 42: printf("4.2\n"); break;
  12.         case 52: printf("5.2\n"); break;
  13.         default: printf("其他\n");
  14.     }
  15.     return 0;
  16. }
复制代码

在上述代码中,我们将输入的浮点数乘以10,并将结果转换为整数,然后再用整数进行switch判断。通过这种方式,我们可以判断浮点数是否在某个范围内。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-26 14:16:33 | 显示全部楼层    本楼为最佳答案   
在C语言中,switch语句的case后面只能跟整数或字符常量,不能直接跟浮点数常量,所以在你的代码中,当你将float类型的变量作为switch语句的表达式时,编译器会报错。

这是因为浮点数在计算机中表示方式的特殊性。浮点数的每个比特位都有特定的含义,它们分别用来表示符号、指数和尾数。由于浮点数在内存中并不是精确保存的,所以对比浮点数常量进行判断时可能会出现精度问题。

一般来说,在C语言中,如果想要比较两个浮点数是否相等,我们应该使用浮点数之差的绝对值与一个误差范围进行比较。具体做法如下:
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(){
  4.     float i;
  5.     printf("请输入一个小数:");
  6.     scanf("%f", &i);
  7.     if (fabs(i - 1.2) < 0.000001){
  8.         printf("1.2\n");
  9.     } else if (fabs(i - 2.2) < 0.000001){
  10.         printf("2.2\n");
  11.     } else if (fabs(i - 3.2) < 0.000001){
  12.         printf("3.2\n");
  13.     } else if (fabs(i - 4.2) < 0.000001){
  14.         printf("4.2\n");
  15.     } else if (fabs(i - 5.2) < 0.000001){
  16.         printf("5.2\n");
  17.     }
  18.     return 0;
  19. }
复制代码

在上面的代码中,我们使用`fabs()`函数求取两个浮点数之差的绝对值,并将其与一个极小的误差范围(例如0.000001)进行比较,来判断两个浮点数是否相等。

当然,如果只是简单的判断浮点数是否在某个范围内,我们也可以将浮点数转化为整数进行判断,例如:
  1. #include <stdio.h>
  2. int main(){
  3.     float i;
  4.     printf("请输入一个小数:");
  5.     scanf("%f", &i);
  6.     int x = i * 10; // 将浮点数乘以10,转化为整数
  7.     switch (x){
  8.         case 12: printf("1.2\n"); break;
  9.         case 22: printf("2.2\n"); break;
  10.         case 32: printf("3.2\n"); break;
  11.         case 42: printf("4.2\n"); break;
  12.         case 52: printf("5.2\n"); break;
  13.         default: printf("其他\n");
  14.     }
  15.     return 0;
  16. }
复制代码

在上述代码中,我们将输入的浮点数乘以10,并将结果转换为整数,然后再用整数进行switch判断。通过这种方式,我们可以判断浮点数是否在某个范围内。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-26 15:17:53 | 显示全部楼层
FishC 发表于 2023-12-26 14:16
在C语言中,switch语句的case后面只能跟整数或字符常量,不能直接跟浮点数常量,所以在你的代码中,当你将f ...

@FishC,根据小甲鱼出的题目,帮我看看我的代码哪里出错了!

                               
登录/注册后可看大图

  1. #include <stdio.h>

  2. char isSign(char ch){
  3.         switch(n){
  4.                 case '+':
  5.                         return num1 + num2;
  6.                 case '-':
  7.                         return num1 - num2;
  8.                 case 'x':
  9.                         return num1 * num2;
  10.                 case '/':
  11.                         return num1 / num1;
  12.         }

  13. }
  14. int main(){
  15.         float num1, num2, ch;
  16.         printf("请输入式子:");
  17.         scanf("%f %c %f", &num1, &ch, &num2);
  18.        
  19.         if(num2 != 0){
  20.                 printf("结果是:", isSign(ch));

  21.         }else{
  22.                 printf("很遗憾,除数不能为零!");
  23.         }
  24. }
复制代码

scanf输入的时候,为什么不能同时输入float和char的类型的参数。
我写的代码传参出了问题,我不知道哪里出了问题,帮我解答下。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-26 15:18:04 | 显示全部楼层
liyifeng295641 发表于 2023-12-26 15:17
@FishC,根据小甲鱼出的题目,帮我看看我的代码哪里出 ...

在你的代码中,存在一些问题:

1. 函数`isSign()`的形参应该是`char ch`而不是`n`,因为你在函数内部使用了`ch`来进行判断。

2. `isSign()`函数的返回值类型声明为`char`,但实际上你想要返回的是计算结果,应该将返回值类型声明为`float`或`int`。

3. 在`scanf`函数中,你应该使用`%f`来读取`float`类型的输入值,而不是`%c`。

4. 在调用`printf`函数时,你忘记了使用格式转换符`%f`来打印浮点数结果。

修改后的代码如下:
  1. #include <stdio.h>
  2. float isSign(char ch, float num1, float num2){
  3.     switch(ch){
  4.         case '+':
  5.             return num1 + num2;
  6.         case '-':
  7.             return num1 - num2;
  8.         case 'x':
  9.             return num1 * num2;
  10.         case '/':
  11.             return num1 / num2;
  12.     }
  13. }
  14. int main(){
  15.     float num1, num2;
  16.     char ch;
  17.    
  18.     printf("请输入式子:");
  19.     scanf("%f %c %f", &num1, &ch, &num2);
  20.    
  21.     if(num2 != 0){
  22.         printf("结果是:%f", isSign(ch, num1, num2));
  23.     }else{
  24.         printf("很遗憾,除数不能为零!");
  25.     }
  26.    
  27.     return 0;
  28. }
复制代码

请注意仔细阅读代码,并确保理解每一行的作用。如果还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-26 15:32:56 | 显示全部楼层
FishC 发表于 2023-12-26 15:18
在你的代码中,存在一些问题:

1. 函数`isSign()`的形参应该是`char ch`而不是`n`,因为你在函数内部使 ...

@FishC,帮我看看这个警告是什么?
test.c:10:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-26 15:33:11 | 显示全部楼层
liyifeng295641 发表于 2023-12-26 15:32
@FishC,帮我看看这个警告是什么?
test.c:10:1: warn ...

这个警告提示你的代码中存在一个函数没有在所有的控制路径上返回值。警告发生在第10行,也就是你的`isSign()`函数的结束位置。

出现这个警告的原因是你在`switch`语句中没有处理所有的情况。虽然你已经处理了`case '+'`、`case '-'`、`case 'x'`和`case '/'`,但是你没有针对其他情况编写`default`语句。当输入的`ch`不匹配任何一个`case`时,程序无法确定要返回什么值。

为了解决这个警告,你可以为`switch`语句添加一个`default`分支,并在其中返回一个默认值。根据你的需求,你可以选择返回一个合适的默认计算结果,或者返回一个错误标志。

以下是修改后的代码示例:
  1. #include <stdio.h>
  2. float isSign(char ch, float num1, float num2) {
  3.     switch(ch) {
  4.         case '+':
  5.             return num1 + num2;
  6.         case '-':
  7.             return num1 - num2;
  8.         case 'x':
  9.             return num1 * num2;
  10.         case '/':
  11.             return num1 / num2;
  12.         default:
  13.             printf("未知的运算符\n");
  14.             return 0.0; // 返回一个默认值
  15.     }
  16. }
  17. int main() {
  18.     float num1, num2;
  19.     char ch;
  20.     printf("请输入式子:");
  21.     scanf("%f %c %f", &num1, &ch, &num2);
  22.     if (num2 != 0) {
  23.         printf("结果是:%f", isSign(ch, num1, num2));
  24.     } else {
  25.         printf("很遗憾,除数不能为零!");
  26.     }
  27.     return 0;
  28. }
复制代码

在上述代码中,我们在`switch`语句中添加了`default`分支,并在该分支中打印了错误信息,并返回了默认值`0.0`。这样就可以确保在所有情况下都会返回一个值,消除了警告。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 17:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表