構造体(こうぞうたい、英: structure)はプログラミング言語におけるデータ型の一つで、1つもしくは複数の値をまとめて格納できる型。それぞれのメンバー(フィールド)は型が異なっていてもよい点が配列と異なる。
フリー百科事典『ウィキペディア(Wikipedia)』
構造体とは複数の変数を一つにまとめたもの。
例えば、ある人間を表すものとして、名前や年齢、性別・・・といった無数の要素が考えられる。
構造体を使うことで、これらを人間の構成要素としてまとめることができる。
構造体のそれぞれの変数を、構造体のメンバという。
#include <stdio.h>
#include <string.h>
struct member {
int id;
char name[256];
int age;
};
int main(void) {
struct member data;
data.id = 1;
strcpy(data.name, "Mike");
data.age = 12;
printf("ID:%d Name:%s Age:%d\n", data.id, data.name, data.age);
return 0;
}
構造体を配列として扱う。
#include <stdio.h>
#include <string.h>
struct member {
int id;
char name[256];
int age;
};
typedef struct member member_data;
int main(void) {
int i;
member_data data[] = {
{1, "Mike", 12},
{2, "John", 13},
{3, "Taro", 14}
};
for (i=0; i<3; i++) {
printf("ID:%d Name:%s Age:%d\n", data[i].id, data[i].name, data[i].age);
}
return 0;
}
ポインタで構造体を扱う。
#include <stdio.h>
#include <string.h>
// struct member {
// int id;
// char name[256];
// int age;
// };
// typedef struct member member_data;
// 以下の表記で上と同じ処理。
typedef struct {
int id;
char name[256];
int age;
} member_data;
void set_data(member_data*, int, char*, int);
void show_data(member_data*);
int main(void) {
member_data data[4];
int id[] = {1, 2, 3};
char name[][256] = {
"Mike",
"John",
"Taro"
};
int age[] = {12, 13, 14};
int i;
for (i=0; i<3; i++) {
set_data(&data[i], id[i], name[i], age[i]);
}
for (i=0; i<3; i++) {
show_data(&data[i]);
}
return 0;
}
void set_data(member_data* data, int id, char* name, int age) {
data->id = id;
strcpy(data->name, name);
data->age = age;
}
void show_data(member_data* data) {
printf("ID:%d Name:%s Age:%d\n", data->id, data->name, data->age);
}
構造体と参照渡し
大量のデータを扱う可能性のある構造体では、メモリ容量の理由で、値渡しではなく、参照渡しを使った方が良い場合が多い。
- 参照渡しでは、スタック領域が圧迫されない。
- 参照渡しでは、データのコピーが起こらない。
#include <stdio.h>
typedef struct {
int id;
double num;
} sample_data;
// 値渡し
void func_call_by_val(sample_data);
// 参照渡し
void func_call_by_ref(sample_data*);
int main(void) {
sample_data s1 = {1, 1.23};
sample_data s2 = {1, 2.34};
printf("ADDRESS_s1:%p\nADDRESS_s2:%p\n", &s1, &s2);
func_call_by_val(s1);
func_call_by_ref(&s2);
printf("s1.id:%d s1.num:%lf\n", s1.id, s1.num);
printf("s2.id:%d s2.num:%lf\n", s2.id, s2.num);
return 0;
}
void func_call_by_val(sample_data data) {
puts("--start call by val");
printf("id:%d num:%lf\n", data.id, data.num);
printf("ADDRESS:%p\n", &data);
data.id = 5;
data.num = 6.78;
puts("--end call by val");
}
void func_call_by_ref(sample_data* pdata) {
puts("--start call by ref");
printf("id:%d num:%lf\n", pdata->id, pdata->num);
printf("ADDRESS:%p\n", pdata);
pdata->id = 5;
pdata->num = 6.78;
puts("--end call by ref");
}