CMD与DOS脚本编程【第四章】
预计更新
第一章. 简介和基础命令
1.1 介绍cmd/dos脚本语言的概念和基本语法
1.2 讲解常用的基础命令和参数,如echo、dir、cd等
第二章. 变量和运算符
2.1 讲解变量和常量的定义和使用方法
2.2 介绍不同类型的运算符和运算规则
第三章. 控制流程和条件语句
3.1 介绍if、else、for、while等控制语句的用法
3.2 讲解条件语句的语法和应用场景
第四章. 函数和参数传递
4.1 讲解如何定义和调用函数以及传递参数
4.2 介绍函数的作用域和递归调用
第五章. 文件操作
5.1 讲解如何创建、读取、写入和删除文件
5.2 介绍文件操作的常用命令和参数,如copy、del、type等
第六章. 环境变量和系统信息
6.1 介绍环境变量的概念和设置方法
6.2 讲解如何获取系统信息,如系统时间、用户名等
第七章. 网络通信和远程控制
7.1 介绍如何使用cmd/dos脚本语言进行网络通信
7.2 讲解如何使用远程控制命令,如telnet、net等
第八章. 错误处理和调试技巧
8.1 介绍常见的错误类型和处理方法
8.2 讲解如何使用调试工具和技巧
第九章. 脚本编写和调试实战
9.1 提供一些实际案例,让读者通过编写和调试脚本来加深理解和掌握技能
9.2 讲解如何测试和优化脚本性能
第十章. 其他高级主题和扩展
10.1 讲解其他高级主题,如正则表达式、批处理、交互式命令等
10.2 介绍如何扩展和定制cmd/dos脚本语言的功能和特性
第四章. 函数和参数传递4.1 讲解如何定义和调用函数以及传递参数4.2 介绍函数的作用域和递归调用
讲解如何定义和调用函数以及传递参数
本文将深入讲解在 cmd 和 DOS 脚本语言编程中如何定义和调用函数以及传递参数的方法和技巧。我们将从函数的概念和语法开始,讨论函数的定义、调用和返回值的使用。然后,我们将介绍参数的传递方式和如何在函数中使用它们。最后,我们将通过实例来演示如何使用函数和参数来编写实际的脚本程序。
一、函数的概念和语法
在 cmd 和 DOS 脚本语言中,函数是一组可重用的代码块,用于完成特定的任务。函数可以接受输入参数并返回值。函数的定义格式如下:
:label
command1
command2
...
goto :eof
其中,:label
是函数的名称,可以由用户自定义,但必须以冒号开头。command1
、command2
等是函数的主体,用于执行特定的任务。goto :eof
表示函数的结束,其中 :eof
是 cmd 中预定义的标签,表示文件的末尾。
为了调用函数,我们需要在脚本中使用函数名称加上参数列表的形式来调用函数。例如:
call :functionName parameter1 parameter2 ...
其中,call
是 cmd 中调用函数的关键字,functionName
是函数的名称,parameter1
、parameter2
等是函数的输入参数。
二、函数的定义和调用
函数的定义是编写脚本程序的重要部分,正确的定义可以使代码更加清晰和易于维护。下面是一个简单的函数定义示例:
:myFunction
echo "This is my function."
goto :eof
在上述示例中,我们定义了一个名为 myFunction
的函数,函数主体中使用 echo
命令输出了一条消息。goto :eof
表示函数结束,这也是 cmd 中标准的函数结束方式。
要调用函数,我们需要在脚本中使用 call
命令,并指定需要调用的函数名称和输入参数。下面是一个调用 myFunction
函数的示例:
call :myFunction
在上述示例中,我们使用 call
命令调用了 myFunction
函数。因为我们在函数定义中没有定义任何输入参数,所以在调用函数时不需要传递任何参数。
三、函数的返回值
在函数中,我们可以使用 set
命令来设置函数的返回值。下面是一个简单的函数定义示例,该函数返回传递的第一个参数:
:returnValue
set returnValue=%1
goto :eof
在上述示例中,我们定义了一个名为 returnValue
的函数,函数主体中使用 set
命令设置了返回值为传递的第一个参数。在函数结束时,我们使用 goto :eof
命令表示函数结束。
在调用函数时,我们可以使用 %returnValue%
的形式来访问函数的返回值。下面是一个示例,展示了如何调用 returnValue
函数并访问其返回值:
call :returnValue parameter1
echo The return value is %returnValue%.
在上述示例中,我们使用 call
命令调用了 returnValue
函数,并传递了一个参数 parameter1
。然后,使用 %returnValue%
访问函数的返回值,并使用 echo
命令输出。
需要注意的是,在函数中设置的变量只能在函数内部使用,无法在函数外部访问。如果需要在函数外部访问函数的返回值,可以使用 setlocal
和 endlocal
命令来设置局部变量。
四、函数的参数传递
在 cmd 和 DOS 脚本语言中,函数支持两种类型的参数传递方式:位置参数和命名参数。
- 位置参数
位置参数是指在函数调用时按照顺序传递的参数,它们的顺序对应着函数定义中的参数顺序。下面是一个示例,展示了如何在函数中使用位置参数:
:sum
set /a result=%1+%2
goto :eof
在上述示例中,我们定义了一个名为 sum
的函数,函数主体中使用 set /a
命令计算传递的前两个位置参数的和,并将结果保存在 result
变量中。在函数结束时,我们使用 goto :eof
命令表示函数结束。
在调用函数时,我们可以按照顺序传递参数。下面是一个示例,展示了如何调用 sum
函数并传递两个位置参数:
call :sum 3 5
echo The result is %result%.
在上述示例中,我们使用 call
命令调用了 sum
函数,并传递了两个位置参数 3
和 5
。然后,使用 %result%
访问函数的返回值,并使用 echo
命令输出。
需要注意的是,在函数中使用位置参数时,可以使用 %1
、%2
等来访问它们。例如,在上述示例中,我们可以使用 %1
和 %2
来访问传递的位置参数。
- 命名参数
命名参数是指在函数调用时使用名称和值的形式传递的参数。命名参数可以使代码更易于阅读和维护,因为它们不依赖于参数的顺序。下面是一个示例,展示了如何在函数中使用命名参数:
:concat
set concatResult=%param1%%param2%
goto :eof
在上述示例中,我们定义了一个名为 concat
的函数,函数主体中使用 set
命令将传递的两个命名参数按顺序拼接在一起,并将结果保存在 concatResult
变量中。在函数结束时,我们使用 goto :eof
命令表示函数结束。
在调用函数时,我们可以使用名称和值的形式传递参数。下面是一个示例,展示了如何调用 concat
函数并传递两个命名参数:
call :concat param1=Hello param2=World
echo The result is %concatResult%.
在上述示例中,我们使用 call
命令调用了 concat
函数,并传递了两个命名参数 param1=Hello
和 param2=World
。然后,使用 %concatResult%
访问函数的返回值,并使用 echo
命令输出。
需要注意的是,在函数中使用命名参数时,可以使用 %param1%
、%param2%
等来访问它们。例如,在上述示例中,我们可以使用 %param1%
和 %param2%
来访问传递的命名参数。
五、实例演示
为了更好地理解如何定义和调用函数以及传递参数,下面我们将演示一个实际的脚本程序。该脚本程序可以计算一个文本文件中每个单词出现的次数,并将结果输出到另一个文件中。
首先,我们需要定义一个函数来计算单词出现的次数。该函数需要接受一个文件名作为输入参数,并返回一个包含单词出现次数的关联数组。下面是函数定义的代码:
:countWords
setlocal enabledelayedexpansion
set inputFile=%1
for /f "tokens=1" %%i in ('type !inputFile! ^| findstr /r /c:"^[^ ]"') do (set word=%%iset /a words[!word!]+=1
)
endlocal & set words=%words%
goto :eof
在上述代码中,我们定义了一个名为 countWords
的函数,函数主体中使用setlocal enabledelayedexpansion
命令启用了延迟扩展,这样我们就可以在循环中使用 !
来访问变量,而不是 %
。
函数主体中使用 for
命令遍历文件中的每个单词,并使用 set /a
命令将其添加到关联数组 words
中。在循环结束后,我们使用 endlocal & set words=%words%
命令将关联数组传递回调用者。最后,我们使用 goto :eof
命令表示函数结束。
接下来,我们需要定义另一个函数来将单词出现次数输出到文件中。该函数需要接受两个参数:一个包含单词出现次数的关联数组和一个输出文件名。下面是函数定义的代码:
:outputWordCount
setlocal enabledelayedexpansion
set outputFile=%2
(for /f "tokens=1,2 delims==" %%i in ('set words') do (echo %%i=%%j
)) > %outputFile%
endlocal
goto :eof
在上述代码中,我们定义了一个名为 outputWordCount
的函数,函数主体中使用 for
命令遍历关联数组 words
中的每个元素,并使用 echo
命令将其输出到文件中。在循环结束后,我们使用 endlocal
命令结束本地化环境,并使用 goto :eof
命令表示函数结束。
现在我们已经定义了两个函数,可以在脚本程序中调用它们来计算单词出现次数并将结果输出到文件中。下面是脚本程序的完整代码:
@echo offset inputFile=input.txt
set outputFile=output.txtcall :countWords %inputFile%
call :outputWordCount %words% %outputFile%echo Done.goto :eof:countWords
setlocal enabledelayedexpansion
set inputFile=%1
for /f "tokens=1" %%i in ('type !inputFile! ^| findstr /r /c:"^[^ ]"') do (set word=%%iset /a words[!word!]+=1
)
endlocal & set words=%words%
goto :eof:outputWordCount
setlocal enabledelayedexpansion
set outputFile=%2
(for /f "tokens=1,2 delims==" %%i in ('set words') do (echo %%i=%%j
)) > %outputFile%
endlocal
goto :eof
在上述代码中,我们定义了两个变量 inputFile
和 outputFile
,分别表示输入文件名和输出文件名。然后,我们调用 countWords
函数计算单词出现次数,并将结果保存在 words
变量中。接着,我们调用 outputWordCount
函数将单词出现次数输出到文件中。最后,我们使用 echo
命令输出消息表示程序执行完成,并使用 goto :eof
命令表示程序结束。
需要注意的是,在调用函数时,我们使用 %1
、%2
等来访问位置参数,并使用 %words%
和 %outputFile%
来访问变量。在函数定义中,我们使用 !inputFile!
和 !word!
来访问变量,这是因为在函数中启用了延迟扩展。
总结一下,函数是一种模块化编程的技术,可以将代码分解为可重用的部分,从而提高代码的可维护性和可读性。在批处理脚本中,我们可以使用 call
命令定义和调用函数,并使用位置参数或命名参数传递参数。
介绍函数的作用域和递归调用
在CMD和DOS脚本语言中,函数作为模块化编程的基本单元,可以分解代码为可重用的部分,从而提高代码的可维护性和可读性。在本文中,我们将介绍函数的作用域和递归调用,以帮助读者更好地理解和使用函数。
一、函数的作用域
作用域是指变量和函数的可见范围。在CMD和DOS脚本语言中,函数的作用域与变量的作用域是相同的,都遵循静态作用域规则。
静态作用域规则指的是变量和函数的作用域在编译期间就已经确定,而不是在运行期间动态确定。具体来说,函数内部可以访问全局变量和函数,但全局变量和函数不能访问函数内部的局部变量和函数。
下面是一个示例代码,演示了函数的作用域规则:
@echo offset globalVar=globalcall :func1
echo globalVar=%globalVar%
goto :eof:func1
set localVar=local
set globalVar=modified
echo localVar=%localVar%
goto :eof
在上述代码中,我们定义了一个全局变量 globalVar
和一个函数 func1
。在 func1
中,我们定义了一个局部变量 localVar
,并修改了全局变量 globalVar
的值。在主程序中,我们调用 func1
并输出全局变量 globalVar
的值。
运行上述代码,输出结果如下:
localVar=local
globalVar=modified
可以看到,函数 func1
可以访问全局变量 globalVar
,并修改了它的值。但是,主程序不能访问函数 func1
中的局部变量 localVar
。
二、递归调用
递归调用是指函数直接或间接调用自身的过程。在许多算法和数据结构问题中,递归调用是一种比较自然和简洁的解决方案。在CMD和DOS脚本语言中,函数也支持递归调用。
下面是一个示例代码,演示了递归调用的实现:
@echo offset /a n=5call :factorial %n% resultecho %n%! = %result%
goto :eof:factorial
if %1==0 (set /a %2=1
) else (set /a n=%1-1call :factorial %n% tempset /a %2=%1*temp
)
goto :eof
在上述代码中,我们定义了一个函数 factorial
,它计算一个正整数的阶乘,并存储结果在参数 %2
中。在函数中,我们使用递归调用实现了阶乘的计算过程。
具体来说,我们首先判断参数 %1
是否为0,如果是,则将参数 %2
设为1,表示阶乘的结果为1。如果参数 %1
不为0,则将参数 %1
减1,并调用函数 factorial
计算参数 %1
的阶乘。在递归调用返回后,我们将参数 %2
设为 %1
与计算结果的乘积,从而得到参数 %1
的阶乘。
运行上述代码,输出结果如下:
5! = 120
可以看到,我们成功地使用递归调用实现了阶乘的计算。
需要注意的是,递归调用可能会导致栈溢出等问题,因此在设计和使用递归调用时需要谨慎。在CMD和DOS脚本语言中,由于缺乏语言层面的优化和支持,递归调用的效率可能较低,尤其是对于大规模的计算任务。因此,在实际编程中,我们需要根据具体的问题需求和程序性能考虑是否使用递归调用。
三、总结
在本文中,我们介绍了函数的作用域和递归调用在CMD和DOS脚本语言中的使用。函数的作用域遵循静态作用域规则,即函数内部可以访问全局变量和函数,但全局变量和函数不能访问函数内部的局部变量和函数。递归调用是一种比较自然和简洁的解决方案,但也需要注意可能导致的栈溢出等问题。在实际编程中,我们需要根据具体的问题需求和程序性能考虑是否使用递归调用。
相关文章:
CMD与DOS脚本编程【第四章】
预计更新 第一章. 简介和基础命令 1.1 介绍cmd/dos脚本语言的概念和基本语法 1.2 讲解常用的基础命令和参数,如echo、dir、cd等 第二章. 变量和运算符 2.1 讲解变量和常量的定义和使用方法 2.2 介绍不同类型的运算符和运算规则 第三章. 控制流程和条件语句 3.1 介…...
Liunx安装Docker
Liunx在线安装Docker 简介: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不…...

