C言語のポインタとは?基本の使い方と9種類のポインタ演算を徹底解説
ポインタとは
ポインタ(pointer)とは、別の変数のアドレス、すなわちメモリ上の格納位置を直接指し示す値を持つ変数のことです。通常の変数や定数と同様に、ポインタも変数のアドレスを格納する前に必ず宣言しておく必要があります。
まず、次の文を見てみましょう。
int qty = 179;
この変数はメモリ上で以下のように表現されます。
ポインタは次のように宣言します。
int *p;
これは「p は別の int 型変数のアドレスを保持するポインタ変数である」という意味です。
アドレス演算子(&)による初期化
ポインタ変数は、アドレス演算子「&」を使って初期化します。
int qty = 175;
int *p;
p = &qty;
これにより、ポインタ p には変数 qty のアドレスが格納されます。
間接参照演算子(*)による値へのアクセス
ポインタが指し示す先の変数の値にアクセスするには、間接参照演算子「*」を使用します。「*」は「そのアドレスに格納されている値」として捉えることができます。
したがって、次の2つの文はそれぞれ等価です。
p = &qty;
n = *p; /* n = qty と同じ意味 */
C言語における主なポインタ演算
C言語で行えるポインタ演算には、以下のようなものがあります。
代入:アドレス演算子「&」を使って、ポインタにアドレスを代入できます。
値の取得(デリファレンス):「*」演算子により、ポインタが指す位置に格納された値を取り出せます。
ポインタ自身のアドレス取得:ポインタ変数も他の変数と同じくアドレスと値を持ちます。アドレス演算子を使えば、ポインタ自体がどこに格納されているかを調べることができます。
ポインタへの整数の加算:「+」演算子でポインタに整数を加算したり、整数にポインタを加算したりできます。いずれの場合も、整数は指し示す型のバイト数と掛け合わされ、その結果が元のアドレスに加算されます。
ポインタのインクリメント:配列に対して使用すると、次の要素へ移動することができます。
ポインタからの整数の減算:「-」演算子でポインタから整数を減算します。整数は指し示す型のバイト数と掛け合わされ、その結果が元のアドレスから差し引かれます。
ポインタのデクリメント:デクリメントすると、直前の位置を指すようになります。前置形式・後置形式のどちらの記法でも使用可能です。
減算(ポインタ同士):2つのポインタの差を求めることができます。一般的には、2つの要素がどれだけ離れているかを調べる際に使われます。
比較:関係演算子を使って、2つのポインタの値を比較できます。
サンプルプログラム
以下は、C言語におけるポインタ演算の動作を確認するためのプログラム例です。
#include <stdio.h>
int main(void) {
int x, y;
int *p; /* ポインタの宣言 */
x = 10;
p = &x; /* ポインタへのアドレスの代入 */
y = *p; /* ポインタ経由での値の取得 */
printf("Value of x = %d\n", x);
printf("x is stored at address %u\n", &x);
printf("Value of x using pointer = %d\n", *p);
printf("Address of x using pointer = %u\n", p);
printf("Value of x in y = %d\n", y);
*p = 25; /* ポインタ経由での値の変更 */
printf("Now x = %d\n", x);
return 0;
}
実行結果
このプログラムを実行すると、次のような出力が得られます(アドレスの値は実行環境によって異なります)。
Value of x = 10
x is stored at address 5000
Value of x using pointer = 10
Address of x using pointer = 5000
Value of x in y = 10
Now x = 25
まとめ
ポインタは「&」でアドレスを取得し、「*」でその指し示す先の値にアクセスするのが基本動作です。さらに、整数の加減算、インクリメント・デクリメント、ポインタ同士の減算や比較など、多彩な演算が可能です。特に配列操作との相性が非常に良く、C言語プログラミングを理解するうえで欠かせない重要な概念といえます。
-
C言語の探索アルゴリズム解説|線形探索と二分探索の違いと実装例
探索(サーチ)とは、複数の要素で構成されるリストの中から、目的の「キー」となる要素を見つけ出す処理のことです。 リストの中に指定した要素が存在すれば、その探索は「成功」とみなされます。 指定した要素がリストに存在しなければ、その探索は「失敗(不成功)」となります。 C言語で広く使われている代表的な探索手法は、主に次の2つです。 線形探索(Linear Search/リニアサーチ) 二分探索(Binary Search/バイナリサーチ) 線形探索(Linear Search)とは 線形探索は、リストの先頭から順に要素を1つずつ取り出し、キーと一致するかどうかを確認していく、最も基本的な探
-
C言語の型変換入門:暗黙的変換と明示的変換(キャスト)の違いを徹底解説
あるデータ型を別のデータ型へ変換することを「型変換(type conversion)」と呼びます。C言語における型変換には、主に以下の2種類があります。 暗黙的な型変換(implicit conversion) 明示的な型変換(explicit conversion) 暗黙的な型変換とは 演算対象(オペランド)同士のデータ型が異なる場合、コンパイラが自動的に行う型変換です。 プログラマが特に指示しなくても、小さいデータ型から大きいデータ型への変換が自動的に実行されます。これを「型の昇格」とも呼びます。 int i,x; float f; double d; long int l;