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
============================================
相关推荐
jason成都2 小时前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙2 小时前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github
caimouse2 小时前
ReactOS 图形系统分析(38):区域子系统 — region.c
c语言
嵌入式阿蔡3 小时前
STM32时钟树详解:配错一个全乱套
c语言·stm32·单片机·嵌入式硬件
MarkHD3 小时前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion
云水初3 小时前
【agent篇】RAG 知识库构建避坑指南
开发语言·python·学习·agent·rag
2019一路前行3 小时前
Python 函数、循环语句
开发语言·python
caimouse3 小时前
ReactOS 图形系统分析(37):路径子系统 — path.c
c语言·reactos
CarIise4 小时前
C语言基础课程笔记:硬件原理、数据类型、结构体与格式化输入输出详解
c语言·开发语言·笔记
leoZ2314 小时前
Vue3 还原一个企业级后台-14-项目总结
开发语言·人工智能·后端·opencv·计算机视觉·数据挖掘·rust