ポインタ演算
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 9/63。
*(array + i) のようなポインタ表記を使用して配列の要素にアクセスする方法を学びました。ここでは、さらに強力なテクニックである ポインタ演算 を学びます。これを使えば、単純なインクリメントやデクリメント操作でメモリ内のポインタを移動させることができます。
ポインタを ++ でインクリメントしたり、-- でデクリメントしたりするとき、ポインタは単に1バイト移動するわけではありません。代わりに、それが指し示すデータ型のサイズ分だけ移動します。整数ポインタの場合、ptr++ は sizeof(int) バイト分進み、メモリ上のちょうど次の整数に到達します。
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // 最初の要素 (10) を指します
ptr++; // 2番目の要素 (20) を指すようになります
ptr++; // 3番目の要素 (30) を指すようになりますこの自動的なサイズ計算こそが、ポインタ演算を非常に強力で便利なものにしています。バイト計算を心配する必要はありません。C言語がポインタのデータ型に基づいて、メモリのアドレッシングを自動的に処理してくれます。
ポインタ演算は、ループ内で配列を走査する際に特に有用です。配列のインデックスを使用する代わりに、ポインタをインクリメントして各要素を順番に移動することができ、多くの場合、より効率的なコードになります。
チャレンジ
簡単ポインタのインクリメント操作を使用して配列を走査および処理することにより、ポインタ演算を実証するCプログラムを作成してください。プログラムは以下の内容を行う必要があります:
- 5つの要素を持つ
dataという名前の整数配列を宣言し、値 {12, 24, 36, 48, 60} で初期化します。 ptrという名前の整数へのポインタを宣言し、配列の最初の要素を指すように初期化します。- ポインタ演算のみを使用して配列全体を走査する、5回実行される for ループを使用します。
- ループ内:
- 間接参照演算子を使用して、
ptrが指している現在の値を表示します。 %pフォーマット指定子を使用して、ptrに格納されているメモリ番地を表示します。ptr++を使用してポインタをインクリメントし、次の要素に移動します。
- 間接参照演算子を使用して、
- ループの後、
ptrを配列の最初の要素を指すようにリセットします。 - ポインタ演算を使用して、
*(ptr + 2)により3番目の要素(インデックス 2)に直接アクセスして表示します。 - ポインタ演算を使用して、
*(ptr + 4)により最後の要素(インデックス 4)に直接アクセスして表示します。
出力は以下の形式で結果を表示する必要があります:
Value: 12, Address: [address]
Value: 24, Address: [address]
Value: 36, Address: [address]
Value: 48, Address: [address]
Value: 60, Address: [address]
Third element: 36
Last element: 60このチャレンジでは、ポインタのインクリメント操作がデータ型のサイズ分だけ自動的に移動すること、およびポインタ演算を使用してベースポインタの位置から特定のオフセットにある配列要素にアクセスする方法についての理解をテストします。
チートシート
ポインタ演算を使用すると、インクリメントおよびデクリメント操作を使用してメモリ内でポインタを移動させることができます。ポインタをインクリメントすると、1バイトではなく、それが指しているデータ型のサイズ分だけ移動します。
基本的なポインタ演算操作:
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // 最初の要素 (10) を指す
ptr++; // 2番目の要素 (20) を指すようになる
ptr++; // 3番目の要素 (30) を指すようになるポインタ演算を使用して、特定のオフセットにある要素にアクセスすることもできます。
*(ptr + 2) // 現在の位置からオフセット2にある要素にアクセスするポインタ演算はループ内での配列の走査に便利であり、多くの場合、配列のインデックスを使用するよりも効率的なコードになります。
自分で試してみよう
#include <stdio.h>
int main() {
// TODO: ここにコードを記述してください
// 配列 'data' を宣言し、値 {12, 24, 36, 48, 60} で初期化します
// ポインタ 'ptr' を宣言し、最初の要素を指すように初期化します
// ポインタ演算を用いた for ループを使用して配列を走査します
// 各値とアドレスを出力し、ポインタをインクリメントします
// ポインタをリセットし、ポインタ演算を使用して特定の要素にアクセスします
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。