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

C言語入門:ポインタと1次元配列の基本を徹底解説


ポインタとは、他の変数のアドレス(メモリ上の場所)を格納するための変数です。C言語においてポインタは非常に重要な概念であり、メモリを直接操作することで効率的なプログラムを作成できます。

ポインタの特徴

ポインタには主に以下のような特徴があります。

  • メモリ空間を節約できる。
  • メモリ上の場所へ直接アクセスするため、実行速度が速い。
  • ポインタを利用することでメモリを効率的に扱え、動的なメモリの確保と解放が可能になる。
  • 連結リストなどのデータ構造と組み合わせて活用される。

ポインタの宣言・初期化・アクセス

まず、次の文を見てみましょう。

int qty = 179;

このとき、変数qtyはメモリ上で次のように表現されます。

ポインタの宣言

ポインタの宣言とは、「p」が別の整数型変数のアドレスを保持するポインタ変数であることを定義することです。宣言は次のように行います。

int *p;

ポインタの初期化

ポインタ変数の初期化には、アドレス演算子「&」を使用します。

例:

int qty = 175;
int *p;
p = &qty;

この例では、変数qtyのアドレスがポインタpに代入され、pはqtyを指す状態になります。

ポインタ経由での変数へのアクセス

ポインタが指し示す先の変数の値を取得するには、間接演算子(デリファレンス演算子)「*」を使用します。

ここで「*」は「そのアドレスに格納されている値」と捉えることができます。

したがって、次の2つの文は等価です。

p = &qty;
n = *p;   /* n = qty と同じ意味 */

ポインタと1次元配列

  • コンパイラは、配列のすべての要素に対して連続したメモリ領域を割り当てます。
  • ベースアドレスとは、配列の先頭要素(インデックス0)のアドレスのことです。
    • 例:int a[5] = {10, 20, 30, 40, 50};

配列要素のメモリ配置

5つの要素は、メモリ上に次のように順番に格納されます。

  • pが整数型ポインタとして宣言されている場合、次のいずれかの代入によって配列aを指すことができます。

p = a;
または p = &a[0];

配列名aはそれ自体が先頭要素のアドレスを表すため、どちらの書き方でも同じ意味になります。

  • p++ を使ってポインタを1つずつ進めることで、配列の各要素へ順にアクセスできます。ポインタをインクリメントすると、その値はポインタが指すデータ型のサイズ分だけ増加します。この増分の大きさは「スケールファクタ」と呼ばれます。

  • pとaの関係は以下のようになります(int型が4バイトの場合)。

P = &a[0] = 1000
P+1 = &a[1] = 1004
P+2 = &a[2] = 1008
P+3 = &a[3] = 1012
P+4 = &a[4] = 1016
  • 各要素のアドレスは、インデックスとデータ型のスケールファクタを使って計算できます。以下に具体的な例を示します。

a[3] のアドレス = ベースアドレス + (3 × int型のスケールファクタ)
= 1000 + (3 × 4)
= 1000 + 12
= 1012
  • 配列の添字(インデックス)を使う代わりに、ポインタを使って配列要素にアクセスすることも可能です。

  • *(p+3) は a[3] の値を表します。

a[i] = *(p+i)

サンプルプログラム

以下は、ポインタと1次元配列を使用したC言語のサンプルプログラムです。

#include<stdio.h>
main( ){
    int a[5];
    int *p, i;
    printf("Enter 5 elements");
    for (i=0; i<5; i++)
        scanf("%d", &a[i]);
    p = &a[0];
    printf("Elements of the array are");
    for (i=0; i<5; i++)
        printf("%d", *(p+i));
}

実行結果

上記のプログラムを実行すると、次のような出力が得られます。

Enter 5 elements : 10 20 30 40 50
Elements of the array are : 10 20 30 40 50
  1. C言語におけるユニオンとポインタの使い方を徹底解説

    ユニオン(共用体)とは、異なるデータ型を持つ複数の変数が、同一のメモリ領域を共有するための仕組みです。構造体が各メンバーごとに独立したメモリを割り当てるのに対し、ユニオンではすべてのメンバーが同じアドレスを参照するという点が大きな特徴です。 ユニオンの構文 ユニオンを定義するときの基本的な書式は次の通りです。 union タグ名{ データ型 メンバー1; データ型 メンバー2; ---- ---- データ型 メンバーn; }; 実際の記述例を見てみましょう。 union sample{ int a; float b; char

  2. C言語のポインタ入門!宣言・初期化から配列アクセスの実例まで徹底解説

    ポインタ(pointer)とは、他の変数のメモリアドレスを格納するための変数です。C言語においてポインタは、メモリを直接操作したり、関数間でデータを効率的にやり取りしたりするために欠かせない重要な概念です。 ポインタの宣言・初期化とアクセス まず、次のような通常の整数変数の宣言を見てみましょう。 int qty = 179; 変数qtyには値「179」が格納されると同時に、メモリ上のどこかにその格納場所(アドレス)が割り当てられます。 ポインタの宣言 int *p; 「p」はポインタ変数であり、別の整数型(int)変数のアドレスを保持します。変数名の前にアスタリスク(*)を付けることで、「こ