文字列とconst
文字列がメモリのどの領域に配置されるか実験
#include <stdio.h>
char *p = "abc";
char *q = "abc";
const char s[] = "abc";
int main(void) {
char *r = "abc";
printf("p: %p %p\n", p, &p);
printf("q: %p %p\n", q, &q);
printf("r: %p %p\n", r, &r);
printf("s: %p\n", s);
return 0;
}出力結果
p: 0x10a938f04 0x10a939068
q: 0x10a938f04 0x10a939070
r: 0x10a938f04 0x7fff6a537b00
s: 0x10a938f08
文字列p、q、rが指す0x10a938f04と配列sのアドレス0x10938f08は読み取り専用の静的記憶領域(ROM領域)に置かれている。p、qのアドレス0x10a939068と0x10a939070は読み書き可能な静的記憶領域に置かれ、rのアドレス0x7fff6a537b00はスタックに置かれている
この時に、q[1]='@';等して値を変更しようとすると実行時にエラーが発生する。
これをコンパイル時に検出する為には変数qの宣言にconstを付ける
const char *q = abc
constの動作についてまとめ
constは必ず定数を意味するものではない。
char *my_strcpy(char *dest, const char *src) {
src = NULL;
}srcに代入しているのにコンパイルエラーにならない。
この時、読み取り専用になっているのは「src」ではなく「srcが指す先にあるもの」
char *my_strcpy(char *dest, const char *src) {
*src = 'a';
}この場合エラーになる
「src」そのものを読み取り専用にするなら
char *my_strcpy(char *dest, char * const src) {
src = NULL;
}この場合代入ができずエラーとなる
「src」と「srcの指す先にあるもの」を読み取り専用にするなら
char *my_strcpy(char *dest, const char * const src) {
src = NULL;
*src = 'a';
}この場合は両方ともエラーになる