陣列是一種資料結構,能夠儲存多個相同資料型別的資料。比如:儲存全班同學的年齡,儲存全班同學的身高等。雖然陣列看起來很簡單,但在實際應用中,還是有很多需要注意的地方。在本文中,列出了我所目前遇到的難點和重點,希望可以和大家分享分享。如有疏漏之處,還望各位讀者可以進行補充。
顧名思義,靜態陣列便是陣列長度固定的陣列,我們需要在宣告陣列時,便指定陣列的長度,且在程式執行過程中無法改變。比如:
int array1[10]
=;//宣告乙個包含10個int型別資料的陣列,且全部初始化為0
int array2=
;//宣告了乙個包含3個int型別資料的陣列,陣列中的資料分別為:1,2,3
const
int array_size =
100;
double array3[array_size]=;
//宣告乙個包含100個int型別資料的陣列,且初始化為0
如果我們試圖在程式執行時更改陣列的長度,如下:
int array_size =10;
int array[array_size]
=;
那麼,編譯器一定會報錯,並指明陣列的長度不能夠是變數。
綜上所述,對於靜態陣列而言,是在程式編譯過程中,就需要完成為陣列分配儲存空間等工作,這也算是一種面向過程程式設計的一處體現。
對於某些我們無法明確陣列長度的應用場景,唯一的辦法便是使陣列的長度盡可能的大一點,盡可能可以容納所有的資料。但這樣便可能會導致記憶體的浪費,而且擴充套件性也非常低下,看起來十分笨拙。
顧名思義,動態陣列是可以在程式執行期間,對陣列的長度進行改變。換句話說,我們可以在程式的執行過程中,指定陣列的長度,以滿足不同的需求。
那麼,我們如何實現動態更改陣列長度的目的呢?在c語言中,我們一般使用malloc函式和free函式,實現記憶體空間的動態分配。但是在c++中,可以使用更好的new運算子和delete運算子,完成上述功能。
相對應的是,malloc函式和new運算子的作用均是在堆空間上開闢乙個新的記憶體空間,free函式和delete運算子則是在需要時及時釋放剛才開闢的記憶體空間,避免記憶體洩漏。下面,我們來**如何使用new和delete運算子實現動態陣列。
我們在利用new和delete運算子建立動態陣列時,需要知道三個資訊:
1、需要建立的陣列的長度array_size;
2、陣列資料的資料型別type_name;
3、什麼時候對記憶體進行釋放。
比如:
int
* new_int_array =
newint[10
];//建立乙個包含10個int型別資料的陣列,並返回陣列的首位址給new_int_array..
...delete
new_int_array;
//在合適的地方,釋放上面開闢的記憶體空間
double
* new_double_array =
newdouble
[100];
//建立乙個包含100個double型別資料的陣列..
....
delete
new_double_array;
//釋放空間
與c語言中的malloc函式一樣,我們在利用new運算子開闢了乙個新的空間之後,將返回該記憶體空間的首位址。
所以,我們需要利用乙個指標變數接收該位址。並且,該指標變數指向的資料型別必須與new出來的記憶體空間中將要儲存的資料型別保持一致,否則無法通過編譯,比如:
double
* new_array =
newint[10
];//這是錯誤的,因為資料型別不同..
....
delete
new_array;
//釋放整個陣列空間
在成功利用new建立乙個動態陣列之後,我們便可以利用指標和陣列之間的關係對陣列中的資料進行處理了。如下:
int
* array =
newint[3
];//開闢乙個包含3個int資料的陣列,並返回首位址給array指標變數
array[0]
=1;array[1]
=2;array[2]
=3;//對陣列進行賦值操作
cout <<
"第乙個元素為"
<<
*(array +0)
<< endl;
//輸出1
cout <<
"第二個元素為"
<<
*(array +1)
<< endl;
//輸出2
cout <<
"第三個元素為"
<< array[2]
<< endl;
//輸出3
delete
array;
//釋放開闢的記憶體空間
在使用new和delete建立和釋放動態陣列時,需要注意以下事項:
1、不能使用delete釋放不是由new分配的動態記憶體;
2、不能使用delete多次釋放同乙個new出來的記憶體;
3、如果使用new [ ]為陣列分配儲存空間,那麼需要使用delete [ ]來進行釋放;
4、對空指標而言,可以使用delete進行釋放。
與靜態陣列相比,動態陣列更加靈活,也更符合人類的思維。但同時也增大了危險性,尤其是當new之後,如果未及時delete,便會發生記憶體洩漏。
下標為0的陣列元素表示的是陣列的第乙個元素,以此類推。
當訪問超過陣列長度的空間時,將發生陣列越界的現象。這可能導致非常嚴重的錯誤,甚至導致系統崩潰。所以,在訪問陣列元素時,一定要避免越界訪問,比如:
int array[2]
=;//初始化陣列
cout << array[1]
<< endl;
//輸出10
array[0]
=9;//將9賦值給陣列的第乙個元素
array[2]
=10;//越界訪問
靜態陣列之間是不允許進行整體賦值的,比如:
int array1[3]
=;int array2[3]
=;array2 = array1;
//報錯
而只能單個的進行賦值操作,比如:
int array1[3]
=;int array2[3]
=;for(
int i =
0;i <
3;i++
)
int
* array1 =
newint[10
];*(array1+0)
=1;*
(array1+1)
=2;*
(array1+2)
=3;*
(array1+3)
=4;.
....
.*(array1+9)
=10;//對陣列進行初始化
int* array2 =
newint[10
];array2 = array1;
//這是正確的,此時,array2與array1指向同乙個記憶體位址,並沒有重新建立乙個陣列..
....
delete
array1;
delete
array2;
本文中,主要講解了靜態陣列和動態陣列的一些知識,以及一些注意事項。而在c++中,還另外提供了兩個陣列的替代品,分別是模板類vector和模板類array,我們將在後面的文章中進行專門的學習。 golang復合資料型別 陣列
顧名思義,復合資料型別就是由其他型別組合而成的型別。go語言基本的復合資料型別有 指標 陣列 切片 字典 map 通道 結構和介面 go語言提供了陣列型別的資料結構。陣列是具有相同唯一型別的一組編號且長度固定的資料項序列,這種型別可以是任意的原始型別,例如 整形 字串或者自定義型別。陣列元素可以通過...
新手上路系列4 復合資料型別
今天就記一下復合資料型別相關的內容吧。復合資料型別 1 struct 1 struct是乙個用來宣告結構體型別的關鍵字,它只是起到乙個宣告的作用,所以記憶體並沒有為它分配空間。變數定義時有多種不同的方式,比如以下幾種 1 struct student stu 定義了乙個student結構體變數,變數...
Go語言復合資料型別之map
map的操作 雜湊表是乙個無序的key value對的集合,要求所有的key必須不同,然後通過給定的key可以在o 1 內檢索 更新或者刪除對應的value。go語言中map就是乙個雜湊表,其表達形式為map key value key在map中是同一種資料型別,其中key必須是支援比較運算子的型別...