docker:容器的数据卷
1 数据卷概念及作用 1.1 什么是容器数据卷 先来看看Docker的理念: 将应用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的容器之间希望有可能共享数据 Docker容器产生的数据,如果不通过…...

【TCP】对TCP三次握手的个人理解
三次握手 TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。三次握手的过程如下图: 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态 …...

squid的基本代理
一、Squid代理服务器的概述 squid 作为一款服务器代理工具,可以缓存网页对象,减少重复请求,从而达到加快网页访问速度,隐藏客户机真实IP,更为安全。 Squid主要提供缓存加速、应用层过滤控制的功能 1、squid代理的工…...

【从零开始写视觉SLAM】v0.1基于特征点的简单VO
v0.1版本的oSLAM实现了基于orb特征点的简单视觉里程计,通过连续两帧的rgbd数据实现相机相对位姿的估计。 #mermaid-svg-ibQfHFVHezQD5RWW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ibQfHFVHezQD5RW…...

CentOS-7 安装 MariaDB-10.8
一、安装之前删除已存在的 Mysql/MariaDB 1 查找存在的 MariaDB # 注意大小写 rpm -qa | grep MariaDB # rpm -qa 列出所有被安装的rpm package (-qa:query all) rpm -qa | grep mariadb # grep (缩写来自Globally search a Regular Expre…...

Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1
Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1 地址分配表 设备 接口 IP 地址 子网掩码 交换机端口 VLAN PC1 NIC 172.17.10.21 255.255.255.0 S2 F0/11 10 PC2 NIC 172.17.20.22 255.255.255.0 S2 F0/18 20 PC3 NIC 172.17.30.23 255.255.255.0…...

