C言語定数ポインタとconstポインタ完全マスター
C言語において、ポインタは別の変数のメモリアドレスを格納する変数であり、constキーワードは一度初期化したら値を変更できない変数やポインタを定義するために使用されます。ポインタとconstキーワードを組み合わせると、2つのことを制御できます:
- ポインタに格納されたアドレスを変更できるかどうか。
- そのアドレスに格納された値を変更できるかどうか。
この章では、定数ポインタの3つの主要なバリエーションを見ていきます:
- 定数ポインタ(Constant Pointer)
- 定数へのポインタ(Pointer to Constant)
- 定数への定数ポインタ(Constant Pointer to Constant)
定数ポインタ(Constant Pointer)
定数ポインタとは、ポインタ自体が定数であることを意味します。一度メモリ位置を指すように初期化されると、異なる位置を指すことはできませんが、その位置に格納された値は変更可能です。
以下は定数ポインタの構文です:
data_type *const pointer_name = &variable;
この構文では、data_typeはポインタが指すデータの型、*constがポインタ自体を定数にし、pointer_nameがポインタ名、&variableが変数のメモリアドレスを割り当てます。
定数ポインタの例
この例では、定数ポインタptrを宣言し、変数xのアドレスで初期化します。その後、ptrを使ってxの値を変更し、その値を表示します。
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int *const ptr = &x; // intへの定数ポインタ
printf("Value of x: %d\n", *ptr);
*ptr = 15; // アドレスの値を変更可能
printf("Modified value of x: %d\n", *ptr);
// ptr = &y; // ポインタアドレス変更は不可
return 0;
}
以下は上記プログラムの出力で、ポインタがxに固定されているが、xの値は更新可能であることを示しています。
Value of x: 10 Modified value of x: 15
定数ポインタエラーの例
ここでは定数ポインタptrを宣言し、変数xのアドレスで初期化します。その後、変数yのアドレスを指すようにしようとします。これはエラーになります。なぜなら定数ポインタは一度初期化されると別のメモリ位置を指せないからです。
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int *const ptr = &x; // intへの定数ポインタ
printf("Value of x: %d\n", *ptr);
// 別の変数yを指すように試みる
ptr = &y; // 定数ポインタのアドレス変更不可
return 0;
}
以下にエラーを示します。定数ポインタのアドレスを変更できないことを示しています。
error: assignment of read-only variable 'ptr'
定数へのポインタ(Pointer to Constant)
定数へのポインタとは、指している値を変更できないが、ポインタ自体は異なるメモリアドレス(または変数)を指せることを意味します。
以下は定数へのポインタの構文です:
const data_type *pointer_name = &variable; data_type const *pointer = &variable;
この構文では、const data_typeまたはdata_type constはポインタが定数値を指すことを意味し、pointer_nameはポインタ名、&variableが変数のアドレスを割り当てます。
定数へのポインタの例
この例では、定数値を指すポインタptrを宣言し、変数aのアドレスを割り当てます。その後、ポインタを変数bの別アドレスを指すようにし、その値を表示します。
#include <stdio.h>
int main() {
int a = 5;
int b = 30;
const int *ptr = &a; // 定数intへのポインタ
printf("Value of a: %d\n", *ptr);
// *ptr = 10; // ポインタ経由で値変更不可
ptr = &b; // ポインタアドレス変更可能
printf("Now pointing to b: %d\n", *ptr);
return 0;
}
以下は上記プログラムの出力で、同じポインタが異なる変数を指していることを示しています。
Value of a: 5 Now pointing to b: 30
定数へのポインタエラーの例
ここでは定数へのポインタptrを宣言し、変数aのアドレスで初期化します。その後、ポインタ経由でaの値を変更しようとします。これはエラーになります。なぜなら定数へのポインタは指している値の変更を許可しないからです。
#include <stdio.h>
int main() {
int a = 5;
const int *ptr = &a; // 定数intへのポインタ
printf("Value of a: %d\n", *ptr);
// 定数へのポインタ経由で値変更不可
*ptr = 10;
return 0;
}
以下に出力を示します。定数へのポインタ経由で値を変更できないことを示すエラーです。
error: assignment of read-only location '*ptr'
定数への定数ポインタ(Constant Pointer to Constant)
定数への定数ポインタは、メモリアドレスを変更できず、かつそのメモリアドレスに格納された値も変更できないポインタです。両方の操作が制限されるため、値を読み取ることしかできません。
以下は定数への定数ポインタの構文です:
const data_type *const pointer_name = &variable;
この構文では:
- const data_typeは、ポインタ経由でメモリ位置の値を変更できないことを示します。
- *const pointer_nameは、ポインタ自体が初期化後に他のメモリアドレスを指せないことを意味します。
- &variableはポインタを変数のメモリアドレスに割り当てます。
定数への定数ポインタの例
この例では、定数への定数ポインタptrを宣言し、変数aのメモリアドレスを割り当てます。その後、ポインタを使ってaの値を表示します。
#include <stdio.h>
int main() {
int a = 10;
const int *const ptr = &a; // 定数への定数ポインタ
printf("Value of a: %d\n", *ptr);
// *ptr = 15; // 値変更不可
// ptr = &b; // ポインタ位置変更不可
return 0;
}
以下は上記プログラムの出力です:
Value of a: 10
定数への定数ポインタエラーの例
この例では、定数への定数ポインタptrを宣言し、変数aで初期化します。その後、ポインタ経由で値を変更し、さらに別の変数を指すようにしようとします。両操作とも許可されず、コンパイルエラーになります。
#include <stdio.h>
int main() {
int a = 10;
int b = 20;
const int *const ptr = &a; // 定数への定数ポインタ
printf("Value of a: %d\n", *ptr);
// *ptr = 15; // 値変更不可
// ptr = &b; // ポインタアドレス変更不可
return 0;
}
以下にエラーを示す出力を表示します:
Value of a: 10
定数ポインタタイプの違い
以下の表は、定数ポインタ、定数へのポインタ、定数への定数ポインタの違いを示しています。
| バリエーション | 定義 | アドレス変更可? | 値変更可? | 構文例 |
|---|---|---|---|---|
| 定数ポインタ | アドレス固定だが、そのアドレスの値は変更可能 | 不可 | 可 | int *const p = &x; |
| 定数へのポインタ | 異なるアドレスを指せるが、指先の値は変更不可 | 可 | 不可 | const int *p = &x; |
| 定数への定数ポインタ | アドレス固定かつ、そのアドレスの値も変更不可 | 不可 | 不可 | const int *const p = &x; |
結論
この章では、C言語の定数ポインタと定数へのポインタを解説しました。定数ポインタはアドレスを固定し値変更を許可、定数へのポインタはアドレス変更を許可し値変更を制限、定数への定数ポインタは両方を制限します。
C言語
- C# 変数とプリミティブデータ型:完全マスターガイド
- C++演算子完全ガイド:算術・代入・関係・論理・ビット演算子と実例
- C#の構造体:値型の定義と活用を徹底解説
- C++マルチスレッド完全ガイド:効率的な並行プログラミング
- C++演算子オーバーロード:コード例付き実践ガイド
- C言語ユーザー定義関数の4つの実証済みパターン
- C 言語 switch-case 文の理解: 構文、例、ベストプラクティス
- C++関数オーバーロード実践ガイド:同名異なるシグネチャの活用法
- C言語ポインタ完全マスター:実践的ステップで上級プログラミングへ
- C++リファレンス完全理解:重要概念とポインタとの違い
- C#開発環境:ツールとフレームワークの概要