Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

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は「ポインタ自体」を保護します。このルールを覚えておけば、複雑な宣言でも迷わず読み解けるようになります。

  1. C#と.NETの違いをわかりやすく解説!言語とフレームワークの関係

    C#と.NETの基本的な違いC#(シーシャープ)はマイクロソフトが開発したプログラミング言語であり、一方の.NET(ドットネット)はアプリケーション開発を支援するフレームワークです。この2つは密接な関係にありますが、それぞれの役割はまったく異なります。.NETの中核となる「共通言語ランタイム(CLR)」.NETには「共通言語ランタイム(CLR:Common Language Runtime)」と呼ばれる仮想的な実行環境が組み込まれています。CLRはメモリ管理、例外処理、セキュリティなどを担当し、.NET上で動作するすべてのアプリケーションの土台となる重要なコンポーネントです。C#だけじゃない!

  2. GoとJavaの違いを徹底比較!特徴と使い分けのポイント

    プログラミング言語を選ぶ際、「Go」と「Java」のどちらを採用すべきか迷う開発者は少なくありません。どちらもGoogleや企業システムで広く使われる人気言語ですが、設計思想や言語仕様には大きな違いがあります。本記事では、それぞれの言語の特徴を解説したうえで、両者の主な違いを比較表を使ってわかりやすく整理します。 GoとはGoはGoogleが開発した手続き型(プロシージャル)プログラミング言語です。プログラムはパッケージ単位で構成され、シンプルで読みやすいコード記述を重視した設計になっています。動的言語に近い柔軟なパターンを取り入れつつ、静的型付けによる安全性も兼ね備えています。また、軽量スレ