AI开发C语言应用按步走,表达式计算器calc的第二十步,魔法数修复、测试分隔符、位运算截断检查、进制溢出检查

calc20 --- 魔法数修复、测试分隔符、位运算截断检查、进制溢出检查

1. 概述

本次迭代从 suggestions.md 中选取了 4 个待改进项进行修复,涵盖代码质量、测试框架和运行时健壮性三个方面。

修复项

编号 问题 类型
C1 var_name[32] 魔法数 代码质量
G3 测试文件分隔符与表达式分隔符 ; 冲突 测试框架
G4 位运算截断 int 无警告 运行时健壮性
G5 进制数溢出无检查 运行时健壮性

2. 变更清单

文件 操作 说明
main.c 编辑 var_name[32]var_name[MAX_NAME](2 处)
test.expr 编辑 分隔符 ; → `````(反引号),避免与表达式分隔符 ; 冲突
Makefile 编辑 IFS=';'IFS='\'`
eval.c 编辑 新增 #include <limits.h> + check_int_trunc() 函数;6 处 (int) 转换前添加截断检查
parse.c 编辑 新增 #include <errno.h> + #include <stdio.h>;3 处 strtoul 后添加 errno == ERANGE 溢出检查

3. C1 --- var_name[32] 魔法数

3.1 改造前

c 复制代码
char var_name[32];

硬编码的 32,与 parse.hToken.name[32] 无显式关联。

3.2 改造后

c 复制代码
char var_name[MAX_NAME];

MAX_NAMEparse.h 中定义为 32,两处统一引用,修改一端时同步更新。

4. G3 --- 测试文件分隔符

4.1 问题

test.expr 使用 ; 作为字段分隔符,但 ; 现在也是合法的表达式分隔符(表达式分隔功能),导致 1;2;3 等表达式无法在测试文件中使用。

4.2 方案

将分隔符改为反引号 `````,原因:反引号在 calc 的词法分析器中永远为非法字符(TOKEN_ERROR),不会与任何合法表达式冲突。

文件 改动
test.expr ; → `````
Makefile IFS=';'IFS='\'`

同时保留了 ; 作为表达式分隔符的功能不变。

5. G4 --- 位运算截断检查

5.1 问题

eval.c 中位运算操作数先转为 int(32 位),超出 INT_MAX(2147483647)的值被静默截断,用户得不到提示。

5.2 方案

新增 check_int_trunc 函数,在 6 处 (int) 转换前调用:

c 复制代码
static int check_int_trunc(long double v)
{
    if (v > INT_MAX || v < INT_MIN) {
        fprintf(stderr, "  warning: value truncated to int\n");
        return 1;
    }
    return 0;
}

调用位置:parse_bitorparse_bitxorparse_bitandparse_shift(SHL/SHR)、parse_unary(BITNOT)。

6. G5 --- 进制数溢出检查

6.1 问题

parse.cstrtoul 解析十六进制/二进制/八进制数字时,超出 unsigned long 范围的值被静默截断为 ULONG_MAX,用户得不到提示。

6.2 方案

在每个 strtoul 调用前重置 errno = 0,调用后检查 errno == ERANGE

c 复制代码
errno = 0;
val = (long double)strtoul(input_pos, &end, 16);
if (errno == ERANGE)
    fprintf(stderr, "  warning: integer overflow\n");

7. 测试验证

bash 复制代码
$ make test
============================================
  calc --- 测试套件
============================================
  122 passed, 0 failed, 122 total
============================================

全部 122 个回归测试通过,功能不变,新增的检查仅在溢出/截断时输出警告,不影响正常计算结果。

相关推荐
大牧师28 分钟前
Nest.js 微服务入门教程
开发语言·javascript·后端·微服务·node.js·nest.js·nest
格林威32 分钟前
C# 图像异步落盘存储:基于Channel 配合 ArrayPool 实现异步落盘
开发语言·人工智能·数码相机·机器学习·计算机视觉·c#·视觉检测
软件黑马王子33 分钟前
11.缓存池优化:窗口布局
开发语言·前端框架·c#
深圳市益普科技有限公司37 分钟前
半导体MES的数字孪生:虚拟调试如何把上线风险提前清零
java·开发语言
低代码布道师44 分钟前
外包项目管理平台全栈实战课02搭建数据底座:Next.js + PostgreSQL + Prisma 7
开发语言·javascript·postgresql·全栈开发
格林威1 小时前
C# 图像使用AVX2指令集:使用OpenCvSharp实现字节图像解压缩速度和map_image算子速度提升
开发语言·图像处理·人工智能·计算机视觉·c#·视觉检测·工业相机
(Charon)1 小时前
【C++】网络缓冲区设计(四):epoll + Reactor中Buffer的完整读写流程
开发语言·c++
西西弗Sisyphus1 小时前
Qt 实现一个 Windows 启动项查看器
开发语言·windows·qt
FfHUCisI1 小时前
Golang 函数调用的瞬间:栈帧、拷贝栈与逃逸分析
开发语言·后端·golang