在〈字元陣列與字串〉談過 C 風格字串,本質上就是個字元陣列,而陣列名稱具有指標性質,那可以如下建立字串嗎?
char *text = "hello";
以前可以,不過使用 MinGW-w64,GNU 編譯器版本 8.1.0 編譯的話,會有以下警訊:
warning: ISO C++ forbids converting a string constant to 'char*'
text
儲存了字串常量的位址值,然而字串常量建立的內容是唯讀的,必須如下才不會有警訊:
const char *text = "hello";
上述方式中,text
只是個型態為 const char*
的指標,是與以下不同的,底下建立的 text
內容並不是唯讀的,因為 text
是個陣列,text
是將 "hello"
複製至各索引處:
char text[] = "hello";
對於 wchar_t
等其他為了支援 Unicode 的型態,都有這類特性。
然而,無論是哪個形式,都可以傳遞位址,例如:
char text1[] = "hello";
const char *text2 = "hello";
const char *text = text1; // OK
text = text2; // OK
不過,底下不行:
char text1[] = "hello";
const char *text2 = "hello";
char *text = text1; // OK
text = text2; // error: invalid conversion from 'const char*' to 'char*'
錯誤該行如果真的想通過編譯,就必須明確告訴編譯器,你要去除 const
修飾,也就是使用 const_cast
:
char text1[] = "hello";
const char *text2 = "hello";
char *text = text1; // OK
text = const_cast<char*>(text2); // OK
會需要這麼做的情況,可能是在使用一些舊的函式,它們在參數上宣告的是 char*
,而不是 const char*
。
那麼,如何建立字串陣列呢?
#include <iostream>
#include <cstring>
using namespace std;
int main() {
const char *names[] = {"Justin", "Monica", "Irene"};
for(auto name : names) {
cout << name << endl;
}
return 0;
}
留意一下底下的不同:
const char *names1[] = {"Justin", "Monica", "Irene"};
char names2[][10] = {"Justin", "Monica", "Irene"};
name1
的每個元素,儲存了各個字串常量的位址值;然而,name2
是有三個長度為 10 的 char
陣列,並複製了各個字串常量的 char
。
在 C++ 中使用 C 風格字串是比較麻煩的,可以的話建議使用 string
。