【C語言入門】169.字串字面常數與 const char *

這篇文章我們來介紹字串、字面常數和 const char* 之間的關係。

字面常數我們在這篇文章提過,要表達一個字串,我們會使用一組雙引號,把一串文字框起來。

字串再儲存的時候,是用字元陣列的方式儲存。

上一篇文章,我們有介紹了我們可以用 const 去修飾一個變數或一個值。

char strA[] = "test";
char *strB = "test";

strA[0] = 'T';  //(O)
strB[0] = 'T';  //(X) 未定義行為

strA = "Test";  //(X)編譯失敗
strB = "Test";  //(O)

我們在使用字串字面常數的時候你會發現,我們以前是用一個 character pointer 來處理字串字面常數,他會存這整個陣列第一個元素的位置。

為了安全起見,通常我們不改成前面加了 const 修飾字的,也就是說,我們不只是用 character pointer 來存放這個字串,我們用的是 const character pointer。

如果是 const character pointer,strB 裡面存的依舊是整個陣列裡的第一個位置。

但是因為陣列裡的每個元素,他都被變成一個 const 的 character,也就代表他是一個不能再被複製的字元。

char strA[] = "test";
const char *strB = "test";

strA[0] = 'T';  //(O)
strB[0] = 'T';  //(X) 未定義行為

strA = "Test";  //(X)編譯失敗
strB = "Test";  //(O)

當我們在函式之間傳遞字串的時候,以 printf 舉例,我們會用雙引號去傳字串。

事實上我們在傳遞的時候,這個型態其實就是 const character pointer。

printf("Hello World!");

當我傳雙引號過去的時候,printf 如果不小心把陣列內容做了修改,就會發生未定義行為。

那為甚麼 printf 不會不小心修改到呢?

我們來看 printf function 的 declaration:

int printf(const char *format, ...)

這是因為 printf 第一個參數型別的 character 字元前面是有加 const 的,因此 format 指標指向的字元陣列的內容是不會被更改到的,因為每個元素都是加 const 的元素。

char strA[] = "test";
const char *strB = "test";

strA[0] = 'T';  //(O)
strB[0] = 'T';  //(X) 未定義行為

strA = "Test";  //(X)編譯失敗
strB = "Test";  //(O)

一般情況下,能夠放雙引號的地方,也就是可以放字串字面常數的地方,通常就會是 const character pointer 的形式。

而如果你看一個函式給你要一個 const character pointer 形式的參數,通常也就代表那個地方可以放一個雙引號的字串。

Leave a Comment

Your email address will not be published. Required fields are marked *