(原創) 如何動態建立一維陣列? (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.com3

4
Filename : ArrayDynamicOneDim.cpp5
Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++6
Description : Demo how to dynamic allocate 1 dim array on heap7
Release : 02/23/2007 1.08
*/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++ style23
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 style37
// free(ia);38
// C++ style39
delete []ia; 40
41
return true;42
}43

44
bool oneDimSimuTwoDimArrayDynamic(const int sizex, const int sizey) {45
// C style46
//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++ style53
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 style71
free(ia);72
// C++ style73
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()的原型如下
void *malloc(size_t size); // stdlib.h2
void free(void *pmem); // stdlib.h
malloc()要傳進的參數為欲建立陣列的byte數,回傳為陣列第一個元素的pointer,因為malloc()是以byte為單位,在pre ANSI C的malloc()傳回的是char *,但在ANSI C均改為void *了,表示『通用的指標』,代表各種型別。17行的寫法
int *arr = (int *)malloc((size_t)xsize * sizeof(int));
是一個標準的寫法,C語言並不要求一定要從(void *)轉成(int *),但C++則強烈要求,否則compiler會有cannot convert from 'void *' to 'int *'的錯誤訊息,而(size_t)的轉型則可有可無。
18行的calloc()的原型如下
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


浙公网安备 33010602011771号