C言語のポインタ入門!宣言・初期化から配列アクセスの実例まで徹底解説
ポインタ(pointer)とは、他の変数のメモリアドレスを格納するための変数です。C言語においてポインタは、メモリを直接操作したり、関数間でデータを効率的にやり取りしたりするために欠かせない重要な概念です。
ポインタの宣言・初期化とアクセス
まず、次のような通常の整数変数の宣言を見てみましょう。
int qty = 179;
変数qtyには値「179」が格納されると同時に、メモリ上のどこかにその格納場所(アドレス)が割り当てられます。
ポインタの宣言
int *p;
「p」はポインタ変数であり、別の整数型(int)変数のアドレスを保持します。変数名の前にアスタリスク(*)を付けることで、「これはポインタである」ことをコンパイラに伝えます。
ポインタの初期化
ポインタ変数の初期化には、アドレス演算子(&)を使用します。&を変数の前に付けると、その変数のメモリアドレスを取得できます。
int qty = 175; int *p; p = &qty;
このコードでは、ポインタpにqtyのアドレスが代入され、「pはqtyを指している」状態になります。
実践例:ポインタによる文字配列へのアクセス
それでは、ポインタが文字列(文字の配列)の要素へアクセスする際にどのように役立つのか、具体的なサンプルで確認しましょう。
次のプログラムでは、配列内の特定の位置にある要素へポインタ経由でアクセスし、その値を操作しています。ポイントは前置インクリメント(++*p)で、これは「ポインタが指し示す先の値をインクリメントする」という動作になります。
サンプルプログラム
#include<stdio.h>
int main(){
char s[] = {'a', 'b', 'c', '\n', 'c', '\0'};
char *p, *str, *str1;
p = &s[3];
str = p;
str1 = s;
printf("%d", ++*p + ++*str1 - 32);
return 0;
}
出力結果
77
解説
処理の流れを順番に追ってみましょう。
p = &s[3];… 配列sの4番目の要素「'\n'」のアドレスをpに代入します。str = p;… strもpと同じく「'\n'」の位置を指します。str1 = s;… 配列名sは先頭要素のアドレスを表すため、str1は「'a'」を指します。
続いて、printf文の中の計算を見ていきます。
- '\n' のASCIIコードは10なので、
++*pにより 10 + 1 = 11 になります。 - 'a' のASCIIコードは97なので、
++*str1により 97 + 1 = 98 になります。
したがって、計算式は以下のようになります。
++*p + ++*str1 - 32 = 11 + 98 - 32 = 77
この結果、画面には「77」が出力されます。
まとめ
ポインタは変数のアドレスを扱う強力な仕組みです。&(アドレス演算子)でアドレスを取得し、*(間接参照演算子)でその指し示す先の値にアクセスします。「*p」(値の参照)と「++*p」(値の更新)の違いを正しく理解できれば、配列や文字列を柔軟かつ効率的に操作できるようになり、C言語プログラミングの幅が大きく広がります。
-
C言語におけるユニオンとポインタの使い方を徹底解説
ユニオン(共用体)とは、異なるデータ型を持つ複数の変数が、同一のメモリ領域を共有するための仕組みです。構造体が各メンバーごとに独立したメモリを割り当てるのに対し、ユニオンではすべてのメンバーが同じアドレスを参照するという点が大きな特徴です。 ユニオンの構文 ユニオンを定義するときの基本的な書式は次の通りです。 union タグ名{ データ型 メンバー1; データ型 メンバー2; ---- ---- データ型 メンバーn; }; 実際の記述例を見てみましょう。 union sample{ int a; float b; char
-
C#のクラスとは?基本概念からコンストラクタまで徹底解説
C#におけるクラスは、最も重要な型の一つです。クラスは、問題領域に関連するオブジェクトを生成するための「設計図」と考えることができます。つまり、クラスはテンプレートであり、そこからオブジェクトを作成します。クラスには、そのクラスから作られるオブジェクト群が共有する構造(データ)と振る舞い(メソッド)が定義されています。たとえるなら、クラスは「クッキーの型」であり、オブジェクトはその型で作られた「クッキー」そのものです。 カプセル化という重要な概念 クラスは、オブジェクト指向プログラミングにおける重要な概念である「カプセル化」を実現します。カプセル化とは、データと、そのデータを操作する処理を一箇