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

C言語の参照とポインタとは?違いをサンプルコード付きでやさしく解説

はじめに

Cプログラミングを学ぶうえで避けて通れないのが「参照」と「ポインタ」の概念です。本記事では、それぞれの特徴・構文・違いを、実際に動くサンプルコードとともにわかりやすく解説します。

参照とは

参照とは、宣言済みの変数につけられた「別名(エイリアス)」のようなものです。主な特徴は次のとおりです。

  • 宣言した変数の別名として振る舞う
  • 値渡し(pass by value)のように扱える
  • null値を持つことができない

※補足:厳密には「参照」はC++の機能であり、純粋なC言語には変数の別名を作る構文は存在しません。C言語で変数を間接的に操作するための仕組みが、後述する「ポインタ」です。

ポインタとは

ポインタとは、変数がメモリ上のどこに配置されているかを示す「アドレス」を格納するための変数です。主な特徴は次のとおりです。

  • 変数のアドレスを格納できる
  • null値(NULLポインタ)を保持できる
  • 参照渡し(pass by reference)のように関数へ渡せる
  • 宣言時に初期化しなくてもよい

ポインタの宣言構文

データ型 *変数名;

例:int *a; —— aはint型変数のアドレスを格納するポインタとなります。

アドレスの代入構文

ポインタ変数 = &別の変数;

&は「アドレス演算子」と呼ばれ、変数の先頭アドレスを取得します。一方、*は「間接参照演算子(デリファレンス)」と呼ばれ、ポインタが指し示す先の値にアクセスします。

サンプルコード

#include <stdio.h>

int main(void){
    int a = 2, b = 4;
    int *p;
    printf("add of a=%d\n", &a);
    printf("add of b=%d\n", &b);
    p = &a; /* pは変数aを指す */
    printf("a value is =%d\n", a);   /* aの値を表示 */
    printf("*p value is =%d\n", *p); /* p経由でaの値を表示 */
    printf("p value is =%d\n", p);   /* aのアドレスを表示 */
    p = &b; /* pは変数bを指す */
    printf("b value is =%d\n", b);   /* bの値を表示 */
    printf("*p value is =%d\n", *p); /* p経由でbの値を表示 */
    printf("p value is =%d\n", p);   /* bのアドレスを表示 */
    return 0;
}

実行結果

add of a=-748899512
add of b=-748899508
a value is =2
*p value is =2
p value is =-748899512
b value is =4
*p value is =4
p value is =-748899508

実行結果の読み方

  • p = &a; を実行した直後は、*p がaの値「2」を、p がaのアドレスを表しています。
  • 続く p = &b; で指し先をbに切り替えると、同じ *p が今度はbの値「4」を返します。これが「ポインタは指し先を自由に変更できる」という大きな特徴です。
  • アドレスとして表示される数値は、実行環境や実行のたびに異なります。重要なのは数値そのものではなく、「pにaのアドレスを入れると *p がaの値になる」という対応関係です。

参照とポインタの比較まとめ

項目参照ポインタ
正体変数の別名アドレスを格納する変数
null値保持できないNULLを保持できる
指し先の変更不可可能
宣言時の初期化必須任意
主な言語C++C / C++

まとめ

ポインタは「アドレスを格納する変数」、参照は「変数そのものの別名」です。C言語で実際に使うのはポインタであり、&でアドレスを取得し、*で指し先の値へアクセスするという基本の流れを押さえておきましょう。まずは小さなサンプルを自分で書いて、挙動を確認することが上達への近道です。

  1. C言語入門:モノリシックプログラミングとモジュラープログラミングの違いを徹底解説

    本記事では、C言語におけるモノリシックプログラミングとモジュラープログラミングの違いを、それぞれのメリット・デメリットとともに詳しく解説します。 モノリシックプログラミングとは プログラム全体を1つの関数、すなわちmain関数だけですべて記述する方式を「モノリシック(一枚岩)型プログラミング」と呼びます。しかし、すべてのロジックを単一の関数に詰め込むのは、良いプログラミングスタイルとは言えません。 デメリット モノリシックプログラミングには、以下のような欠点があります。 プログラムが非常に大きく、複雑になりやすい。 デバッグ、テスト、保守が非常に困難になる。 モジュラープログラミングとは

  2. C#の値型と参照型の違いを徹底解説!メモリの仕組みとサンプルコードで比較

    C#におけるすべての型は、大きく分けて「値型」と「参照型」という2つのカテゴリに分類されます。この2つの違いを正しく理解することは、バグの防止やパフォーマンスの最適化において非常に重要です。本記事では、それぞれの型の特徴、動作の仕組み、そして実際のコード例を使った挙動の違いについて詳しく解説します。 値型とは 値型の変数は、データそのものを直接保持します。各変数が独自のデータコピーを持つため、ある変数の値を変更しても、別の変数やオブジェクトには一切影響しません。 C#における値型には、以下のようなものがあります。 int、float、double などのすべての数値型 char 型および b