今天看了壹個前輩的程序,發現為了分析協議的消息類型,我用了if...中斷函數中的else語句。因為目前只有兩類消息,未來可能會增加,不確定。
我覺得這個有點不合適,為什麽不用switch語句呢?猜測是出於效率的考慮。畢竟要盡量讓中斷處理代碼更簡潔,時間效率更高。
所以我查了相關資料,顯示switch語句比ifelse更高效。
下面詳細描述壹下switch和ifelse的區別。
轉換...情況
與if的根本區別...否則那就是開關...case會生成壹個跳轉表來指示實際case分支的地址,這個跳轉表的索引號和switch的索引號相同。
變量值相等。因此,開關...case不需要遍歷條件分支,直到它遇到像if這樣的條件...否則,只需訪問索引號對應的表項即可到達定位分支。
分支的目的。
具體來說,開關...case會生成壹個最大case常量+1的skip表,程序會先判斷switch變量是否大於。
最大案例
常數,如果大於,跳到默認分支進行處理;否則,獲取索引號為switch變量大小的跳轉表項的地址(即跳轉表的起始地址+表項的大小*索引號),然後程序跳轉。
在這個地址執行,分支跳轉在這裏完成。
//
int main()
{
無符號int i,j;
I = 3;
開關(壹)
{
案例0:
j = 0;
打破;
案例1:
j = 1;
打破;
案例二:
j = 2;
打破;
案例三:
j = 3;
打破;
案例4:
j = 4;
打破;
默認值:
j = 10;
打破;
}
}
使用gcc編譯器生成匯編代碼(沒有編譯器優化)
。文件“shiyan.c”
。文本
。全球總管
。鍵入main,@function
主要:
第4級(%esp),%ecx
和1美元-16%,esp
pushl -4(%ecx)
pushl %ebp
運動百分比esp,%ebp
pushl %ecx
子$20,%esp
movl $3,-8(%預算外)
cmpl $4,-8(%ebp)
ja .L2
movl -8(%ebp),%eax
所有2美元,%eax
movl .L8(%eax),%eax
jmp *%eax
。部分。羅達塔
。對齊4
。對齊4
. L8:
。長. L3
。long .L4
。長. L5
。長. L6
。long .L7
。文本
. L3:
movl $0,-12(%ebp)
jmp .L11
. L4:
movl $1,-12(%ebp)
jmp .L11
. L5:
movl $2,-12(%ebp)
jmp .L11
. L6:
movl $3,-12(%ebp)
jmp .L11
. L7:
movl $4,-12(%ebp)
jmp .L11
. L2:
movl $10,-12(%ebp)
. L11:
附加20美元,%esp
popl %ecx
popl %ebp
leal -4(%ecx),%esp
浸水使柔軟
。主要尺寸,。-主
。" GCC:(Ubuntu 4 . 3 . 3-5ubuntu 4)4 . 3 . 3 "
。section .note.GNU-stack,"",@progbits
從這個角度來看,switch有點以空間換時間,事實上也確實如此。
1.分支多的時候,當時使用switch的效率是很高的。因為switch是隨機訪問,即在確定選擇值後,直接跳轉到那個特定的分支,但是如果。。否則就是遍歷所有可能的值,直到找到滿足條件的分支。從這個角度來說,switch的效率確實比ifelse高很多。
2.從上面的匯編代碼中,我們可以知道開關...case占用較多的代碼空間,因為需要生成跳表,特別是當case常數分布範圍較大但實際有效值較少時,交換機的空間利用率...情況會變得很低。
3 .開關...情況
我們只能處理常數的情況,對非常數的情況無能為力。例如,如果(a >;1。& ampa & lt
100),不能使用開關...要處理的案子。因此,在從常量中選擇分支時,switch只能比ifelse更有效,但是ifelse可以應用於更多
Ifelse在很多場合更靈活。
從這個角度來說,在上面幾位前輩的中斷處理程序中使用switch比較合適,這樣既節省了時間,也便於以後程序的擴展。因為消息類型的值基本上是用整型常量表示的。