(原創) 如何動態建立一維陣列? (C/C++) (C)
使用int ia[sizex]語法所建立的array是建立在stack,且sizex必須在compile-time就決定,是一種靜態的array,若sizex須在run-time決定,就必須在heap建立動態array。
要建立動態array,有兩種方式,一種是C語言的malloc()或calloc(),在Linux或Embedded System上常用,一種是C++的new,無論使用哪種方式,所傳回的都是pointer,指向array的第一個元素。
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : ArrayDynamicOneDim.cpp
5Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to dynamic allocate 1 dim array on heap
7Release : 02/23/2007 1.0
8*/
9
10#include <iostream>
11#include "stdlib.h"
12
13using namespace std;
14
15bool oneDimArrayDynamic(const int sizex) {
16 // C style
17 // int *ia = (int *)malloc((size_t)sizex * sizeof(int));
18 // int *ia = (int *)calloc((size_t)sizex, (size_t)sizeof(int));
19 //if (ia == NULL)
20 // return false;
21
22 // C++ style
23 int *ia = new int[sizex];
24 for(int i = 0; i != sizex; ++i) {
25 ia[i] = i;
26 }
27
28 cout << "1 dim dynamic array on heap" << endl;
29
30 for(int i = 0; i != sizex; ++i) {
31 cout << ia[i] << " ";
32 }
33
34 cout << endl;
35
36 // C style
37 // free(ia);
38 // C++ style
39 delete []ia;
40
41 return true;
42}
43
44bool oneDimSimuTwoDimArrayDynamic(const int sizex, const int sizey) {
45 // C style
46 //int *ia = (int *)malloc((size_t)sizex * sizey * sizeof(int));
47 //int *ia = (int *)calloc((size_t)sizex * sizey, (size_t)sizeof(int));
48
49 //if (ia == NULL)
50 // return false;
51
52 // C++ style
53 int *ia = new int[sizex * sizey];
54
55 for(int j = 0; j != sizey; ++j) {
56 for(int i = 0; i != sizex; ++i) {
57 *(ia + j * sizex + i) = i + j;
58 }
59 }
60
61 cout << "1 dim dynamic array simulates 2 dim array on heap" << endl;
62
63 for(int j = 0; j != sizey; ++j) {
64 for(int i = 0; i != sizex; ++i) {
65 cout << *(ia + j * sizex + i) << " ";
66 }
67 cout << endl;
68 }
69
70 // C style
71 free(ia);
72 // C++ style
73 delete []ia;
74
75 return true;
76}
77
78int main() {
79 const int sizex = 3;
80 const int sizey = 2;
81
82 bool res;
83
84 res = oneDimArrayDynamic(sizex);
85 if (!res)
86 return -1;
87
88 res = oneDimSimuTwoDimArrayDynamic(sizex, sizey);
89 if (!res)
90 return -1;
91}
執行結果
0 1 2
1 dim dynamic array simulates 2 dim array on heap
0 1 2
1 2 3
malloc()和free()的原型如下
2void free(void *pmem); // stdlib.h
malloc()要傳進的參數為欲建立陣列的byte數,回傳為陣列第一個元素的pointer,因為malloc()是以byte為單位,在pre ANSI C的malloc()傳回的是char *,但在ANSI C均改為void *了,表示『通用的指標』,代表各種型別。17行的寫法
是一個標準的寫法,C語言並不要求一定要從(void *)轉成(int *),但C++則強烈要求,否則compiler會有cannot convert from 'void *' to 'int *'的錯誤訊息,而(size_t)的轉型則可有可無。
18行的calloc()的原型如下
n為陣列元素個數,size為每個元素的byte數,與malloc()不同的是,calloc()會將每個元素初始化為0。
若記憶體配置失敗,malloc()和calloc()都會傳回NULL。
23行為C++的寫法
語法乾淨多了,類似C語言C99的寫法,與malloc()一樣,new並不會將陣列做初始化的動作。
37行的free(),須配合malloc()或calloc()使用,39行的delete,則一定要搭配new使用,不可混用。
至於39行的delete []arr,為什麼[]要寫在arr前面呢?這真的是一個很怪異的語法,我目前還沒看到有任何書解釋為什麼?可能要看看BS的書怎麼解釋,若有網友知道,請告訴我,謝謝。
44行的oneDimSimuTwoDimArrayDynamic()只是實際用動態的一維陣列去模擬二維陣列,因為用C/C++做動態二維陣列並不容易,這是我下一個主題要討論的,各位就會看到為了使用二維subscripting的語法方便,需花這麼大的代價,還不如用一維陣列模擬就好,這是個典型的寫法,很容易懂,我就不多做解釋了,重點是這仍是一維陣列,不是二維陣列!!
若要由靜態的方式由一維陣列模擬二維陣列,請參閱(原創) 由一維陣列模擬二維陣列(多維陣列) (中級) (C/C++) 。
See Also
(原創) 由一維陣列模擬二維陣列(多維陣列) (C/C++)
(原創) 如何動態建立二維陣列(多維陣列)? (C/C++) (C)
(原創) 如何動態建立二維陣列(多維陣列)? (C/C++)
Reference
C/C++ 辭典 2nd p.170, p.217, p.252
C Primer Plus 5/e中文精華版 p.573