構造体の初期化、代入、アロー演算子、構造体配列の理解度を確認しましょう。
struct Point { int x; int y; }; struct Point p = {3, 7}; printf("(%d, %d)\n", p.x, p.y);
struct Point a = {1, 2}; struct Point b; b = a; b.x = 10; printf("a.x=%d, b.x=%d\n", a.x, b.x);
struct Point p = {5, 8}; struct Point *ptr = &p; printf("%d\n", ptr->y);
ptr->y は (*ptr).y と同じ。ポインタ経由でメンバにアクセスする際はアロー演算子を使います。p.y = 8。struct Student { char name[20]; int score; }; struct Student s[3] = { {"Taro", 80}, {"Hanako", 95}, {"Jiro", 70} }; int max = 0; for (int i = 0; i < 3; i++) { if (s[i].score > s[max].score) max = i; } printf("%s\n", s[max].name);
typedef struct { int x; int y; } Point; Point p = {3, 4}; printf("%d\n", p.x + p.y);
typedef struct { ... } Point; は構造体に Point という別名を付けます。
struct ... と書かずに Point p; だけで宣言できるstruct Point { int x; int y; }; struct Line { struct Point start; struct Point end; }; struct Line l = {{0, 0}, {3, 4}}; printf("%d\n", l.end.x);
{3, 4}(Point 構造体)// 一般的な64bit環境(int=4, char=1, アラインメント4) struct S { char c; int i; }; printf("%lu\n", sizeof(struct S));
struct Point { int x; int y; }; void reset(struct Point p) { p.x = 0; p.y = 0; } int main(void) { struct Point pt = {5, 10}; reset(pt); printf("%d %d\n", pt.x, pt.y); return 0; }
void reset(struct Point *p))にして p->x = 0; のようにします。構造体が大きい場合、コピーのコストを避けるためにもポインタ渡しが有効です。
struct Point { int x; int y; int z; }; struct Point p = {5}; printf("%d %d %d\n", p.x, p.y, p.z);
struct Point p = {0}; と書くと全メンバを 0 で初期化できます。指定子付き初期化(C99)では {.x = 5} と特定メンバだけ指定することもできます。