【6日でできるC言語入門】構造体のポインタ

 C言語の「構造体のポインタ」は、構造体データを効率的に扱うために欠かせないテクニックです。構造体そのものを関数に渡すと、コピー処理が発生して無駄が多く、また値の変更も呼び出し元には反映されません。
 しかし、構造体のアドレス(ポインタ)を渡すことで、データの無駄なコピーを防ぎ、関数内で元の値を直接変更できるようになります。
 ここでは、構造体ポインタの基本から、関数引数への活用法まで、図やサンプルコードを使って分かりやすく解説します。

1.構造体ポインタの基本

1.1. 構造体のポインタとは

構造体型の変数に対しても、通常の変数と同じように**ポインタ(アドレスを保持する変数)**を使うことができます。

構文例意味
student_data *p;student_data型構造体のポインタpを宣言
p = &data;構造体変数dataのアドレスをpに代入
p->idポインタpが指す構造体のメンバidにアクセス

「->」演算子

構造体ポインタが指す先のメンバには、「->」演算子を使ってアクセスします。
これは「(*p).id」の省略形です。

1.2. 構造体の値渡しとポインタ渡し

構造体を関数に渡す場合、「値渡し」と「ポインタ渡し」で大きな違いがあります。

方法メリット/デメリット
値渡しコピーが発生、関数内の変更は呼び出し元に反映されない。
ポインタ渡しコピーせずに済み、関数内の変更が呼び出し元に反映

2.サンプルプログラムで学ぶ構造体ポインタ

2.1. ポインタによる構造体の操作

サンプル:構造体ポインタを使ったデータ変更

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

#include <stdio.h>
#include <string.h>

typedef struct {
    int number;
    char name[100];
    double price;
} PRODUCT;

// 値渡し
void setByValue(PRODUCT prod) {
    prod.number = 2;
    strcpy(prod.name, "コーヒー");
    prod.price = 120.0;
}

// ポインタ渡し
void setByPointer(PRODUCT* pprod) {
    pprod->number = 2;
    strcpy(pprod->name, "コーヒー");
    pprod->price = 120.0;
}

int main(void) {
    PRODUCT item1 = {1, "お茶", 100.0};
    PRODUCT item2 = {1, "お茶", 100.0};

    setByValue(item1);      // 値渡し
    setByPointer(&item2);   // ポインタ渡し

    printf("item1: %d %s %.1f\n", item1.number, item1.name, item1.price);
    printf("item2: %d %s %.1f\n", item2.number, item2.name, item2.price);

    return 0;
}

実行結果

「SDLチェック」を「いいえ」にして、プログラムを実行します。

item1: 1 お茶 100.0
item2: 2 コーヒー 120.0

解説

  • 値渡し(item1)は関数内の変更がmain側に反映されない。
  • ポインタ渡し(item2)は関数内の変更がmain側にも反映される。

2.2. 構造体ポインタとアドレス操作

サンプル:アドレス確認と「->」演算子

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

#include <stdio.h>

typedef struct {
    int a;
    double b;
} TEST;

void showPointer(TEST* p) {
    printf("アドレス: %p\n", (void*)p);
    printf("a=%d, b=%f\n", p->a, p->b);
}

int main(void) {
    TEST t = { 5, 3.14 };
    showPointer(&t);
    return 0;
}

実行結果

アドレス: 00000095648FF908
a=5, b=3.140000

3.構造体ポインタの実践的な使い方

3.1. 配列・動的メモリとの連携

構造体の配列や、mallocで動的に確保した構造体も、ポインタで簡単に操作できます。

サンプル:配列とポインタ

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

#include <stdio.h>

typedef struct {
    int score;
} DATA;

int main(void) {
    DATA list[2] = { {80}, {90} };
    DATA* p = list;

    printf("1人目の点数: %d\n", p->score);
    printf("2人目の点数: %d\n", (p+1)->score);

    return 0;
}

実行結果

1人目の点数: 80
2人目の点数: 90

まとめ

  • 構造体のポインタは、「データのコピー無しで元の値を直接操作できる」強力な手法
  • 関数で値を変更したい、配列や動的メモリと組み合わせたい時はポインタ渡しが基本
  • アクセスには「->」演算子を使う

構造体ポインタの理解は、C言語でより実用的なプログラムを書くための第一歩です!