找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: buyiyang

[数值计算] 【已解决】批处理的整数变量是如何解析存储的?

[复制链接]
发表于 2023-9-25 01:41:57 | 显示全部楼层
补充一些细节,
  1. long wcstol( const wchar_t *nptr, wchar_t **endptr, intbase);

  2. 释义:将字符串类型根据不同的基转化数字形式。

  3. 其中:[in] nptr 表示要进行扫描字符串指针

  4. [out] endptr  存储扫描后无法转化的剩余的字符串
复制代码
也就是说,读取后剩余部分会覆盖掉原来的tas
下面if的意思是,假如读取后的剩余部分的第一个字符还是数字或者字母的话,那么失败
例子:1000a执行后还剩下a,所以解析失败。
而2147483648由于超出32bit正数范围,解析后tas会指向8,读进去的数字是214748364,由于现在指向的还是一个数字,if命中,命令报错。

评分

参与人数 1技术 +1 收起 理由
buyiyang + 1 乐于助人

查看全部评分

发表于 2023-9-25 08:09:40 | 显示全部楼层
不明觉厉
 楼主| 发表于 2023-9-25 17:10:06 | 显示全部楼层
本帖最后由 buyiyang 于 2023-9-25 19:15 编辑

回复 12# 老刘1号


    大概明白了,算数运算的解析字符串表达式是逐字符的,-首先被解析,被解析为操作符了,然后后面的数字2147483648被解析为操作数,操作数字符串要转长整型,过程中由于溢出遇到错误tas会指向最后停止的位置,判断指向的是数字8就会报错。

    十分感谢@老刘1号提供的源码!基于第二个源码我再详细理解一下解析过程,有几个重要的变量,bUnaryOpPossible来判断是否允许一元操作符出现,初始值为TRUE。然后c=*tas,c是TCHAR类型的,c那么就是tas字符串数组的第一个字符,然后判断c是空白、字母、数字、操作符还是变量名,空白字符删除,操作符压入操作符栈,变量名压入操作数栈,变量名存储在 lOperands 数组中的Name字段,计算表达式时从环境变量中获取其值,如果是数字就从对tas字符串进行_tcstol处理转成长整型,遇到错误就将指针指向最后停止的位置,去除tas字符串前面成功转成长整型的部分。每判断一个字符,都会tas += 1,去除tas字符串中前一个已经判断过的字符。进行do while循环中直到尾tas字符串\0。

    比如,set /a n=1+1,对于字符串"n=11+1",首先指针指向n,c为'n',判断为变量名,然后指针移到=,判断为操作符,指针移到1,判断为数字,对"11+1"进行_tcstol处理,在+遇到错误,11转成长整型作为操作数,指针移到+,判断为操作符,指针移到1,判断为数字,对"1"进行_tcstol处理,1转成长整型作为操作数,指针移到\0,循环结束。
 楼主| 发表于 2023-9-25 17:28:25 | 显示全部楼层
回复 15# 老刘1号
进行_tcstol的时候c已经是一个dight了,而c=*tas,那么也就是说tas指向的字符串是数字开头的

这个是如何看出来的?
发表于 2023-9-25 17:34:07 | 显示全部楼层
回复 19# buyiyang


    见第二个文件的69和75行
 楼主| 发表于 2023-9-25 17:44:07 | 显示全部楼层
回复 20# 老刘1号


    这里从tas字符数组第一个地址开始判断每个字符是空白、字母、数字、操作符,如何得出tas指向的字符串是数字开头的?do循环中,c=*tas应该是tas字符数组的第一个字符,判断完后,然后tas += 1,再赋值c=*tas是tas字符数组的第二个字符。
发表于 2023-9-25 18:44:12 | 显示全部楼层
回复 21# buyiyang


   可能我表述不太清晰,你可以理解为tas指向的子串(原字符串去掉了前面若干字符剩余的部分)
因为c的字符串本质上就是指向以0结尾的字节数组的指针嘛,指针+1了指向的那个字符串就变化了(相当于最前面的字符就没了)。
 楼主| 发表于 2023-9-25 19:10:15 | 显示全部楼层
回复 22# 老刘1号


    可能误解你的意思了,你的意思是:c=*tas,当能进行_tcstol的时候说明c是一个dight,此时tas指向的字符串是数字开头的。明白了,我以为你说一开始的tas
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-18 06:35 , Processed in 0.019171 second(s), 7 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表