
【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.1400003.構造体ポインタの実践的な使い方
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言語でより実用的なプログラムを書くための第一歩です!
