09_構造体3.md
構造体メンバに同じ型へのポインタをもう構造体
- 自己参照的構造体(self-referential structure)
struct data {
char name[32];
int age;
struct data *nextdata;
};
サンプルコード
#include <stdio.h>
#include <stdlib.h>
typedef struct _tagDATA {
char name[32];
int age;
struct _tagDATA *nextdata;
}DATA;
int main(){
DATA a = { "小西", 28 },
b = { "田中", 35 },
c = { "鈴木", 28 };
DATA *lpdata;
a.nextdata = &b;
b.nextdata = &c;
c.nextdata = NULL;
for (lpdata = &a; lpdata; lpdata = lpdata->nextdata){
printf("%s (%d歳)\n", lpdata->name, lpdata->age);
}
system("pause");
return 0;
}
出力結果
小西 (28歳)
田中 (35歳)
鈴木 (28歳)
続行するには何かキーを押してください . . .
解説
a.nextdata = &b;
b.nextdata = &c;
c.nextdata = NULL;
for (lpdata = &a; lpdata; lpdata = lpdata->nextdata){
printf("%s (%d歳)\n", lpdata->name, lpdata->age);
}
- for文に注目!
- 初期化:
DATA
に格納されている最初のアドレス(&a
)
- 継続条件:
lpdata
- 再設定式:
lpdata = lpdata->nextdata
a.nextdata = b
なので、次のDATA型の要素が指定される。
共用体
- 一つの領域を確保して、そこにいろいろなデータ型の
データを格納できる機能を持つ共用体(union)と呼ばれるデータ型がある。
- 記憶できるのは一つのメンバだけであるので注意!
書式
union 共用体タグ{
共用体メンバ;
...
} 共用体変数;
サンプルコード
#include <stdio.h>
#include <stdlib.h>
union myUnion{
int i;
double d;
char c;
char *str;
};
int main(){
union myUnion u;
u.i = 200;
printf("u.i = %d\n", u.i);
u.d = 95.25;
printf("u.d = %f\n", u.d);
u.c = 'A';
printf("u.c = %c\n", u.c);
u.str = "ABCDE";
printf("u.str = %s\n", u.str);
system("pause");
return 0;
}
出力結果
u.i = 200
u.d = 95.250000
u.c = A
u.str = ABCDE
続行するには何かキーを押してください . . .
サンプル2
#define PAN "パン食い競争"
#define RUN "100m 競走"
#define NO 6
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "struct.h"
int myinput(LPDATA, char *, char *, char *);
int main(){
DATA data[NO];
LPDATA lpdata;
int i;
lpdata = data;
myinput(lpdata + 0, "田中", PAN, "1");
myinput(lpdata + 1, "佐藤", RUN, "20.5");
myinput(lpdata + 2, "太田", PAN, "2");
myinput(lpdata + 3, "加藤", PAN, "4");
myinput(lpdata + 4, "筒井", RUN, "15.2");
myinput(lpdata + 5, "鈴木", PAN, "3");
printf("%4s\t%-14s\t%4s\n"
, "氏名", "競技名", "成績");
printf("-------------------------------\n");
for (i = 0; i < NO; i++){
printf("%4s\t%-14s\t", data[i].name, data[i].kind);
if (strcmp(data[i].kind, RUN) == 0){
printf("%4.1f秒\n", data[i].record.time);
}
else{
printf("%4d位\n", data[i].record.time);
}
}
system("pause");
return 0;
}
int myinput(LPDATA lpData, char *name, char *kind, char *record){
strcpy_s(lpData->name, name);
strcpy_s(lpData->kind, kind);
if (!strcmp(kind, PAN)){
lpData->record.rank = atoi(record);
}
else{
lpData->record.time = atof(record);
}
return 0;
}
出力結果
氏名 競技名 成績
-------------------------------
田中 パン食い競争 1位
佐藤 100m 競走 20.5秒
太田 パン食い競争 2位
加藤 パン食い競争 4位
筒井 100m 競走 15.2秒
鈴木 パン食い競争 3位
続行するには何かキーを押してください . . .