一個很簡單的問題:在C語言中,如果一個數組有10個元素,那么這個數組的下標的允許取值范圍是什么呢?
你當然能很快的回答 0-9!而不會說是1-10。但是你能說自己從沒寫過如下這樣的代碼嗎?
int a[10];
for (int i=0; i <= 10; i++)
a[i] = 0;
是的,這是一個簡單的錯誤,不過也是一個容易犯的錯誤。
下一個問題:假定整數x滿足邊界條件x>=16且x<=37,那么此范圍內x的可能取值個數有多少?
是37-16=21嗎?很遺憾,我們又犯了一個錯誤,正確的應該是37-16+1=22。
為什么要多加1呢?這就是《C陷阱與缺陷》中所說的“欄桿錯誤”,并且該書還告訴我們,盡管這些錯誤很容易出現,但是任然存在一些編程技巧來盡量避免,用第一個入界點和第一個出界點來表示一個數值范圍!
比如,對前面的例子,我們不應說整數x滿足邊界條件x>=16且x<=37,而是說整數x滿足邊界條件x>=16且x<38。注意,這里下界是“入界點”,即包括在取值范圍之中;而上界是“出界點”,即不包括在取值范圍之中。這種不對稱也許從數學上而言并不優美,但是它對于程序設計的簡化效果卻足以令人吃驚:
1.取值范圍的大小就是上界與下界之差。38-16的值是22,恰恰是不對稱邊界16和38之間所包括的元素數目。
2.如果取值范圍為空,那么上界等于下界。這是第1條的直接推論。
3.即使取值范圍為空,上界也永遠不可能小于下界。
而最關鍵的是,對于像C這樣的數組下標從0開始的語言,不對稱邊界給程序設計帶來的便利尤其明顯:這種數組的上界(即第一個“出界點”)恰是數組元素的個數!因此,如果我們要在C語言中定義一個擁有10個元素的數組,那么0就是數組下標的第一個“入界點”(指處于數組下標范圍以內的點,包括邊界點),而10就是數組下標中的第一個“出界點”(指不在數組下標范圍以內的點,不含邊界點)。正因為此,我們這樣寫:
int a[10];
for (int i=0; i < 10; i++)
a[i] = 0;
而不是寫成下面這樣:
int a[10];
for (int i=0; i <= 9; ++i)
a[i] = 0;
好了,說了這么多。本篇目的不僅僅是引出這個編碼技巧:“用第一個入界點和第一個出界點來表示一個數值范圍!”,其實我希望表達的是:C/C++語言中,寫類似for這些涉及邊界值的語句時,統一采用不對稱邊界編碼風格!這樣不僅避免犯錯,還能少敲一個'='號哦~