運(yùn)行環(huán)境:
Windows 10 專業(yè)版
if_else語句多選復(fù)合語句問題
1.單條語句的嵌套
1.a
如這樣一段簡單的復(fù)合選擇語句,是無法通過運(yùn)行的。

1.b
當(dāng)我們?yōu)槊織l語句加上 () 小括號(hào)時(shí),它依然是無法正常運(yùn)行。

1.c
這是因?yàn)?if 和 else 條件后的執(zhí)行語句,只能做一條語句看待。
if %option% == 3 ( echo three ) else if %option% == 2 ( echo two ) else if %option% == 1 ( echo one ) else ( echo zero )

1.d
實(shí)際編程中,如果我們的需求較大,選項(xiàng)多、語句代碼長時(shí),所有if_else嵌套語句寫在了一行,即影響了可讀性,也提高了維護(hù)難度。我們不大可能編寫這樣一行代碼。
由于產(chǎn)生了換行,我們需要在每條條件執(zhí)行語句結(jié)尾的 )后面加上 ^,以充當(dāng)續(xù)行的作用。
set option=2
if %option% == 3 ( echo three ) ^
else if %option% == 2 ( echo two ) ^
else if %option% == 1 ( echo one ) ^
else ( echo zero )

2.多條邏輯語句的多選復(fù)合語句
2.a
上述通過添加 ^ 的形式,確實(shí)解決了多層嵌套的問題。但是對(duì)于多條語句的執(zhí)行情況,又是不同。
我們可以看到,進(jìn)入第二行的條件里,它把后面的賦值語句,當(dāng)字符串輸出了。如果是更復(fù)雜的語法,而不是例子中第一條語句是echo,就會(huì)看到語法錯(cuò)誤。

這時(shí),我們需要把兩條語句分行編寫,才能保證程序的正確運(yùn)行。
到了這里,可能會(huì)有熟悉C/C++編程習(xí)慣的朋友,會(huì)編寫這樣if_else格式的語句:
if (option == 2)
{
//
}
else if (option == 1)
{
//
}
else
{
//
}
又或者是Java的編程習(xí)慣的形式:
if (option == 2) {
//
} else if (option == 1) {
//
} else {
//
}
2.b
我們先看下C/C++編寫習(xí)慣的if_else語句:
程序運(yùn)行到第一個(gè)條件語句就已經(jīng)報(bào)錯(cuò)。這就是因?yàn)?if 條件后的操作都視為一條語句。

2.c
我們在每個(gè)if后面加上續(xù)行操作符 ^ 后,我們并不能得到想要的運(yùn)行結(jié)果。
我的一個(gè)理解是,續(xù)行操作符只將下一行語句前置到同行,由于讀到下一行沒有語句,就依照程序邏輯往下運(yùn)行。這時(shí)就出現(xiàn)了我們一般在C/C++、Java等語言沒出現(xiàn)過的一種情況。嵌套在if_else語句中間的語句被執(zhí)行了。觀察結(jié)果,我們可以看到每條echo語句都有執(zhí)行,并且執(zhí)行的4次sum賦值,顯示的就是最后一次賦值為0的執(zhí)行結(jié)果。這是bat腳本的第一個(gè)很神奇的語法特點(diǎn)。
這個(gè)續(xù)行操作符跳過空的一行語句,繼續(xù)執(zhí)行了正確的語句,找到了else時(shí),判斷到前面有if語句,并不認(rèn)為是語法錯(cuò)誤,就繼續(xù)往下執(zhí)行。

2.d
這樣添加續(xù)行操作符的動(dòng)作,沒有識(shí)別到條件語句后的邏輯是一個(gè)代碼塊。我們嘗試直接將每個(gè)條件語句后的語句塊的左括號(hào) ( 前置到與if語句同一行的后面,我們卻得到了正確的結(jié)果:
setlocal EnableDelayedExpansion
set option=2
set sum=-1
if %option% == 3 (
echo three
set /a sum=%option%*%option%*%option%
) ^
else if %option% == 2 (
echo two
set /a sum=2*%option%
) ^
else if %option% == 1 (
echo one
set /a sum=%option%
) ^
else (
echo zero
set /a sum=0
)
echo sum = !sum!

至此,我們確實(shí)得到了正確的運(yùn)行結(jié)果。不過我們還是想要驗(yàn)證,類似C/C++編程習(xí)慣格式的語句?;赝说?.c的操作上,繼續(xù)做修改。
我們先排除幾種修改的可能:
- 右括號(hào)后面的續(xù)行操作符 ^ 不會(huì)刪除。這是第1大點(diǎn)得出的結(jié)論。
- 不會(huì)在每一行代碼后加續(xù)行操作符 ^ ,這與2.a的錯(cuò)誤結(jié)論相等。
2.e
在每一行代碼后加續(xù)行操作符。
結(jié)論不理想,這樣的操作更像是一個(gè)多行輸出的操作。

2.f
在上面的基礎(chǔ)上,在每個(gè)左括號(hào) ( 后面加續(xù)行操作符。
結(jié)論更不理想,沒有一條語句有執(zhí)行到。

2.g
在2.c的基礎(chǔ)上,只做在每個(gè)左括號(hào) ( 后面加續(xù)行操作符的動(dòng)作。
結(jié)論依然是錯(cuò)誤的。

正確的寫法
至此,我們沒有得到類似C/C++編寫習(xí)慣的if_else格式的正確寫法,但是有2.d這樣的結(jié)論:
- if 語句與左括號(hào) ( 同行
- 右括號(hào) ) 不與 else if 同行
- 右括號(hào) ) 后面加上續(xù)行操作符 ^
setlocal EnableDelayedExpansion
set option=2
set sum=-1
if %option% == 3 (
echo three
set /a sum=%option%*%option%*%option%
) ^
else if %option% == 2 (
echo two
set /a sum=2*%option%
) ^
else if %option% == 1 (
echo one
set /a sum=%option%
) ^
else (
echo zero
set /a sum=0
)
echo sum = !sum!
2.h.Java編寫習(xí)慣的寫法
我們也很清楚地看到,這種編寫習(xí)慣也是正確的。
setlocal EnableDelayedExpansion
set option=2
set sum=-1
if %option% == 3 (
echo three
set /a sum=%option%*%option%*%option%
) else if %option% == 2 (
echo two
set /a sum=2*%option%
) else if %option% == 1 (
echo one
set /a sum=%option%
) else (
echo zero
set /a sum=0
)
echo sum = !sum!
