C言語で構造体を引数に渡す方法
- 作成日: 2022-01-05
- 更新日: 2024-03-19
- カテゴリ: C言語
C言語の構造体を引数に渡す方法
C言語では構造体を扱うことができます。
この記事では構造体を関数の引数に渡す方法を具体的に解説します。
構造体は関数とともによく使われます。
そのため関数における構造体の扱い方を押さえておくのは有用と言えます。
今回は↓を中心に解説します。
- 構造体を引数にコピーして渡す
- 構造体のポインタを引数に渡す
- 構造体の配列を引数に渡す
C言語や他の言語を扱うYoutubeも公開しています。
興味がある方は以下のリンクからご覧ください。
関連記事
目が覚めるC言語のdo-while文の使い方【ループ処理、初心者向け】
明快!C言語のcontinue文の使い方
君はまだC言語のdefineのすべてを知らない【マクロ、プリプロセス】
メッセージボックスの型と構造体 - Rustで作るWindowsアプリ
プログラミングのポインタをわかりやすく解説【C言語】
関連動画
C言語の構造体を関数の引数に渡す方法 - YouTube
構造体を引数にコピーして渡す
↓のような関数の定義があったとき、この関数の引数に構造体を渡すと構造体がコピーされます。
void func(struct Animal arg) {
...
}
具体的には↓のようなコードになります。
#include <stdio.h>
// 動物を表す構造体
struct Animal {
int age; // 年齢
char name[40]; // 名前
};
// 引数のargには構造体がコピーされる
void func(struct Animal arg) {
// argのメンバを出力
printf("age[%d] name[%s]\n", arg.age, arg.name);
}
int main(void) {
// cat変数を定義する
struct Animal cat = { 20, "Tama" };
// funcにcatをコピーして渡す(値渡し)
func(cat);
return 0;
}
上記のコードをコンパイルして実行すると↓のような結果になります。
age[20] name[Tama]
上記のコードではmain
関数内でstruct Animal
構造体の変数cat
を定義しています。
そしてそのcat
をfunc()
に渡しています。
// cat変数を定義する
struct Animal cat = { 20, "Tama" };
// funcにcatをコピーして渡す(値渡し)
func(cat);
この時、関数の呼び出し側の引数を実引数、関数の定義側の引数を仮引数と言います。
実引数cat
はfunc()
の仮引数arg
にコピーされて渡されます。
// 引数のargには構造体がコピーされる
void func(struct Animal arg) {
// argのメンバを出力
printf("age[%d] name[%s]\n", arg.age, arg.name);
}
引数arg
にはcat
のデータがコピーされていますので、cat
とarg
はそれぞれ別のメモリ上に確保されています。
そのためmain()
関数側でcat
のデータを変更したり、func()
側でarg
のデータを変更しても、cat
とarg
それぞれは干渉しません。
このような値渡しによる引数への構造体の渡し方は、一般的にあまり効率がよくありません。
というのも、構造体のメンバが増えればそれだけコピーのコストが増えるからです。
そのため、速度を必要とするプログラムでは後述するポインタ渡し(アドレス渡し)のほうが一般的です。
関連記事
C言語の構造体をコピーする
構造体のポインタを引数に渡す
構造体のポインタを関数の引数に渡すには↓のようにします。
#include <stdio.h>
// 動物を表す構造体
struct Animal {
int age; // 年齢
char name[40]; // 名前
};
// 引数のargには構造体のポインタが渡される
void func(struct Animal *arg) {
// argのメンバを出力
printf("age[%d] name[%s]\n", arg->age, arg->name);
}
int main(void) {
// cat変数を定義する
struct Animal cat = { 20, "Tama" };
// funcにcatのアドレス(ポインタ)を渡す
func(&cat);
return 0;
}
func()
関数の引数は「struct Animal *arg
」です。
これはstruct Animal
のポインタ変数(ポインタ引数)になります。
// 引数のargには構造体のポインタが渡される
void func(struct Animal *arg) {
// argのメンバを出力
printf("age[%d] name[%s]\n", arg->age, arg->name);
}
main()
関数側では構造体変数のcat
のアドレス(ポインタ)をfunc()
に渡しています。
// cat変数を定義する
struct Animal cat = { 20, "Tama" };
// funcにcatのアドレス(ポインタ)を渡す
func(&cat);
変数の頭に&
(アンパサンド)を付けるとその変数のアドレスを取り出すことができます。
このような「struct Animal *arg
」という引数は関数内で構造体のデータを間接的に参照したい&変更したい場合などによく使われます。
const
を付けていないのでarg
で参照できるデータはfunc()
内でも変更が可能です。
void func(struct Animal *arg) {
arg->age = 30;
strcpy(arg->name, "Hige");
}
参照だけしてデータを変更する予定がない場合は引数にconst
を付けて「const struct Animal *arg
」のように書きます。
// constを付けたポインタ
void func(const struct Animal *arg) {
// 書き込みできないのでエラーになる
arg->age = 30;
}
関連記事
C言語の構造体のポインタの使い方
構造体の配列を引数に渡す
構造体の配列も関数の引数に渡せます。
#include <stdio.h>
// 動物を表す構造体
struct Animal {
int age; // 年齢
char name[40]; // 名前
};
// 配列を引数に取る
void func(struct Animal animals[]) {
// animalsを出力
printf("0: age[%d] name[%s]\n", animals[0].age, animals[0].name);
printf("1: age[%d] name[%s]\n", animals[1].age, animals[1].name);
printf("2: age[%d] name[%s]\n", animals[2].age, animals[2].name);
}
int main(void) {
// 配列を定義する
struct Animal cats[] = {
{ 20, "Tama" },
{ 30, "Pochi" },
{ 40, "Yamada" },
};
// funcに配列を渡す
func(cats);
return 0;
}
func()
関数の引数は「struct Animal animals[]
」になってます。
これは一見すると配列のように見えますが、実体はただのポインタです。
ですので配列を引数に渡す場合は関数側の引数を「struct Animal *animals
」にしても大丈夫です。
見た目的には[]
にしたほうが配列だとわかるので、配列の場合は*
ではなくて[]
が使われることが多くあります。
関連記事
C言語の構造体の配列の使い方
おわりに
今回はC言語の構造体を関数の引数に渡す方法を解説しました。
構造体は関数とセットでよく使われます。
🦝 < 構造体を引数にシュート
🐭 < C言語マスターに俺はなる