C言語における「const char*」「char* const」「const char* const」の違いを徹底解説
ポインタとconstの基本
C言語において、*pはポインタが指し示す先に格納されている値を表し、pはその値が格納されているアドレス(メモリ上の場所)を表します。このアドレスを保持する変数が「ポインタ」と呼ばれます。
ポインタ宣言にconstを組み合わせることで、「指し示す先の値」を変更できるかどうかと、「ポインタ自体」を変更できるかどうかを個別に制御できます。この2つの組み合わせにより、以下の3つのパターンが生まれます。
1. const char*(char const* と同じ)
const char* および char const* は、「定数charへのポインタ」を意味します。このポインタが指す先のcharの値は変更できません。しかし、ポインタ自体は定数ではないため、別の定数charを指し示すように変更することは可能です。
2. char* const
char* const は、「charへの定数ポインタ」を意味します。このポインタが指す先のcharの値は変更できます。しかし、ポインタ自体が定数になっているため、別のcharを指し示すように変更することはできません。
3. const char* const
const char* const は、「定数charへの定数ポインタ」を意味します。このポインタが指す先の値も変更できず、ポインタ自体も変更できません。つまり、宣言時に初期化した内容から一切変更できない、完全に固定された状態になります。
読み方のコツ:右から左へ
これらの宣言を正しく理解するための経験則として、「宣言構文を右から左へ読む」という方法があります。
// 定数charへの定数ポインタ const char * const // charへの定数ポインタ char * const // 定数charへのポインタ const char *
C言語での実例
以下のコードでは、コメントアウトされた誤った代入文をコメント解除すると、コンパイルエラーが発生することを確認できます。
#include <stdio.h>
int main() {
// 例: char const*
// 注意: char const* は const char* と同じ意味
const char p = 'A';
// q は定数charへのポインタ
char const* q = &p;
// 不正な代入
// p の値は変更不可
// エラー: assignment of read-only location '*q'
//*q = 'B';
const char r = 'C';
// q は別の定数charを指せる
q = &r;
printf("%c\n", *q);
// 例: char* const
char u = 'D';
char * const t = &u;
// 値は変更できる
*t = 'E';
printf("%c", *t);
// 不正な代入
// t は変更不可
// エラー: assignment of read-only variable 't'
//t = &r;
// 例: char const* const
char const* const s = &p;
// 不正な代入
// s の指す値は変更不可
// エラー: assignment of read-only location '*s'
// *s = 'D';
// 不正な代入
// s 自体も変更不可
// エラー: assignment of read-only variable 's'
// s = &r;
return 0;
}実行結果
C E
まとめ
| 宣言 | 指す先の値の変更 | ポインタ自体の変更 |
|---|---|---|
| const char* | 不可 | 可 |
| char* const | 可 | 不可 |
| const char* const | 不可 | 不可 |
このように、constの位置によって保護される対象が異なります。*の左側にあるconstは「指す先の値」を保護し、*の右側にあるconstは「ポインタ自体」を保護します。このルールを覚えておけば、複雑な宣言でも迷わず読み解けるようになります。
-
C#と.NETの違いをわかりやすく解説!言語とフレームワークの関係
C#と.NETの基本的な違いC#(シーシャープ)はマイクロソフトが開発したプログラミング言語であり、一方の.NET(ドットネット)はアプリケーション開発を支援するフレームワークです。この2つは密接な関係にありますが、それぞれの役割はまったく異なります。.NETの中核となる「共通言語ランタイム(CLR)」.NETには「共通言語ランタイム(CLR:Common Language Runtime)」と呼ばれる仮想的な実行環境が組み込まれています。CLRはメモリ管理、例外処理、セキュリティなどを担当し、.NET上で動作するすべてのアプリケーションの土台となる重要なコンポーネントです。C#だけじゃない!
-
GoとJavaの違いを徹底比較!特徴と使い分けのポイント
プログラミング言語を選ぶ際、「Go」と「Java」のどちらを採用すべきか迷う開発者は少なくありません。どちらもGoogleや企業システムで広く使われる人気言語ですが、設計思想や言語仕様には大きな違いがあります。本記事では、それぞれの言語の特徴を解説したうえで、両者の主な違いを比較表を使ってわかりやすく整理します。 GoとはGoはGoogleが開発した手続き型(プロシージャル)プログラミング言語です。プログラムはパッケージ単位で構成され、シンプルで読みやすいコード記述を重視した設計になっています。動的言語に近い柔軟なパターンを取り入れつつ、静的型付けによる安全性も兼ね備えています。また、軽量スレ