批處理位運(yùn)算演示代碼
在論壇里看到netbenton的那個(gè)不用call調(diào)用函數(shù)的帖子(下面貼有鏈接)后,突然記起以前自己寫的一個(gè)位運(yùn)算演示的代碼(用call來調(diào)用函數(shù),現(xiàn)改用netbenton的方法另類的調(diào)用),現(xiàn)拿出來和大家分享一下,希望能給初學(xué)者一些小小的幫助
@echo off title 位運(yùn)算示例code by:cn-bathome-more echo. echo.位運(yùn)算名詞解釋(個(gè)人理解): echo. echo.位運(yùn)算: 按操作數(shù)在計(jì)算機(jī)內(nèi)表示的二進(jìn)制數(shù)逐位進(jìn)行邏輯運(yùn)算或移位運(yùn)算. echo.與:全部都是1才為1(指返回值,下同),否則為0. echo.或:只要有1則為1,否則為0. echo.異或: 不同為1,相同為0. echo.取反: 是1則0,是0則1(單目運(yùn)算符). echo.取負(fù): 先取反再加1(單目運(yùn)算符). echo.左移n位: 相當(dāng)于乘以2的n次方(用0補(bǔ)位). echo.右移n位: 相當(dāng)于除以2的n次方(負(fù)數(shù)用1補(bǔ)位,正數(shù)用0補(bǔ)位). echo. echo.下面的示例是在三十二位系統(tǒng)(數(shù)值范圍:-2147483648~2147483647)下運(yùn)行的結(jié)果. echo.請(qǐng)輸入批處理能處理的數(shù)值(整數(shù)),否則將不能正確處理.如發(fā)生溢出,結(jié)果也不會(huì)正確. echo. rem 將十進(jìn)制轉(zhuǎn)換為二進(jìn)制的函數(shù). set "fun_d2b=setlocal enabledelayedexpansion&(for /l %%a in (0 1 31) do (set /a "str=!#a#!^>^>%%a"&set /a "str^&=1"&set "str_d2b=!str!!str_d2b!"))&(for %%a in (!str_d2b!) do (endlocal&set #a#=%%a))" setlocal enabledelayedexpansion :agn set in=&set /p in=請(qǐng)輸入兩個(gè)數(shù)(中間用空格隔開): if not defined in exit set n=0 for %%a in (%in%) do ( set /a n+=1 set /a num!n!=%%a 2>nul ) cls echo.輸入的兩個(gè)數(shù)的有效數(shù)值為: "!num1!" 和 "!num2!", 用二進(jìn)制表示分別為: set /a str1=num1,str2=num2 %fun_d2b:#a#=str1% %fun_d2b:#a#=str2% echo.&echo.!str1! ==^> !num1! echo.!str2! ==^> !num2! echo.&echo.各種位運(yùn)算的結(jié)果如下: set /a "num=!num1!&!num2!,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位與:!num1! ^& !num2! = !t! set /a "num=!num1!|!num2!,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位或:!num1! ^| !num2! = !t! set /a "num=!num1!^^!num2!,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位異或: !num1! ^^^^ !num2! = !t! set /a "num=~!num1!,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位取反: ~(!num1!) = !t! set /a "num=-!num1!,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 取負(fù): -(!num1!) = !t! set /a "ran=%random%%%5+2,num=!num1!,num<<=ran,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 左移!ran!位:!num1! ^<^< !ran! = !t! set /a "ran=%random%%%5+2,num=!num1!,num>>=ran,t=num" %fun_d2b:#a#=num%&echo.&echo.!num! ==^> 右移!ran!位:!num1! ^>^> !ran! = !t! echo.&goto :agn
批處理函數(shù)的高效另類應(yīng)用(免call的哦!)
高速的真正的批處理函數(shù)應(yīng)用方法!
并非調(diào)用子過程。。。
我想這次應(yīng)該可以把批處理編程推向一個(gè)新的臺(tái)階。
目前只支持一個(gè)參數(shù),
@echo off ::定義函數(shù) set "d-h=setlocal enabledelayedexpansion&set/a dx=#a#&set xs=0123456789abcdef&(for /l %%z in (1,1,4) do set /a x%%z=dx%%16,dx=dx/16)&(for /f "tokens=1-4" %%1 in ("!x1! !x2! !x3! !x4!") do set hx=!xs:~%%4,1!!xs:~%%3,1!&(if !hx!==00 set hx=)&(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal&set #a#=%%~z))" ::10進(jìn)制轉(zhuǎn)為16進(jìn)制的函數(shù),參數(shù)入口#a# ::要在開啟變量延遲之前定義 setlocal enabledelayedexpansion for /l %%a in (1,7,1024) do ( set abc=%%a (%d-h:#a#=abc%) rem 函數(shù)調(diào)用 echo !abc! ) pause
可以支持多參數(shù)了
len函數(shù)為兩個(gè)參數(shù),
@echo off ::定義函數(shù) set "d-h=setlocal enabledelayedexpansion&set/a dx=#a#&set xs=0123456789abcdef&(for /l %%z in (1,1,4) do set /a x%%z=dx%%16,dx=dx/16)&(for /f "tokens=1-4" %%1 in ("!x1! !x2! !x3! !x4!") do set hx=!xs:~%%4,1!!xs:~%%3,1!&(if !hx!==00 set hx=)&(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal&set #a#=%%~z))" ::10進(jìn)制轉(zhuǎn)為16進(jìn)制的函數(shù),調(diào)用方法:%d-h:#a#=變量名% set "len=for /f "tokens=1-3" %%1 in ("#a#") do setlocal enabledelayedexpansion&(if defined %%2 (set /a z=8180,x=0&(for /l %%a in (1,1,14) do set/a "y=(z-x)/2+x"&(for %%b in (!y!) do if "!%%2:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)))) else (set z=0))&(for %%z in ("!z!") do endlocal&set %%1=%%~z)" ::取字符串長度函數(shù),調(diào)用方法:%len:#a#=結(jié)果變量名 字符串變量名% setlocal enabledelayedexpansion for /l %%a in (1,7,1024) do ( set abc=%%a (%len:#a#=slen abc%) (%d-h:#a#=abc%) (%len:#a#=dlen abc%) rem 函數(shù)調(diào)用 echo %%a轉(zhuǎn)成16進(jìn)制為:!abc!轉(zhuǎn)換前字符數(shù):!slen! 轉(zhuǎn)換后字符數(shù):!dlen! ) pause
思路確實(shí)夠新
但是因?yàn)閮蓚€(gè)原因不建議推廣
代碼的可閱讀性降低
環(huán)境變量的過分使用也會(huì)影響效率
對(duì)于函數(shù)的效率問題
我覺得還是傳統(tǒng)的”goto對(duì)“來得更加簡單、自由和高效
通常情況下
應(yīng)該避免在組合語句(括號(hào)對(duì)中的語句)中使用函數(shù)
如果綜合權(quán)衡后還是要使用
那么就需要保證組合語句的循環(huán)和遞歸級(jí)數(shù)滿足設(shè)計(jì)要求
這種方法,對(duì)于函數(shù)的內(nèi)部結(jié)構(gòu),可讀性是很差,但是對(duì)于主程序的可讀性卻表現(xiàn)得非常好
看:
(%len:#a#=slen abc%)
調(diào)用用函數(shù)len,作用是,計(jì)算變量abc中字符串的長度,把結(jié)果存到變量slen中
使用函數(shù)的作用不就是為了簡化主程序嗎?
而對(duì)于函數(shù),通常都是引用前人或者自己常用的功能代碼,只要根據(jù)注釋使用就可以了,
根本就不必去理會(huì)函數(shù)的內(nèi)部做了什么。就像其它編程語言調(diào)用api和dos中斷一樣,難道還要去了解其內(nèi)部是怎么運(yùn)行的嗎?
有了這種函數(shù),就算是批處理新手,也可以輕松寫出高效的批處理來,
就算是老手要寫較大型的批程序時(shí),這些可是很好的磚瓦啊。
這種函數(shù)定義只要一行就可以了,不足處是要占用一個(gè)變量名,和環(huán)境變量空間,但是這對(duì)于效率來說,這點(diǎn)是微小的,因?yàn)橐粋€(gè)call :sub子過程用時(shí)相當(dāng)于30層的call,及執(zhí)行300次的set var=n,當(dāng)然有一點(diǎn),call sub.bat這種用法,要比call :sub 批處理內(nèi)部子過程要快一半,但也是比用%len:#a#=var%多出來的時(shí)間,效率可想而知了。
經(jīng)過這樣封裝的函數(shù),是不可能會(huì)破壞主程序的結(jié)構(gòu)的,4樓對(duì)len函數(shù)的使用,主程序和函數(shù)同進(jìn)使用了同一個(gè)for令牌%%a卻一樣可以得到正確的結(jié)果。函數(shù)內(nèi)部的變量使用完全是臨時(shí)的,在函數(shù)結(jié)束時(shí)已經(jīng)用endlocal清場(chǎng),只保存返回結(jié)果。
想說些贊美的話,不好說出口。在一次創(chuàng)作中,突然想起netbenton這種函數(shù)的用法,于是也山寨了一個(gè),呵呵。確實(shí)如樓主所言,發(fā)展一些高效的、正確的、常用的函數(shù)很有必要,能夠充分?jǐn)U展批處理的功能,使得批處理累積起更大的功能,從而實(shí)現(xiàn)更高的跨越式的發(fā)展。
對(duì)于重復(fù)命令調(diào)用處理的方法和技術(shù),目前看來有幾種:
1、復(fù)制粘貼,重復(fù)出現(xiàn)。這種模式在執(zhí)行任務(wù)與命令比較少的情況下可以使用,比如使用echo產(chǎn)生兩三行空行,總比使用for產(chǎn)生的劃算吧?這種模式的結(jié)果是造成大量重復(fù)代碼,缺乏效率。
2、使用標(biāo)簽,GOTO跳轉(zhuǎn)。把那些反復(fù)使用的同一功能段的代碼做成一個(gè)標(biāo)簽,然后使用goto跳轉(zhuǎn),這是最基本的模式。但goto只負(fù)責(zé)跳出去而不跳回來,要想代碼自動(dòng)回來則需要再跳一次。
3、使用標(biāo)簽,Call調(diào)用。call的好處是跳到其他標(biāo)簽后能夠自動(dòng)跳回來。之所以能夠自動(dòng)跳回來,因?yàn)閏all在原來代碼后面使用了標(biāo)記,可能使用了更多的內(nèi)存存儲(chǔ)來暫停原來的進(jìn)程。所以,相對(duì)而言,會(huì)顯得較慢一些。但Call對(duì)參數(shù)有很好的支持,使得人們對(duì)其無法割舍。
4、使用FOR命令,化繁為簡。將那些符合FOR特性的命令融合到FOR當(dāng)中,即可減少必要的重復(fù)操作。
5、使用函數(shù),擴(kuò)大變量。將一些命令組合賦值到某一個(gè)特定的變量中,變成通用函數(shù),支持參數(shù),它不需要重新建立標(biāo)簽,但它占據(jù)了一個(gè)變量空間。這種模式適用于所賦值的命令組合比較簡短,占用空間不大的變量函數(shù)中??梢苑奖惴庋b以用于不同的批處理程序中。
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。