<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 4.5 數組初始化 在C中初始化數組極易出錯,而且相當麻煩。C++通過“集合初始化”使其更安全(注釋⑥)。Java則沒有象C++那樣的“集合”概念,因為Java中的所有東西都是對象。但它確實有自己的數組,通過數組初始化來提供支持。 數組代表一系列對象或者基本數據類型,所有相同的類型都封裝到一起——采用一個統一的標識符名稱。數組的定義和使用是通過方括號索引運算符進行的(`[]`)。為定義一個數組,只需在類型名后簡單地跟隨一對空方括號即可: ``` int[] al; ``` 也可以將方括號置于標識符后面,獲得完全一致的結果: ``` int al[]; ``` 這種格式與C和C++程序員習慣的格式是一致的。然而,最“通順”的也許還是前一種語法,因為它指出類型是“一個`int`數組”。本書將沿用那種格式。 編譯器不允許我們告訴它一個數組有多大。這樣便使我們回到了“引用”的問題上。此時,我們擁有的一切就是指向數組的一個引用,而且尚未給數組分配任何空間。為了給數組創建相應的存儲空間,必須編寫一個初始化表達式。對于數組,初始化工作可在代碼的任何地方出現,但也可以使用一種特殊的初始化表達式,它必須在數組創建的地方出現。這種特殊的初始化是一系列由花括號封閉起來的值。存儲空間的分配(等價于使用`new`)將由編譯器在這種情況下進行。例如: ``` int[] a1 = { 1, 2, 3, 4, 5 }; ``` 那么為什么還要定義一個沒有數組的數組引用呢? ``` int[] a2; ``` 事實上在Java中,可將一個數組分配給另一個,所以能使用下述語句: ``` a2 = a1; ``` 我們真正準備做的是復制一個引用,就象下面演示的那樣: ``` //: Arrays.java // Arrays of primitives. public class Arrays { public static void main(String[] args) { int[] a1 = { 1, 2, 3, 4, 5 }; int[] a2; a2 = a1; for(int i = 0; i < a2.length; i++) a2[i]++; for(int i = 0; i < a1.length; i++) prt("a1[" + i + "] = " + a1[i]); } static void prt(String s) { System.out.println(s); } } ///:~ ``` 大家看到`a1`獲得了一個初始值,而`a2`沒有;`a2`將在以后賦值——這種情況下是賦給另一個數組。 這里也出現了一些新東西:所有數組都有一個本質成員(無論它們是對象數組還是基本類型數組),可對其進行查詢——但不是改變,從而獲知數組內包含了多少個元素。這個成員就是`length`。與C和C++類似,由于Java數組從元素0開始計數,所以能索引的最大元素編號是`length-1`。如超出邊界,C和C++會“默默”地接受,并允許我們胡亂使用自己的內存,這正是許多程序錯誤的根源。然而,Java可保留我們這受這一問題的損害,方法是一旦超過邊界,就生成一個運行期錯誤(即一個“異常”,這是第9章的主題)。當然,由于需要檢查每個數組的訪問,所以會消耗一定的時間和多余的代碼量,而且沒有辦法把它關閉。這意味著數組訪問可能成為程序效率低下的重要原因——如果它們在關鍵的場合進行。但考慮到因特網訪問的安全,以及程序員的編程效率,Java設計人員還是應該把它看作是值得的。 程序編寫期間,如果不知道在自己的數組里需要多少元素,那么又該怎么辦呢?此時,只需簡單地用`new`在數組里創建元素。在這里,即使準備創建的是一個基本數據類型的數組,`new`也能正常地工作(`new`不會創建非數組的基本類型): ``` //: ArrayNew.java // Creating arrays with new. import java.util.*; public class ArrayNew { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { int[] a; a = new int[pRand(20)]; prt("length of a = " + a.length); for(int i = 0; i < a.length; i++) prt("a[" + i + "] = " + a[i]); } static void prt(String s) { System.out.println(s); } } ///:~ ``` 由于數組的大小是隨機決定的(使用早先定義的`pRand()`方法),所以非常明顯,數組的創建實際是在運行期間進行的。除此以外,從這個程序的輸出中,大家可看到基本數據類型的數組元素會自動初始化成“空”值(對于數值,空值就是零;對于`char`,它是`null`;而對于`boolean`,它卻是`false`)。 當然,數組可能已在相同的語句中定義和初始化了,如下所示: ``` int[] a = new int[pRand(20)]; ``` 若操作的是一個非基本類型對象的數組,那么無論如何都要使用`new`。在這里,我們會再一次遇到引用問題,因為我們創建的是一個引用數組。請大家觀察包裝器類型`Integer`,它是一個類,而非基本數據類型: ``` //: ArrayClassObj.java // Creating an array of non-primitive objects. import java.util.*; public class ArrayClassObj { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { Integer[] a = new Integer[pRand(20)]; prt("length of a = " + a.length); for(int i = 0; i < a.length; i++) { a[i] = new Integer(pRand(500)); prt("a[" + i + "] = " + a[i]); } } static void prt(String s) { System.out.println(s); } } ///:~ ``` 在這兒,甚至在`new`調用后才開始創建數組: ``` Integer[] a = new Integer[pRand(20)]; ``` 它只是一個引用數組,而且除非通過創建一個新的`Integer`對象,從而初始化了對象引用,否則初始化進程不會結束: ``` a[i] = new Integer(pRand(500)); ``` 但若忘記創建對象,就會在運行期試圖讀取空數組位置時獲得一個“異常”錯誤。 下面讓我們看看打印語句中`String`對象的構成情況。大家可看到指向`Integer`對象的引用會自動轉換,從而產生一個`String`,它代表著位于對象內部的值。 亦可用花括號封閉列表來初始化對象數組。可采用兩種形式,第一種是Java 1.0允許的唯一形式。第二種(等價)形式自Java 1.1才開始提供支持: ``` //: ArrayInit.java // Array initialization public class ArrayInit { public static void main(String[] args) { Integer[] a = { new Integer(1), new Integer(2), new Integer(3), }; // Java 1.1 only: Integer[] b = new Integer[] { new Integer(1), new Integer(2), new Integer(3), }; } } ///:~ ``` 這種做法大多數時候都很有用,但限制也是最大的,因為數組的大小是在編譯期間決定的。初始化列表的最后一個逗號是可選的(這一特性使長列表的維護變得更加容易)。 數組初始化的第二種形式(Java 1.1開始支持)提供了一種更簡便的語法,可創建和調用方法,獲得與C的“變量參數列表”(C通常把它簡稱為“變參表”)一致的效果。這些效果包括未知的參數數量以及未知的類型(如果這樣選擇的話)。由于所有類最終都是從通用的根類`Object`中繼承的,所以能創建一個方法,令其獲取一個`Object`數組,并象下面這樣調用它: ``` //: VarArgs.java // Using the Java 1.1 array syntax to create // variable argument lists class A { int i; } public class VarArgs { static void f(Object[] x) { for(int i = 0; i < x.length; i++) System.out.println(x[i]); } public static void main(String[] args) { f(new Object[] { new Integer(47), new VarArgs(), new Float(3.14), new Double(11.11) }); f(new Object[] {"one", "two", "three" }); f(new Object[] {new A(), new A(), new A()}); } } ///:~ ``` 此時,我們對這些未知的對象并不能采取太多的操作,而且這個程序利用自動`String`轉換對每個`Object`做一些有用的事情。在第11章(運行期類型識別或RTTI),大家還會學習如何調查這類對象的準確類型,使自己能對它們做一些有趣的事情。 ## 4.5.1 多維數組 在Java里可以方便地創建多維數組: ``` //: MultiDimArray.java // Creating multidimensional arrays. import java.util.*; public class MultiDimArray { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { int[][] a1 = { { 1, 2, 3, }, { 4, 5, 6, }, }; for(int i = 0; i < a1.length; i++) for(int j = 0; j < a1[i].length; j++) prt("a1[" + i + "][" + j + "] = " + a1[i][j]); // 3-D array with fixed length: int[][][] a2 = new int[2][2][4]; for(int i = 0; i < a2.length; i++) for(int j = 0; j < a2[i].length; j++) for(int k = 0; k < a2[i][j].length; k++) prt("a2[" + i + "][" + j + "][" + k + "] = " + a2[i][j][k]); // 3-D array with varied-length vectors: int[][][] a3 = new int[pRand(7)][][]; for(int i = 0; i < a3.length; i++) { a3[i] = new int[pRand(5)][]; for(int j = 0; j < a3[i].length; j++) a3[i][j] = new int[pRand(5)]; } for(int i = 0; i < a3.length; i++) for(int j = 0; j < a3[i].length; j++) for(int k = 0; k < a3[i][j].length; k++) prt("a3[" + i + "][" + j + "][" + k + "] = " + a3[i][j][k]); // Array of non-primitive objects: Integer[][] a4 = { { new Integer(1), new Integer(2)}, { new Integer(3), new Integer(4)}, { new Integer(5), new Integer(6)}, }; for(int i = 0; i < a4.length; i++) for(int j = 0; j < a4[i].length; j++) prt("a4[" + i + "][" + j + "] = " + a4[i][j]); Integer[][] a5; a5 = new Integer[3][]; for(int i = 0; i < a5.length; i++) { a5[i] = new Integer[3]; for(int j = 0; j < a5[i].length; j++) a5[i][j] = new Integer(i*j); } for(int i = 0; i < a5.length; i++) for(int j = 0; j < a5[i].length; j++) prt("a5[" + i + "][" + j + "] = " + a5[i][j]); } static void prt(String s) { System.out.println(s); } } ///:~ ``` 用于打印的代碼里使用了`length`,所以它不必依賴固定的數組大小。 第一個例子展示了基本數據類型的一個多維數組。我們可用花括號定出數組內每個向量的邊界: ``` int[][] a1 = { { 1, 2, 3, }, { 4, 5, 6, }, }; ``` 每個方括號對都將我們移至數組的下一級。 第二個例子展示了用`new`分配的一個三維數組。在這里,整個數組都是立即分配的: ``` int[][][] a2 = new int[2][2][4]; ``` 但第三個例子卻向大家揭示出構成矩陣的每個向量都可以有任意的長度: ``` int[][][] a3 = new int[pRand(7)][][]; for(int i = 0; i < a3.length; i++) { a3[i] = new int[pRand(5)][]; for(int j = 0; j < a3[i].length; j++) a3[i][j] = new int[pRand(5)]; } ``` 對于第一個`new`創建的數組,它的第一個元素的長度是隨機的,其他元素的長度則沒有定義。`for`循環內的第二個`new`則會填寫元素,但保持第三個索引的未定狀態——直到碰到第三個`new`。 根據輸出結果,大家可以看到:假若沒有明確指定初始化值,數組值就會自動初始化成零。 可用類似的表式處理非基本類型對象的數組。這從第四個例子可以看出,它向我們演示了用花括號收集多個`new`表達式的能力: ``` Integer[][] a4 = { { new Integer(1), new Integer(2)}, { new Integer(3), new Integer(4)}, { new Integer(5), new Integer(6)}, }; ``` 第五個例子展示了如何逐漸構建非基本類型的對象數組: ``` Integer[][] a5; a5 = new Integer[3][]; for(int i = 0; i < a5.length; i++) { a5[i] = new Integer[3]; for(int j = 0; j < a5[i].length; j++) a5[i][j] = new Integer(i*j); } ``` `i*j`只是在`Integer`里置了一個有趣的值。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看