AI开发C语言应用按步走,表达式计算器calc的第十九步,注释、表达式分隔符、long double 精度

calc19 --- 注释、表达式分隔符、long double 精度

1. 概述

本次迭代新增三项功能,并对全局数值类型进行了精度升级:

  1. 注释支持 --- # 开头到行尾的内容被忽略
  2. 表达式分隔符 --- ; 分隔多个表达式,返回最后一个的值
  3. long double 精度 --- 全局 doublelong double,提升运算精度

2. 变更清单

文件 操作 说明
parse.h 编辑 新增 TOKEN_SEMICOLONToken.value 类型 doublelong double
parse.c 重写 # 注释跳过;; 解析为 TOKEN_SEMICOLONstrtold/strtoul 替换 strtod
eval.h 编辑 API 参数 double*long double*;新增 eval_exprs 声明
eval.c 重写 全部 doublelong doublefmodfmodl;新增 eval_exprs 实现
sym.h 编辑 API 参数 doublelong double
sym.c 编辑 SymEntry.value doublelong double%Lg
func.h 编辑 API 参数 double*long double*
func.c 重写 args/val doublelong doublesinl/cosll 后缀数学函数
main.c 重写 doublelong double%Lg;调用 eval_exprs 替代 eval_expr
test.expr 编辑 修复溢出测试值;新增 # 注释测试;修复 0b1010/0777 解析

3. 注释支持

parse_next 中,当遇到 # 时跳过直到行尾或字符串结束:

c 复制代码
if (*input_pos == '#') {
    while (*input_pos && *input_pos != '\n') { column++; input_pos++; }
    if (*input_pos == '\n') { line++; column = 1; input_pos++; }
    return parse_next();  /* 递归获取下一个 token */
}

示例

复制代码
calc> 3 + 5 # 这是注释
  8

4. 表达式分隔符

4.1 新增 eval_exprs API

c 复制代码
int eval_exprs(const char *input, long double *result);

循环解析多个以 ; 分隔的表达式,返回最后一个的值:

c 复制代码
int eval_exprs(const char *input, long double *result)
{
    parse_init(input); eval_error = 0;
    long double val = 0.0;
    while (!eval_error) {
        val = parse_expr();
        if (eval_error) return 1;
        Token t = parse_peek();
        if (t.type == TOKEN_SEMICOLON) {
            parse_consume();
            continue;
        }
        if (t.type != TOKEN_END) {
            print_error_context(t.col);
            fprintf(stderr, "  error: unexpected token after expression\n");
            return 1;
        }
        break;
    }
    *result = val; return 0;
}

4.2 使用

bash 复制代码
$ ./build/calc "1; 2; 3"
3

4.3 默认切换

parse_and_evalrepl 均改为调用 eval_exprs,因此 ; 分隔符在所有模式下均可使用。

5. long double 精度升级

5.1 涉及范围

组件 类型变更 影响
Token 数值 doublelong double 解析和存储
求值器 doublelong double 全部运算
符号表 doublelong double 变量值
函数表 doublelong double 参数和返回值
主程序 doublelong double 输出格式 %Lg

5.2 数学函数后缀

所有 <math.h> 函数调用改为 l 后缀版本:

函数 原版 long double 版
正弦 sin sinl
余弦 cos cosl
正切 tan tanl
平方根 sqrt sqrtl
幂运算 pow powl
取模 fmod fmodl
绝对值 fabs fabsl

5.3 精度提升

类型 尾数位数 十进制精度 最大值
double 53 bits ~15 位 ~1.79e308
long double 64 bits ~19 位 ~1.19e4932

6. 测试验证

bash 复制代码
$ make test
============================================
  calc --- 测试套件
============================================
  PASS  [ 1] (90-18)/3+15           → 39
  ...
  PASS  [30] 1e5000*1e5000          → error
  ...
  PASS  [61] 0b1010                 → 10
  PASS  [62] 0777                   → 511
  ...
  PASS  [122] 3+5 # comment          → 8
============================================
  122 passed, 0 failed, 122 total
============================================
相关推荐
崖边看雾1 小时前
Python学习——函数
开发语言·windows·python·学习·pycharm
宸津-代码粉碎机1 小时前
Jar热部署进阶实战|修复原生方案OOM与类冲突问题,生产级无BUG优化方案
java·大数据·服务器·开发语言·前端·人工智能·python
互联网中的一颗神经元12 小时前
小白python入门 - 39. 采集流水线小项目
开发语言·python
Wang's Blog12 小时前
Go-Zero 项目开发22:用户群聊功能的实现与完善
开发语言·golang
a11177612 小时前
坦克大战3D Three.js 3D (开源项目)
开发语言·javascript·3d
Wang's Blog14 小时前
Go-Zero项目开发24: 基于Bitmap实现群聊消息已读未读
开发语言·后端·golang
ziguo112216 小时前
深入浅出 C/C++ 数据类型:从入门到踩坑
linux·c语言·c++·windows·visual studio
吃好睡好便好17 小时前
MATLAB中图像的读取、写入和显示
开发语言·图像处理·学习·计算机视觉·matlab
yaoxin52112317 小时前
476. Java 反射 - 调用方法
java·开发语言