9月 12, 2009

const char* 的兩三事

一整個大中招,完全錯誤的寫法如下:
char *str = "hello" ;
*str = "world" ; //想要改變 string 的內容
第一行的宣告,系統會配置空間存放 "hello" 字串。這筆資料是以常態(const)字串儲存,內容不允許更改。所以在第二行指令,希望透過 str 指標來改寫字串內容時,就會有問題。

比較好的方式,應該改採一維陣列來存放資料。當陣列在宣告時,系統會配置一段連續空間以供使用:
char str[30];
strcpy(str, "hello");
strcpy(str, "world");
另外也能使用「二維陣列」來存放資料。使用二維陣列時,因為系統是採 Row-Major 的方式存放資料,所以在函式中務必要提供陣列的維度(Row Dimension,下例中的 SIZE),這樣編譯器才知道如何存取資料。
#define SIZE 20
void set_string(char str[][SIZE])
{
strcpy(str[0], "hello");
}

main()
{
char str[SIZE][SIZE];
set_string(str);
}
另一個更具彈性的做法是,動態分配記憶體(malloc),如此一來參數傳遞時就不用考量到維度的資訊。
void set_string(char **ptr) //直接傳入雙重指標即可
{
strcpy(ptr[0], "hello");
strcpy(ptr[1], "world");
}
main()
{
char *buf[SIZE];
for (int idx=0;idx<SIZE;idx++)
buf[idx]= (char *) malloc(sizeof(char) * SIZE)
set_string(buf);
}
另一個非常重要的觀念,也是回到這篇的主題。在 set_string() 中的指令:
比較下列兩者,不要誤用了:
strcpy(ptr[0], "hello");
ptr[0] = "hello"
使用 strcpy() 是將字串寫到陣列中,陣列空間是當初系統配置的,所以其內容可以任意更改。而後者只是單純「將指標,指向字串」,字串的性質是常數(const),內容不允許修改。

沒有留言:

張貼留言