auの日記

プログラミング初心者の日記。(auはハンドルネームです)

C言語でstruct関数②

auです。
前回はstruct関数の宣言の仕方を勉強しました。
program-shoshinsya.hatenablog.com

今回は実際に使ってみたいと思います。

struct関数を実際に使う

前回使った構造体名"student"にそれぞれ値を入れていきたいと思います。

#include<stdio.h>

struct student {
    int id;
    char name[30];
    int age;
    char address[30];
};

int main(void) {
    struct student student1 = {1, "Sato", 20, "Tokyo"};
    printf("id: %d\nname: %s\nage: %d\naddress: %s\n", student1.id, student1.name, student1.age, student1.address);
    return 0;
}

// 実行結果
id: 1
name: Sato                               $
age: 20
address: Tokyo

"id"、"name"、"age"、"address"のそれぞれに値を代入できました。
構造体の"student"を使うには、使いたい関数の中(今回はmain文)で

struct 構造体名 変数名 = {データ1, データ2, ...};

と入力します。データには上から順番に値が入ります。つまり、構造体名"student"の変数名"student1"にid = 1、name = Sato、age = 20、address = Tokyo と代入しているのが分かると思います。

ダメな書き方

#include<stdio.h>

struct student {
    int id;
    char name[];
    int age;
    char address[];
};

int main(void) {
    struct student student1 = {1, "Sato", 20, "Tokyo"};
    printf("id: %d\nname: %s\nage: %d\naddress: %s\n", student1.id, student1.name, student1.age, student1.address);
    return 0;
}

// 実行結果
stract.c:5:10: error: flexible array member not at end of struct
     char name[];
          ^stract.c: In function ‘main’:
stract.c:11:47: error: non-static initialization of a flexible array member
     struct student student1 = {1, "Sato", 20, "Tokyo"};
                                               ^
stract.c:11:47: note: (near initialization for ‘student1’)

char型メンバのnameの"[30]"の部分を除くとエラーがでました。
これは、nameをいれる枠をうまく確保できていなくてでていると思われます。
"Sato"は4文字であるため4バイトですが、終端文字を含めたら5バイトになるため、5以上にすればエラーはでなくなります。

#include<stdio.h>

struct student {
    int id;
    char name[5];
    int age;
    char address[6];
};

int main(void) {
    struct student student1 = {1, "Sato", 20, "Tokyo"};
    printf("id: %d\nname: %s\nage: %d\naddress: %s\n", student1.id, student1.name, student1.age, student1.address);
    return 0;
}

// 実行結果
id: 1
name: Sato
age: 20
address: Tokyo

エラーがおきることなく実行することができました。"char name[4]"と入力してもエラーは起きませんが、終端文字(NULL値)を考えると[5]でなければいけません。
ちなみにchar name[1];とした場合

#include<stdio.h>

struct student {
    int id;
    char name[1];
    int age;
    char address[6];
};

int main(void) {
    struct student student1 = {1, "Sato", 20, "Tokyo"};
    printf("id: %d\nname: %s\nage: %d\naddress: %s\n", student1.id, student1.name, student1.age, student1.address);
    return 0;
}

// 実行結果
/* gccコンパイル時 */
stract.c: In function ‘main’:
stract.c:11:35: warning: initializer-string for array of chars is too long
     struct student student1 = {1, "Sato", 20, "Tokyo"};
                                   ^
stract.c:11:35: note: (near initialization for ‘student1.name’)

/* ./a.out時 */
id: 1
name: S
age: 20
address: Tokyo

見てわかる通り、nameは"Sato"の最初の"S"のみ取り出され、表記されています。