如何确定unsigned int的取值范围?输入校验作业相关问题
确定本机unsigned int的取值范围
直接用标准头文件<limits.h>里的UINT_MAX宏即可——它会在编译时自动适配本机unsigned int的位数,比如32位系统对应4294967295(232-1),16位系统对应`65535`(216-1),完全不需要硬编码任何固定数值。另外,unsigned int的最小值固定是0,因为无符号类型没有负数区间。
输入校验的正确姿势(避免溢出)
直接用unsigned int变量接收输入会触发无符号整数溢出,而C标准里无符号溢出是定义为模2^N运算的,溢出后的值会被自动截断,根本没法判断原始输入是否超出范围。推荐两种可靠的校验思路:
方法1:用更宽的整数类型中转(如果平台支持)
如果本机有比unsigned int更宽的无符号类型(比如unsigned long long),可以先把输入读到这个大类型里,再和UINT_MAX做比较:
#include <stdio.h> #include <limits.h> int main() { unsigned long long input; if (scanf("%llu", &input) != 1) { printf("输入不是有效的无符号整数\n"); return 1; } if (input > UINT_MAX) { printf("输入超出unsigned int范围\n"); return 1; } unsigned int val = (unsigned int)input; printf("输入有效:%u\n", val); return 0; }
注意:如果你的平台上unsigned long long和unsigned int宽度相同(比如某些嵌入式系统),这个方法会失效,得用下面的字符串校验法。
方法2:字符串读取后逐位校验
读取输入的字符串,直接和UINT_MAX的字符串形式对比,从根源上避免溢出问题:
#include <stdio.h> #include <limits.h> #include <string.h> #include <ctype.h> int main() { char buf[20]; // 足够容纳64位无符号整数的字符串长度 if (scanf("%19s", buf) != 1) { printf("输入错误\n"); return 1; } // 先检查输入是否全为数字 for (int i = 0; buf[i] != '\0'; i++) { if (!isdigit(buf[i])) { printf("输入不是有效的无符号整数\n"); return 1; } } // 把UINT_MAX转换成字符串 char max_str[20]; snprintf(max_str, sizeof(max_str), "%u", UINT_MAX); // 比较字符串长度和内容 size_t input_len = strlen(buf); size_t max_len = strlen(max_str); if (input_len > max_len) { printf("输入超出unsigned int范围\n"); return 1; } else if (input_len == max_len && strcmp(buf, max_str) > 0) { printf("输入超出unsigned int范围\n"); return 1; } // 此时转换不会溢出,直接转成unsigned int即可 unsigned int val; sscanf(buf, "%u", &val); printf("输入有效:%u\n", val); return 0; }
这个方法适配所有平台,不管unsigned int是多少位,完全不需要预设任何范围值。
内容的提问来源于stack exchange,提问作者Anthu.ny
相关产品推荐
相关产品推荐

