C言語で構造体を代入する方法
目次
C言語で構造体を代入する方法
C言語では構造体というデータ構造を扱うことができます。
構造体を使うと異なる型の変数を1つにまとめることができるので非常に便利です。
この構造体は変数などに代入することができます。
代入することで構造体のデータをコピーして複製することができます。
この記事ではC言語の構造体の代入について詳しく解説します。
関連記事
構造体変数に構造体変数を代入する
構造体で定義した変数を構造体変数と言います。
構造体変数はたとえば↓のように定義します。
struct Animal { int age; char name[40]; }; int main(void) { struct Animal cat = {20, "Tama"}; return 0; }
上記のコードのmain関数内のcat
という変数が構造体変数になります。
この構造体変数cat
はstruct Animal
構造体の変数です。
struct Animal
はint age;
とchar name[40];
という変数を持っています。
この構造体内で定義している変数をメンバ変数と言います。
構造体変数を定義するときは↓のようにコードを書いて、メンバ変数を初期化します。
struct Animal cat = {20, "Tama"};
上記の定義では、構造体変数cat
のメンバ変数age
には20
という整数が、メンバ変数name
には"Tama"
という文字列が保存されます。
この構造体変数cat
を別の構造体変数dog
に代入してみます。
↓がコードです。
#include <stdio.h> struct Animal { int age; char name[40]; }; int main(void) { struct Animal cat = {20, "Tama"}; struct Animal dog = cat; // 代入 printf("cat age[%d] name[%s]\n", cat.age, cat.name); // cat age[20] name[Tama] printf("dog age[%d] name[%s]\n", dog.age, dog.name); // dog age[20] name[Tama] return 0; }
上記のコードをコンパイルして実行すると↓の結果になります。
cat age[20] name[Tama] dog age[20] name[Tama]
コードを見てみます。
まず構造体変数cat
を構造体変数dog
に代入してる部分です。
struct Animal cat = {20, "Tama"}; struct Animal dog = cat;
cat
にはage
に20
, name
に"Tama"
が設定されています。
この構造体変数を同じ構造体の変数、dog
に代入しています。
構造体変数同士の代入では、そのメンバ変数はすべてコピーされます。
int型のage
はコピーされ、char型の配列name
もすべての要素がコピーされます。
char型の配列のコピーでは、文字とナル文字もコピーされるので、コピー先の配列も文字列として機能します。
構造体のメンバ変数が無数にあり、構造体が巨大な場合は代入によるコピーもそれなりにコストがかかります。
ですがほとんどの場合は気にならないコストでしょう。
プログラム中で何度も呼び出す関数で巨大な構造体を代入していたら、もしかしたらボトルネックにはなるかもしれません。
構造体変数のアドレスをポインタ変数に代入する
構造体変数はポインタ変数にすることができます。
たとえば↓が構造体のポインタ変数の定義です。
struct Animal *ptr = NULL;
この構造体のポインタ変数ptr
に構造体変数のアドレスを代入するには↓のようにコードを書きます。
struct Animal cat = {20, "Tama"}; struct Animal *ptr = &cat;
&
は変数のアドレスを取り出す演算子です。
上記のようにするとポインタ変数ptr
に構造体変数cat
のアドレスが代入されます。
#include <stdio.h> struct Animal { int age; char name[40]; }; int main(void) { struct Animal cat = {20, "Tama"}; struct Animal *ptr = &cat; printf("ptr->age[%d] ptr->name[%s]\n", ptr->age, ptr->name); // ptr->age[20] ptr->name[Tama] return 0; }
構造体のポインタ変数からメンバ変数を参照するにはアロー演算子を使います。
ptr->age
やptr->name
のようにメンバ変数を参照します。
ptr
がNULLの場合はプログラムがクラッシュする場合もありますのでその辺は注意が必要です。
構造体変数の配列の要素を代入する
構造体は配列としても定義することができます。
struct Animal { int age; char name[40]; }; int main(void) { // 構造体の配列 struct Animal cats[] = { {20, "Tama"}, // 0番目の要素 {30, "Mike"}, // 1番目の要素 {40, "Bob"}, // 2番目の要素 }; return 0; }
構造体の配列の要素同士は代入することができます。
たとえば↑のcats
の0番目の要素を1番目の要素に代入してみると↓のようなコードになります。
#include <stdio.h> struct Animal { int age; char name[40]; }; int main(void) { // 構造体の配列 struct Animal cats[] = { {20, "Tama"}, // 0番目の要素 {30, "Mike"}, // 1番目の要素 {40, "Bob"}, // 2番目の要素 }; printf("代入前\n"); printf("cats[0] age[%d] name[%s]\n", cats[0].age, cats[0].name); printf("cats[1] age[%d] name[%s]\n", cats[1].age, cats[1].name); // 0番目の要素を1番目の要素に代入 cats[1] = cats[0]; printf("代入後\n"); printf("cats[0] age[%d] name[%s]\n", cats[0].age, cats[0].name); printf("cats[1] age[%d] name[%s]\n", cats[1].age, cats[1].name); return 0; }
↑のコードをコンパイルして実行すると↓の結果になります。
代入前 cats[0] age[20] name[Tama] cats[1] age[30] name[Mike] 代入後 cats[0] age[20] name[Tama] cats[1] age[20] name[Tama]
代入前ではcats[1]
のage
は30
になってます。
これが0番目の要素を1番目の要素に代入するとcats[1]
のage
は20
になります。
これはcats[1]
にcats[0]
のメンバがコピーされたからです。
また配列の要素は普通の構造体変数に代入することも可能です。
struct Animal dog = cats[0]; // 代入
構造体変数を関数の引数に渡す(代入する)
関数の引数にも構造体変数を使うことができます。
たとえば↓のような関数です。
void func(struct Animal dog) { printf("dog age[%d] name[%s]\n", dog.age, dog.name); }
この関数func
は引数にstruct Animal
型の構造体変数を取ります。
(構造体引数とでも言いましょうか)
こういった関数に構造体変数を渡すと構造体変数同士の代入と同じ処理が行われます。
#include <stdio.h> struct Animal { int age; char name[40]; }; void func(struct Animal dog) { printf("dog age[%d] name[%s]\n", dog.age, dog.name); // dog age[20] name[Tama] } int main(void) { struct Animal cat = {20, "Tama"}; func(cat); // dogに代入 return 0; }
↑のコードをコンパイルして実行すると↓の結果になります。
dog age[20] name[Tama]
関数の引数に構造体変数をそのまま渡した場合は、代入と同じような処理になります。
func()
の引数dog
にはcat
のメンバがすべてコピーされます。
おわりに
今回はC言語の構造体の代入について解説しました。
構造体の代入はコピー処理で実現されます。
コピーの特性をよく理解して使うようにしてください。
(^ _ ^) | たくさんコピーするぞ |
(・ v ・) | パソコンは働き者 |