为何断言宏对≤0整数不生效却对超INT_MAX值生效?如何改进?
问题分析与修复方案
首先,你的代码里有两个核心问题导致了当前的异常现象,咱们逐个拆解:
1. 断言的逻辑完全写反了
assert()的工作规则是:只有当括号内的表达式结果为false时,才会触发断言失败并打印错误信息。你现在写的是:
assert(total_digits <= 0 && "错误信息");
这意味着只有当total_digits <= 0为true时,整个表达式才是true,断言不会触发——这和你想要的“输入≤0时报错”完全相反!你应该把判断条件反过来,改成检查输入是否合法,这样当输入不合法时,表达式为false,断言才会触发。
2. int变量永远不可能超过INT_MAX
total_digits是int类型,它的取值范围本身就被限定在INT_MIN到INT_MAX之间。如果输入的值超过INT_MAX,scanf("%d", &total_digits)会触发未定义行为,此时total_digits的值是混乱的,根本不可能出现total_digits > INT_MAX的情况,所以这个断言永远不会被触发。
修复后的代码示例
我们可以用long long类型先接收输入,这样就能安全判断输入是否超出int的范围,同时修正断言的逻辑:
#include <stdio.h> #include <assert.h> #include <limits.h> void compute_no_of_pages(int n) { // 这里是你的函数实现 } int main() { long long input; // 用更大的类型接收输入,避免溢出问题 while (scanf("%lld", &input) == 1) { // 检查scanf是否成功读取了有效整数 // 检查输入是否≤0,不合法则触发断言 assert(input > 0 && "Whoops your input data cannot be less or equal to 0. Please rerun the program and enter another input data."); // 检查输入是否超过INT_MAX,不合法则触发断言 assert(input <= INT_MAX && "Whoops your input data cannot be bigger than 2147483647. Please rerun the program and enter another input data."); int total_digits = (int)input; // 输入合法时转换为int类型 compute_no_of_pages(total_digits); } return 0; }
额外补充说明
- 加入了
scanf返回值检查:scanf("%lld", &input) == 1确保我们成功读取了一个整数,如果输入的是字母、符号等非数字内容,循环会终止,避免后续的无效判断。 - 用
long long中转输入,能安全存储超过INT_MAX的值,这样我们就能准确判断输入是否超出int的合法范围。 - 断言逻辑修正为检查合法条件,只有当输入不满足合法要求时,断言才会触发错误提示。
内容的提问来源于stack exchange,提问作者Neri-kun
相关产品推荐
相关产品推荐