五、c++学习(加餐1:汇编基础学习)
经过前面几节课的学习,我们在一些地方都会使用汇编来分析,我们学习汇编,只是学习一些基础,主要是在我们需要深入分析语法的时候,使用汇编分析,这样会让我们更熟悉c编译器和语法。 从这节课开始,…...

iOS正确获取图片参数深入探究及CGImageRef的使用(附源码)
一 图片参数的正确获取 先拿一张图片作为测试使用 图片参数如下: 图片的尺寸为: -宽1236个像素点 -高748个像素点 -色彩空间为RGB -描述文件为彩色LCD -带有Alpha通道 请记住这几个参数,待会儿我们演示如何正确获取。 将这张图片分别放在…...
Typescript 5.0 发布:快速概览
探索最令人兴奋的功能和更新 作为一种不断发展的编程语言,TypeScript 带来了大量的改进和新功能。在本文中,我们将深入探讨 TypeScript 的最新版本 5.0,并探索其最值得关注的更新。 1. 装饰器 TypeScript 5.0 引入了一个重新设计的装饰器系…...
【图像处理 】卡尔曼滤波器原理
目录 一、说明 二、它是什么? 2.1 我们可以用卡尔曼滤波器做什么? 2.2 卡尔曼滤波器如何看待您的问题...

