1. 程式人生 > >char陣列與char指標的區別與聯絡

char陣列與char指標的區別與聯絡

字串(char*)與字元陣列(char[])區別
在C語言中,對字串的操作主要有兩種方式:一是字元陣列(char[]),二是使用字元指標(char*)。接下來最這兩種所使用的情況做徹底的說明:
一、字元陣列
字元陣列的定義有兩種方式:
1.char s[n];
n表示資料的大小。該語句可以理解為 宣告一個字元陣列,並且編譯器為該字元陣列分配n個記憶體空間,這是在編譯期進行的。
賦值有兩種方式:
(1)宣告並初始化
char s[10]="hello,world";//使用字串字面值(string literal)來初始化字元陣列
(2)已經分配了記憶體,然後進行賦值。
char s[10];
s[0]='h',s[1]='e';
錯誤的賦值方式:
(1)char s[];
s = "hello,world";
//這表明僅僅聲明瞭一個char陣列,但是不知道分配多大記憶體空間。
(2)char s[10];
s = "hello,world";//錯誤
s={'h','e','l','l','o'};//錯誤 s是指向陣列首地址的指標。
二、字元指標
可以使用char *str指向一個字串如:
char* str="C++";//宣告一個指向char的指標並進行初始化。
char* str;//宣告一個指標。
str ="C++";
三、兩者的區別
1. 既然 char *a 只是定義了一個指標 a,而並不為其指向的字串分配記憶體,那麼為什麼下面兩行程式碼又能夠編譯通過,且執行結果看上去是正常的?
char *a;
a = "abcde";
這兩行程式的執行過程中,編譯器/計算機都做了些什麼?
在這兩行程式的基礎上,為什麼賦值語句 *a = 'A' 又是不合法的(會導致執行時錯誤)?
相比於上面兩行程式,以下兩行也是不合法的,為什麼?
char a[];
a = "abcde";
答:(1)char *a; 這一行中編譯器做的事情是,宣告一個指向字元的指標,但是沒有讓該指標分配指向記憶體,它只是知道有一個變數 a 可能需要放在棧上;
假如後面需要取變數 a 的地址,那麼編譯器就被迫使 a 佔用棧空間.而假如編譯器決定使 a 不佔用棧空間就要給 a 在它需要保持值的期間保留一個
暫存器, 在執行時計算機不為此做任何事情。
(2)a = "abcde"; //這一行中編譯器做的事情是在字元常量記憶體空間定義一個"abcde"字串,讓字元指標a指向此字元常量記憶體空間的地址。由於該地址空間
不是在棧內,而存在類似於靜態儲存區這樣的空間。
(3)*a = 'A' 之所以會在執行時發發生錯誤,是因為匿名陣列所在的儲存空間是不可寫的。
(4)char a[];
a = "abcde";//以上是不合法的。首先,宣告陣列時如果沒有給變數初始化就必須指明陣列的長度。
其次,即使改成char a[6];a = "abcde";也是不合法的,這是因為你不能將指標值賦給一個數組。
或者用一個更簡單的說法:型別不同,並且不存在一個隱式轉換使得 char* 被轉換成 char[6] 。
2. 以下兩種初始化方式是否有本質區別?
char a[] = "abcde";
char *b = "abcde";
答:從效果上來說,上面兩個語句結果是一樣的,都獲取到字元的首地址。但是本質是不一樣的,char 陣列的初始化器會先為該陣列在棧內分配記憶體,
然後將匿名陣列的內容複製到物件所處的空間中char* 的初始化器會首先在字串常量空間記憶體生成一個常量字串"abcde",然後將該字串的首地址
賦值給字元指標物件。
3. 為什麼下面的程式碼
char *a, *b;
a = "abcde"; b = "abcde";
其執行結果中, a 和 b 會指向同一記憶體地址?而上一問中得到的 a 和 b 就不會指向同一記憶體地址。
答:不一定一樣,這取決於編譯器。
4. 對於陣列宣告(或初始化)的變數,例如
char a[6];

char a[]="abcde";
這句話是否正確?當 a 作為右值(rvalue)時,其型別為 char*;而當 a 作為左值(lvalue)時,其型別就是 char[6]。
答:這句話是錯誤的。從 char[6] 到 char* 有一個隱式轉換,這並不意味著 a 會有飄忽不定的型別。
我有這個疑問,是因為我試過幾次,發現以下程式碼可以正常執行
char a[]="abcde";
char *b;
b = a;
答:可以從char[]隱式轉換為char* 型別,但是不可以從char*型別轉換到char[]型別。
而以下程式碼會導致型別轉換錯誤
char *a="abcde";
char b[6];
b = a;
甚至,以下程式碼也會導致型別轉換錯誤,且錯誤提示和上一段程式碼是一樣的
char a[]="abcde";
char b[6];
b = a;
5.對於函式引數中的char[]和char*是否一樣?
答:在C語言中,陣列作為引數,進行傳遞時,傳遞的是指標 ,換句話說,字元陣列作為引數,進行傳遞時,
傳遞的是字元陣列的起始地址,相當於一個字元指標,兩者沒有區別。