JAVA循環(huán)謎題26:在循環(huán)中

字號(hào):

下面的程序計(jì)算了一個(gè)循環(huán)的迭代次數(shù),并且在該循環(huán)終止時(shí)將這個(gè)計(jì)數(shù)值打印了出來。那么,它打印的是什么呢?
    public class InTheLoop {
     public static final int END = Integer.MAX_VALUE;
     public static final int START = END - 100;
     public static void main(String[] args) {
     int count = 0;
     for (int i = START; i <= END; i++)
     count++;
     System.out.println(count);
     }
    }
    如果你沒有非常仔細(xì)地查看這個(gè)程序,你可能會(huì)認(rèn)為它將打印100,因?yàn)镋ND比START大100。如果你稍微仔細(xì)一點(diǎn),你可能會(huì)發(fā)現(xiàn)該程序沒有使用典型的循環(huán)慣用法。大多數(shù)的循環(huán)會(huì)在循環(huán)索引小于終止值時(shí)持續(xù)運(yùn)行,而這個(gè)循環(huán)則是在循環(huán)索引小于或等于終止值時(shí)持續(xù)運(yùn)行。所以它會(huì)打印101,對(duì)嗎?
    嗯,根本不對(duì)。如果你運(yùn)行該程序,就會(huì)發(fā)現(xiàn)它壓根就什么都沒有打印。更糟的是,它會(huì)持續(xù)運(yùn)行直到你撤銷它為止。它從來都沒有機(jī)會(huì)去打印count,因?yàn)樵诖蛴∷恼Z句之前插入的是一個(gè)無限循環(huán)。
    問題在于這個(gè)循環(huán)會(huì)在循環(huán)索引(i)小于或等于Integer.MAX_VALUE時(shí)持續(xù)運(yùn)行,但是所有的int變量都是小于或等于Integer.MAX_VALUE的。因?yàn)樗欢x為所有int數(shù)值中的值。當(dāng)i達(dá)到Integer.MAX_VALUE,并且再次被執(zhí)行增量操作時(shí),它就有繞回到了Integer.MIN_VALUE。
    如果你需要的循環(huán)會(huì)迭代到int數(shù)值的邊界附近時(shí),你是使用一個(gè)long變量作為循環(huán)索引。只需將循環(huán)索引的類型從int改變?yōu)閘ong就可以解決該問題,從而使程序打印出我們所期望的101:
    for (long i = START; i <= END; i++)
    更一般地講,這里的教訓(xùn)就是int不能表示所有的整數(shù)。無論你在何時(shí)使用了一個(gè)整數(shù)類型,都要意識(shí)到其邊界條件。如果其數(shù)值下溢或是上溢了,會(huì)怎么樣呢?所以通常是使用一個(gè)取之范圍更大的類型。(整數(shù)類型包括byte、char、short、int和long。)
    不使用long類型的循環(huán)索引變量也可以解決該問題,但是它看起來并不那么漂亮:
    int i = START;
    do {
     count++;
    }while (i++ != END);
    如果清晰性和簡(jiǎn)潔性占據(jù)了極其重要的地位,那么在這種情況下使用一個(gè)long類型的循環(huán)索引幾乎總是方案。
    但是有一個(gè)例外:如果你在所有的(或者幾乎所有的)int數(shù)值上迭代,那么使用int類型的循環(huán)索引的速度大約可以提高一倍。下面是將f函數(shù)作用于所有40億個(gè)int數(shù)值上的慣用法:
    //Apply the function f to all four billion int values
    int i = Integer.MIN_VALUE;
    do {
     f(i);
    }while (i++ != Integer.MAX_VALUE);
    該謎題對(duì)語言設(shè)計(jì)者的教訓(xùn)與謎題3相同:可能真的值得去考慮,應(yīng)該對(duì)那些不會(huì)在產(chǎn)生溢出時(shí)而不拋出異常的算術(shù)運(yùn)算提供支持。同時(shí),可能還值得去考慮,應(yīng)該對(duì)那些在整數(shù)值范圍之上進(jìn)行迭代的循環(huán)進(jìn)行特殊設(shè)計(jì),就像許多其他語言所做的那樣。