YOLOv5 实例分割入门
介绍 YOLOv5 目标检测模型以其出色的性能和优化的推理速度而闻名。因此,YOLOv5 实例分割模型已成为实时实例分割中最快、最准确的模型之一。 在这篇文章中,我们将回答以下关于 YOLOv5 实例分割的问题: YOLOv5检测模型做了哪些改动,得到了YOLOv5实例分割架构?使用的 Prot…...

数字城市发展下的技术趋势,你知道多少?
提到数字城市、智慧城市大家都会感觉经常在耳边听到,但是要确切说出具体的概念还是有一点难度的。具体来说:数字城市是一个集合多种技术的系统,以计算机技术、多媒体技术和大规模存储技术为基础,以宽带网络为纽带,运用…...

linux 串口改为固定
在/etc/udev/rules.d 目录下新建定义规则的文件 1. 文件名要按规范写否则改动无效2. 规则文件必须以.rules 结尾3. 规则文件名称必须遵循 xx-name.rules 格式(xx 为数字或字母,name 为规则名称),例如 99-serial-ports.rules。4. 规…...

【SCI一区】考虑P2G和碳捕集设备的热电联供综合能源系统优化调度模型(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Redis缓存数据库(四)
目录 一、概述 1、Redis Sentinel 1.1、docker配置Redis Sentinel环境 2、Redis存储方案 2.1、哈希链 2.2、哈希环 3、Redis分区(Partitioning) 4、Redis面试题 一、概述 1、Redis Sentinel Redis Sentinel为Redis提供了高可用解决方案。实际上这意味着使用Sentinel…...

View中的滑动冲突
View中的滑动冲突 1.滑动冲突的种类 滑动冲突一般有3种, 第一种是ViewGroup和子View的滑动方向不一致 比如: 父布局是可以左右滑动,子view可以上下滑动 第二种 ViewGroup和子View的滑动方向一致 第三种 第三种类似于如下图 2.滑动冲突的解决方式 滑动冲突一般情况下有2…...

java boot项目基础配置之banner与日志配置演示 并教会你如何使用文档查看配置
上文 我们简单讲了一下 springboot 项目的配置 都是写在resources下的application.properties中 springboot 项目中 配置都写在这一个文件 可以说非常方便 不像之前 写个项目配置这里一个哪里一个 看到是非常费力 我们启动项目 这里有个图案 其实 这叫 banner 我们就用配置来…...

蓝鲸平台通过标准运维 API 安装 Agent
目录 一、背景 二、目的 三、创建安装agent流程 四、通过标准运维 API 安装 Agent 五、总结 一、背景 蓝鲸平台正常情况纳管主机需要在节点管理手工安装agent,不能达到完成自动化安装agent的效果。想通过脚本一键安装agent,而不需要在蓝鲸平台进行过…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...

麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...