ポインタとconst

ポインタはアドレスを格納する変数。

constは変数を書き換えないようにする修飾子。

この2つを組み合わせると面倒です。

int main(){
	int a, b;
	const int *p = &a;
	a = 10;
	//*p = 10;	エラー
	p = &b;
}
int main(){
	const int a = 10, b = 0;
	int const *p = &a;
	//a = 10;	エラー
	//*p = 10;	エラー
	p = &b;
}
int main(){
	const int a = 10, b = 0;
	//int *p = &a;	エラー
	p = &b;
}

 const int *型(int const *と書いても同じ)は,const int型へのポインタです。

int main(){
	int a, b;
	int * const p = &a;
	*p = 10;
	//p = &b;	エラー
}

 int * const型は,int型へのconstポインタです。

int main(){
	int a, b;
	const int * const p = &a;
	//*p = 10;	エラー
	//p = &b;	エラー
}

const int * const型(int const * constと書いても同じ)は,const int型へのconstポインタです。

ポインタのポインタをとってみましょう。

int main(){
	int a;
	int *p1, *p2;
	int **pp = &p1;
	**pp = 10;
	*pp = &a;
	pp = &p2;
}

これにconstを付けてみます。

int main(){
	int a;
	int *p1;
	const int *p2;
	const int **pp;
	//pp = &p1;	エラー
	pp = &p2;
	*pp = &a;
	//**pp = 10;	エラー
}

const int **は,const int *型へのポインタです。int *型はconst int *型に変換されましたが,int **型はconst int **型に変換できません。

int main(){
	int a;
	int *p1;
	int * const * pp;
	pp = &p1;
	//*pp = &a;	エラー
	**pp = 10;
}

 int * const *型は,int * const型へのポインタです。int **型はint * const *型に変換できます。int * const *の参照先のポインタは変更できませんが,参照先の参照先は変更できます。

int main(){
	int a;
	int *p1, *p2;
	int ** const pp = &p1;
	//pp = &p2;	エラー
	*pp = &a;
	**pp = 10;
}

int ** const型は,int *型へのconstポインタです。