【6日でできるC言語入門】関数の引数としてのポインタ変数

C言語では関数に値を渡す方法として「値渡し」と「ポインタ渡し」の2種類があります。
特に「ポインタ渡し」は、関数の外の変数の値を関数内で直接書き換えたい時や、複数の値を返したい時に重要な役割を持ちます。
本記事では、ポインタを引数に持つ関数の使い方とそのメリットについて解説します。

1.ポインタ引数の基礎

1.1. 値渡しとポインタ渡しの違い

種類特徴
値渡し変数の「値」そのものをコピーして関数に渡す。関数内で変更しても元の変数には影響しない。void func(int x);
ポインタ渡し変数の「アドレス」を渡す。関数内で元の変数の値を書き換え可能。void func(int *x);

1.2. ポインタ引数を使ったサンプル

【サンプル】2つの変数の値を“ポインタを使って”交換する

プロジェクト/ファイル名: Lesson51_1/main.c

#include <stdio.h>

// 2つのint型の値を入れ替える関数
void swap_values(int*, int*);

int main(void) {
    int x = 10, y = 25;
    printf("交換前: x = %d, y = %d\n", x, y);

    swap_values(&x, &y);   // x, y のアドレスを渡す

    printf("交換後: x = %d, y = %d\n", x, y);
    return 0;
}

// ポインタで受け取った2つの値を入れ替える
void swap_values(int* a, int* b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

実行結果

交換前: x = 10, y = 25
交換後: x = 25, y = 10

2.ポインタ引数の具体的な処理イメージ

2.1. swap_values関数の流れ

ステップ*a(xの値)*b(yの値)tmp(仮の箱)説明
11025初期値
2102510tmp = *a(xの値をtmpへ)
3252510*a = *b(yの値をxへ)
4251010*b = tmp(tmpの値をyへ)

2.2. ポインタ引数を使うことで得られるメリット

  • 関数内で複数の値を書き換え・返すことができる
  • メモリ効率が良い(値のコピーではなくアドレスの受け渡しのみ)
  • 配列や構造体など「大きなデータ」の扱いにも必須

3.ポインタ引数の注意点

3.1. アドレスの渡し忘れ・NULLチェック

ポインタ引数を使う際は、変数のアドレス(&演算子)を渡すことを忘れないでください。
また、NULLポインタ(どこも指していない)を誤って渡すとエラーや異常動作の原因になるので注意しましょう。

3.2. 型の一致

ポインタ引数の型と、渡す変数の型は必ず一致させます。
例:int*型にはint型の変数のアドレス、double*型にはdouble型の変数のアドレス。

4.ポインタ引数の活用例

4.1. 【例】2つのdouble値の和と差を求める関数

プロジェクト/ファイル名: Lesson51_2/main.c

#include <stdio.h>

void calc_sum_diff(double, double, double*, double*);

int main(void) {
    double a = 3.5, b = 1.2, sum, diff;
    calc_sum_diff(a, b, &sum, &diff);
    printf("和: %.2f, 差: %.2f\n", sum, diff);
    return 0;
}

void calc_sum_diff(double x, double y, double* s, double* d) {
    *s = x + y;
    *d = x - y;
}

実行結果

和: 4.70, 差: 2.30

まとめ

  • ポインタ引数を使うことで、関数から複数の値を返したり、呼び出し元の変数を書き換えたりできる。
  • 値渡しとの違いをしっかり理解し、場面ごとに使い分けることが大切。
  • 実際に手を動かして、様々な関数でポインタ引数を使ってみましょう。

ポインタを使いこなせるようになると、C言語の理解がより一段と深まります!