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