鱼C论坛

 找回密码
 立即注册
查看: 2293|回复: 4

[已解决]关于s1e13 动动手2进阶疑问

[复制链接]
发表于 2022-6-7 23:51:06 | 显示全部楼层    本楼为最佳答案   
确实奇怪,为什么会没有人帮你呢?
我帮你看了看,你的思路是对的
但是这么写不是很好,我的调试器检查出了这个溢出
还是强制转换一下unsigned类型吧
  1. $ cat main.c
  2. #include <stdio.h>

  3. int main() {
  4.     int ch, num = 0, num0; // ch为输入的字符,num存储结果用的整形数值
  5.     printf("请输入待转换的字符串:");
  6.     do {
  7.         ch = getchar();
  8.         if(ch >= '0' && ch <= '9') {
  9.             num0 = num; //临时存储,用于比较是否溢出
  10. #if 1
  11.             num = 10 * num + (ch - '0'); //按照10进制记录已读入的值
  12. #else
  13.             num = (unsigned)10 * num + (ch - '0'); //按照10进制记录已读入的值
  14. #endif
  15.             if(num < num0)
  16.                 break; //溢出了,跳出循环,不再读取字符。
  17.         } else if(num) break; //不是数字,则跳出循环。
  18.     } while((ch != '\n'));

  19.     if(num < num0) //溢出时打印结果
  20.         printf("数值超出范围,结果未定义!\n");
  21.     else if(num != 0) //正常时打印结果
  22.         printf("结果是:%d\n", num);
  23.     else
  24.         printf("并未找到任何数值!\n"); //没有数字时打印结果

  25.     return 0;
  26. }
  27. $ gcc-debug -o main main.c
  28. $ ./main
  29. 请输入待转换的字符串:2147483647
  30. 结果是:2147483647
  31. $ ./main
  32. 请输入待转换的字符串:2147483648
  33. main.c:11:17: runtime error: signed integer overflow: 2147483640 + 8 cannot be represented in type 'int'
  34. 数值超出范围,结果未定义!
  35. $
  36. $
  37. $
  38. $ vim main.c
  39. $ cat main.c
  40. #include <stdio.h>

  41. int main() {
  42.     int ch, num = 0, num0; // ch为输入的字符,num存储结果用的整形数值
  43.     printf("请输入待转换的字符串:");
  44.     do {
  45.         ch = getchar();
  46.         if(ch >= '0' && ch <= '9') {
  47.             num0 = num; //临时存储,用于比较是否溢出
  48. #if 0
  49.             num = 10 * num + (ch - '0'); //按照10进制记录已读入的值
  50. #else
  51.             num = (unsigned)10 * num + (ch - '0'); //按照10进制记录已读入的值
  52. #endif
  53.             if(num < num0)
  54.                 break; //溢出了,跳出循环,不再读取字符。
  55.         } else if(num) break; //不是数字,则跳出循环。
  56.     } while((ch != '\n'));

  57.     if(num < num0) //溢出时打印结果
  58.         printf("数值超出范围,结果未定义!\n");
  59.     else if(num != 0) //正常时打印结果
  60.         printf("结果是:%d\n", num);
  61.     else
  62.         printf("并未找到任何数值!\n"); //没有数字时打印结果

  63.     return 0;
  64. }
  65. $ gcc-debug -o main main.c
  66. $ ./main
  67. 请输入待转换的字符串:2147483648
  68. 数值超出范围,结果未定义!
  69. $
复制代码



如果不考虑负数的话,可以直接作为无符数来计算
超过了0x80000000就是溢出(包括这个数)

  1. $ cat main.c
  2. #include <stdio.h>

  3. int main() {
  4.     //int ch, num = 0, num0; // ch为输入的字符,num存储结果用的整形数值
  5.     int ch;
  6.     unsigned int num = 0;
  7.     printf("请输入待转换的字符串:");
  8.     do {
  9.         ch = getchar();
  10.         if(ch >= '0' && ch <= '9') {
  11.             num = num * 10 + (ch - '0');

  12.             if(num >= 0x80000000) break; //溢出了,跳出循环,不再读取字符。

  13.         } else if(num) break; //不是数字,则跳出循环。
  14.     } while((ch != '\n'));

  15.     if(num >= 0x80000000) //溢出时打印结果
  16.         printf("数值超出范围,结果未定义!\n");
  17.     else if(num != 0) //正常时打印结果
  18.         printf("结果是:%d\n", num);
  19.     else
  20.         printf("并未找到任何数值!\n"); //没有数字时打印结果

  21.     return 0;
  22. }
  23. $ gcc-debug -o main main.c
  24. $ ./main
  25. 请输入待转换的字符串:2147483648
  26. 数值超出范围,结果未定义!
  27. $ ./main
  28. 请输入待转换的字符串:2147483647
  29. 结果是:2147483647
  30. $
复制代码



你的这个程序还有一个bug
0是不是数字,0是数字
但是
  1. $ cat main.c
  2. #include <stdio.h>

  3. int main() {
  4.     int ch, num = 0, num0; // ch为输入的字符,num存储结果用的整形数值
  5.     printf("请输入待转换的字符串:");
  6.     do {
  7.         ch = getchar();
  8.         if(ch >= '0' && ch <= '9') {
  9.             num0 = num; //临时存储,用于比较是否溢出
  10. #if 1
  11.             num = 10 * num + (ch - '0'); //按照10进制记录已读入的值
  12. #else
  13.             num = (unsigned)10 * num + (ch - '0'); //按照10进制记录已读入的值
  14. #endif
  15.             if(num < num0)
  16.                 break; //溢出了,跳出循环,不再读取字符。
  17.         } else if(num) break; //不是数字,则跳出循环。
  18.     } while((ch != '\n'));

  19.     if(num < num0) //溢出时打印结果
  20.         printf("数值超出范围,结果未定义!\n");
  21.     else if(num != 0) //正常时打印结果
  22.         printf("结果是:%d\n", num);
  23.     else
  24.         printf("并未找到任何数值!\n"); //没有数字时打印结果

  25.     return 0;
  26. }
  27. $ gcc-debug -o main main.c
  28. $ ./main
  29. 请输入待转换的字符串:0
  30. 并未找到任何数值!
  31. $ ./main
  32. 请输入待转换的字符串:abcd1234
  33. 结果是:1234
  34. $ ./main
  35. 请输入待转换的字符串:abcd0
  36. 并未找到任何数值!
  37. $ ./main
  38. 请输入待转换的字符串:abcd0000
  39. 并未找到任何数值!
  40. $
复制代码


这个bug自己改吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-7 23:58:54 | 显示全部楼层
    if(num < num0) //溢出时打印结果
        printf("数值超出范围,结果未定义!\n");

这个报错说的很好了,数值超出范围,结果未定义!
既然结果未定义,那你怎么能依赖这个未定义的结果来写这个程序呢?

我的调试器捕捉到了这个问题,报了下面这个错误
强制转换一下unsigned类型就可以了
  1. main.c:11:17: runtime error: signed integer overflow: 2147483640 + 8 cannot be represented in type 'int'
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-1 12:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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