如何動態建立一維陣列? (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的第一個元素。

 1 /* 
 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
13 using   namespace  std;
14
15 bool  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
44 bool  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
78 int  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}


執行結果

1  dim dynamic array on heap
0   1   2
1  dim dynamic array simulates  2  dim array on heap
0   1   2
1   2   3


malloc()和free()的原型如下

1 void   * malloc(size_t size);  //  stdlib.h
2 void  free( void   * pmem);  //  stdlib.h


malloc()要傳進的參數為欲建立陣列的byte數,回傳為陣列第一個元素的pointer,因為malloc()是以byte為單位,在pre ANSI C的malloc()傳回的是char *,但在ANSI C均改為void *了,表示『通用的指標』,代表各種型別。17行的寫法

1   int   * arr  =  ( int   * )malloc((size_t)xsize  *   sizeof ( int ));


是一個標準的寫法,C語言並不要求一定要從(void *)轉成(int *),但C++則強烈要求,否則compiler會有cannot convert from 'void *' to 'int *'的錯誤訊息,而(size_t)的轉型則可有可無。

18行的calloc()的原型如下

1 void   * calloc(size_t n, size_t size);


n為陣列元素個數,size為每個元素的byte數,與malloc()不同的是,calloc()會將每個元素初始化為0。

若記憶體配置失敗,malloc()和calloc()都會傳回NULL。

23行為C++的寫法

int   * ia  =   new   int [sizex];


語法乾淨多了,類似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

你可能感兴趣的:(c/c++)