關於char[]和char*的理解


本質區別

char str[]表示str是一個字符數組,str這個字符數組里面所有的元素都是單個的字符,因此char[]強調的是數組的概念。

char* str表示str是一個指針,str這個指針指向了一個字符的地址,因此char*強調的是指針的概念。

 

char[]字符串

由於C語言中沒有“字符串”這種數據類型,而字符串本質上就是將一個個的字符串聯起來,那么完全可以使用字符數組來表示一個字符串:

char str[5] = {'h', 'e', 'l', 'l', 'o'};
這樣從物理空間來講,確實是一個又5個單字符構成的hello的字符串,但是這種寫法看起來不夠直觀,寫起來要加很多的單引號很麻煩,而且比較關鍵的一點是,如何能夠輸出str這個字符串?
如果我們嘗試用printf來輸出這個字符串:
char str[5] = {'h', 'e', 'l', 'l', 'o'};
printf("%s", str);

執行后會發現打印出來前面是對的,但是后面會攜帶一些亂碼(這些亂碼在各個平台的表現形式不同),原因是printf中%s輸出方式是檢測直到遇到'\0'為止,它並不管你這個字符串(在這里就是str這個字符數組)是多長的,只認為我遇到了'\0'就認為這個字符串結束,所以連帶打出了后面一些無法預知的符號,也就是亂碼,直到遇到'\0',也就是我們俗稱的結束符。

 

那既然字符串是以結束符作為結尾的,那就可以手動給這個str字符串添加一個'\0':

char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

注意'\0'也是占據一個字節的,所以此時str的長度變成了6,當然也可以省略不寫數組長度,但實際有效字符其實是5個。

剛提到這種寫法很難一眼看出這是一個字符串,至少在我們的認知中,更容易接受像"hello"這種直觀的表示方法,因此C提供了一種直觀的初始化字符數組的方法:

char str[6] = {"hello"};

這種寫法,不需要顯示的寫出結束符,但是要給結束符預留一個字符,也就是一個字節的位置,所以一樣的,str長度為6,有效字符還是5個。

通常我們把{}省略,用字符數組表示字符串的最簡便形態就是:

char str[6] = "hello";

 

char*字符串

按照正常的理解char*理應像int*之類的基本類型一樣,表示指向的位置存放着一個char類型的變量,也就是指向的是一塊1個字節的內存地址,也就是這樣:

char a = 'A';
char * p = &a;
printf("%c", *p);  // A

但是為什么能夠用char*表示一個字符串?

因為在C語言中像"hello"這樣的字符串本質是用一個地址來表示,用的就是"hello"中的首地址也就是'h'字符的地址。

這樣的話就可以用char*來表示一個字符串,更准確的說是指向這個字符串的首地址:

char* str = "hello"; 

編譯器會自動為"hello"加上一個結束符,用來標志字符串的結束位置。 

 

區別

首先從本質上就是有區別的,char[]是遵循的是數組的規則,含有數組的特性;char*遵循的是指針的規則,含有指針的特性。

其次當使用char* str = "hello"時,編譯器會在常量區創建一個字符串常量"hello",然后str指向這個字符串常量的首地址,編譯器在編譯時就知道str指向的是一個常量。

而char[]雖然是寫成char str[] = "hello",但是是在運行時將"hello"中的字符逐個放入str數組中,所以此時的"hello"並不是常量,而是被拆成了棧上str數組中的各個元素。

因此,使用char* str = "hello"后,不能夠通過str指針來改變常量"hello";使用char[] str = "hello"后,依然能夠改變數組中的各個字符。

 

那么可能我們會好奇,既然char* str = "hello"中的"hello"是常量,為什么還允許我們通過char* str獲取指向"hello",萬一我們通過str企圖改變"hello"不是很危險嗎?

其實編譯器會警告我們:

warning: ISO C++ forbids converting a string constant to 'char*'

禁止將不變字符串轉為char*,如何避免這種警告呢?既然編譯器不想我們改,我們就主動告訴它我沒有想要改變常量字符串的企圖即可:

const char* str = "hello";

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM