|
char *とconst char *は違う
char *とconst char *は違います(当然)。ではどう違うか明確にわかりますか?一言で言えば「データ型」が違いますね。これについてはC言語編「データ型とポインタ」を見てください。
さて、「const char *」というデータ型は、書き換えできない(読み取り専用の)文字列に対して使います。簡単に使い方を見てみましょう。
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
char str[32] = "sample";
const char *pstr = str;
pstr[5] = 'a'; // エラー 書き込みはできない
strcat(pstr, "program"); // エラー char *とconst char *は互換性がない
return 0;
}
|
「const char *」型の変数pstrを作りました。これは文字列のポインタをあらわしていますが、文字列の内容を後から書き換えることはできません。間違えないでほしいのは、ポインタ変数の内容を書き換えられないということではありませんよ。ポインタがさす文字列が書き換えられないんです。(ポインタ変数の内容は書き換えられます。)
また、strcat()の第一引数は「char *」型なので、互換性のない「const char
*」型は渡すことはできません。
当然、無理矢理ほかのデータ型のポインタにキャストして書き換えることはできますが、そんな暴挙をしない限り、データが書き換わらないことを保障できる安全なデータ型です。これは積極的に使っていきましょう。
例えば、関数のプロトタイプ宣言が次のようなものだったとしたとき、これを見て、「おっ、この関数は渡した文字列の内容は書き換えないんだな。安心。安心。」と解釈できます。
int StoreStr(const char *str);
|
しかし、関数のプロトタイプ宣言が次のようなものだったら、「うっ、この関数は何をするかわからないぞ。これは危険だな。」となってしまいます。
関数を作るときに、何気なく引数に「char *」型を使っていませんか?関数の中で文字列を書き換えない場合は、それを主張するために、引数を「const
char *」型にするようにしましょう。
さて、C++では「データ型」に対しては非常に厳密さを要求します。それだけ安全性が高まっているということですね。「const
char *」から「char *」へのキャストに関しては、特殊なキャスト方法をとらないとキャストできません。「const」をとってしまうというのは、非常に危険なことだというのを言語が主張しているんですね。
それは、Cでも全く同じです。「char *」型と「const char *」型は全く違うということを理解しておきましょう。
|