cmd.exe(批处理)脚本中的数组、链表等数据结构

标签 arrays windows batch-file cmd delayedvariableexpansion

我在玩 cmd.exe,但在它的帮助中我没有找到任何信息,如何定义数组。

我发现,如何定义简单变量:

set a=10
echo %a%

但是,我想创建数组、链表等...

那么,它是否能够在 cmd.exe 中使用(我的意思是:在 cmd.exe 中是否存在任何数组关键字?)

我想将一些算法实现为:
  • 冒泡排序
  • 快速排序
  • 侏儒排序

  • 等等...

    所以,我也想知道,Cmd.exe 是否有引用或实例、结构等?

    原因是它的帮助不是完整的:/?

    Cmd.exe 可以被图灵机定义定义为完整的吗? (图灵完备)

    最佳答案

    好的。我会尽量说清楚,以免被误解......

    在 Windows 批处理文件中,变量名称应以字母开头,并且可以包含任何有效字符,其中有效字符是:#$'()*+,-.?@[]_`{}~ 除了字母和数字。

    这意味着从 cmd.exe 的角度来看,SET NORMAL_NAME=123SET A#$'()*+,-.?@[\]_{}~=123 完全相同也与 SET VECTOR[1]=123 相同;这三个都是正常变量。这样,您就可以以数组元素的形式编写变量名:

    set elem[1]=First element
    set elem[2]=Second one
    set elem[3]=The third one
    

    这样,echo %elem[2]%将显示 Second one .

    如果你想使用另一个变量作为索引,你必须知道用它们的值替换百分号包围的变量是从左到右解析的;这意味着:
    set i=2
    echo %elem[%i%]%
    

    没有给出想要的结果,因为这意味着:显示 elem[ 的值变量,后跟 i ,后跟 ] 的值多变的。

    要解决这个问题必须使用延迟扩展,即插入setlocal EnableDelayedExpansion命令开头,索引变量用百分号括起来,数组元素用感叹号括起来:
    setlocal EnableDelayedExpansion
    set elem[1]=First element
    set elem[2]=Second one
    set elem[3]=The third one
    set i=2
    echo !elem[%i%]!
    

    你也可以使用 FOR 命令的参数作为索引:for /L %%i in (1,1,3) do echo !elem[%%i]! .您必须使用 !index!在 FOR 或 IF 中更改索引时将值存储在数组元素中:set elem[!index!]=New value .要在 FOR/IF 内的索引更改时获取元素的值,请将元素括在双百分号中并在命令前加上 call .例如,要将一系列数组元素向左移动四位:
    for /L %%i in (%start%,1,%end%) do (
       set /A j=%%i + 4
       call set elem[%%i]=%%elem[!j!]%%
    )
    

    实现前面过程的另一种方法是使用额外的 FOR 命令将索引的延迟扩展更改为等效的可替换参数,然后对数组元素使用延迟扩展。此方法比之前的 CALL 运行得更快:
    for /L %%i in (%start%,1,%end%) do (
       set /A j=%%i + 4
       for %%j in (!j!) do set elem[%%i]=!elem[%%j]!
    )
    

    这样,批处理文件的行为就像管理数组一样。我认为这里的重点不是讨论 Batch 是否管理数组,而是您可以以与其他编程语言等效的方式管理 Batch 文件中的数组这一事实。
    @echo off
    setlocal EnableDelayedExpansion
    
    rem Create vector with names of days
    set i=0
    for %%d in (Sunday Monday Tuesday Wednesday Thrusday Friday Saturday) do (
       set /A i=i+1
       set day[!i!]=%%d
    )
    
    rem Get current date and calculate DayOfWeek
    for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
       set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c
    )
    if %mm% lss 3 set /A mm=mm+12, yy=yy-1
    set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, jdn=c+dd+e+f-1523, dow=jdn %% 7 + 1
    echo Today is !day[%dow%]!, %date%
    

    请注意,索引值不限于数字,它们可以是任何包含有效字符的字符串;这一点允许定义其他编程语言中的名称 associative arrays .在 this answer对使用关联数组解决问题的方法进行了详细说明。另请注意,空格是变量名中的有效字符,因此您必须注意不要在变量名中插入可能被忽视的空格。

    我在 this post 详细说明了必须在批处理文件中使用数组表示法的原因.

    this post有一个批处理文件,它读取文本文件并将行的索引存储在向量中,然后根据行内容对向量元素进行 Buble 排序;等效的结果是对文件内容进行排序。

    this post Batch 中有一个基于文件中存储的索引的基本关系数据库应用程序。

    this post Batch中有一个完整的多链表应用程序,它组装了一个从子目录中取出的大数据结构,并以TREE命令的形式显示出来。

    关于cmd.exe(批处理)脚本中的数组、链表等数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45381346/

    相关文章:

    javascript - 如何合并 2 个 javascript 对象,如果另一个对象中不存在属性,则填充一个对象中的属性?

    javascript - 使用 .map 将对象添加到数组时出现意外标记 {

    arrays - 垃圾收集器是否保留仅由原始指针引用的数组?

    python - 不确定如何修复此 Cmd 命令错误?

    windows - 远程更改 Windows 7 墙纸

    batch-file - 用于删除目录中具有唯一根茎的文件的批处理脚本

    javascript - 出现在我的 javascript 数组中的未识别值

    c++ - 定时器的使用

    windows - 如何使用批处理脚本对目录中的每个文件执行某些操作

    java - 在 Java 中运行批处理文件