1. 程式人生 > 其它 >簡單討論C中的字元陣列相關的問題

簡單討論C中的字元陣列相關的問題

1.字元陣列跟字元指標有什麼區別?

首先我們知道,定義一個字元陣列如下:

char arr[ ]= "abbbbbcdfefedfadsf"

定義一個字元指標如下:

char* p2 ="abbbbbcdfefedfadsf";

眨眼一看,感覺確實沒什麼區別,但我想說的是區別很大。

我們先來了解一下記憶體的大概儲存是如何分佈的:

圖一:記憶體的大致分佈

假設,陣列跟指標都在main函式中定義,從這個圖可以看出陣列跟指標都是在棧區開闢空間,因為他們都是區域性變數;

好,那麼我們從知道了他們都在棧區開始,來開始解答為什麼區別很大

(1)從初始化角度看是一樣的,都是給他們初始賦值成"abbbbbcdfefedfadsf";這個賦值的字串儲存的空間可不是都在棧區。

  char arr[ ]= "abbbbbcdfefedfadsf";

  char* p2 ="abbbbbcdfefedfadsf";

  arr[ ]中的字串是一種備份,而指標存入的是字串的地址;

  備份跟地址後面再說,先埋個伏筆。

(2)字元陣列跟字元指標的功能不同。

  你在用char arr[]的時候,雖然不能用arr直接賦值字串,即 arr = “hello world”;但你可以用arr[ i ],i∈(0~(arr元素個數 - 1)),來改變arr陣列的值;

  而字元指標的本質就是指向了一個記憶體空間,只要是有權可以訪問,指標就可以指向該記憶體區域並修改這個區域的值,所以說指標真的不能亂用好吧。

(3)最後來說說,備份跟地址的事。

  假設定義int arr[ 10 ] = { 0 };

  陣列儲存的時候,其實是在棧區開闢了一塊連續的儲存空間;第一個元素arr[ 0 ]為最低的地址,每次地址+1時,依次訪問後面的元素,當地址+9時,訪問的元素就是arr[ 9 ]。而初始化為0,其實就是把arr[ 0 ] = 0;arr[ 1 ] = 0;......arr[ 9 ] = 0。這就是所謂的備份;

  那麼在char arr[ ]= "abbbbbcdfefedfadsf" 這句當中,實際就是把每個字元給到對應元素中,最後一個元素就是放了‘\0’表示字串結束,當你除錯VS或者VC的時候,就可以看到arr[ 0 ] = ‘a’;arr[ 0 ] = ‘b’;......arr[ 18 ] = ‘\0’;

圖二:陣列的各個元素情況

因為這是對最初版本(就是"abbbbbcdfefedfadsf")的copy,那肯定是可以改的,所以要對某字串進行修改可以採用字元陣列寫法;

那指標可以嗎?如果你要修改它所指向的字串,我們就試試吧。

圖三:程式掛了

好傢伙,程式直接崩了。

那現在我們可以知道定義char* p1 ="abbbbbcdfefedfadsf";p1實際上是不可變的,那這個原因我想大家應該看了最上面的圖一就知道了,一般來說p1指向的是一塊空間,而你單寫一段字串,像"abbbbbcdfefedfadsf",系統會將這個字串儲存到程式碼段裡,這個程式碼段可牛了,儲存的是一種常量,是不可修改的,固定的值。p1指向了不可修改的空間,你要去改它的值,那當然不行。所以我們一般寫這種程式碼,最好寫成 const char* p1 = "abbbbbcdfefedfadsf"; 前面的const是修飾*p1整體,表示不可修改p1所指向的值。

2.這兩者定義有何區別?

char arr1 [ ] = "abcd" ①

char arr2 [ ] = {‘a’,‘b’,‘c’,‘d’ } ②

我們在VS19run一下

結果很明顯了,arr2實際就只有4個元素,剛開始學習的時候很多小夥伴都是認為這兩種沒什麼區別,結果就導致了一些bug的出現,在以後寫程式碼時,要避免這種小錯誤;

最後,總結一下

(1)char* p1 ="abbbbbcdfefedfadsf";寫法不嚴謹,最好寫成 const char* p1 = "abbbbbcdfefedfadsf";

(2)如果要修改字串裡的值,寫成字元陣列形式,一般是在函式傳參時,需要特別注意;

(3)char arr1 [ ] = "abcd" ,char arr2 [ ] = {‘a’,‘b’,‘c’,‘d’} 兩種寫法並不等價;