Head First C という本を読んでいましたが、あ、そりゃそうだよね、と思ったところがあったので、忘備録として書いておきます。
話は、ある文字列を定義して、その後、プログラムの中でそれを変更したいようなケースです。
1)うまくいかないケース
~~~
char *cards = “JQK” ;
char a_card = cards[2];
cards[2] = cards[1];
~~~
こういうコードだとエラーになると。それはなぜかについて。
char *cards = “JQK”;
こう書くと、プログラム実行時には、まず、全ての定数値を定数メモリブロックに格納する。で、このメモリ領域はリードオンリーである。
次に、プログラムがスタックに cards 変数を作成する。
次に、cards 変数は JQK のアドレスに設定される。
文字列を変更しようとしても、リードオンリーなので出来ない -> エラー
2)うまくいくケース
char *cards = “JQK”;
を
char cards[] = “JQK”;
に変更する。
こうすると、まず、定数値をリードオンリー領域に格納する。
次に、プログラムがスタックに新しい配列を作成する。
次に、配列に対し、JQKの内容のコピーを行う。
配列に、定数のコピーを持っているので、これについては変更可能となる。
ま、文字列を変更したいときは注意、ということですね。でも、変更するつもりがないなら、const をつけて、
const char *s = “何らかの文字列” ;
としておけば、文字列を変更しようとするコードがあれば、コンパイルの段階でエラーが出せる、とも記述がありました。