33章 構造体

http://www.geocities.jp/ky_webid/c/033.html

複数のデータ型を一まとめに取り扱うことができるという構造体。

またかなりややこしそうですね。

構造体についての色々な話がざーっと書かれているのでちょっと頭がついていかない感じがします・・・。

  • 構造体変数の宣言時の初期化
  • 構造体同士の代入
  • 構造体のネスト
  • 構造体を関数に受け渡しする

この四つのポイントをしっかり頭に叩き込みましょう。

問題1

次の構造体の各メンバをprintf関数を使って出力して下さい。

struct s1{
    int num;
    double db;
    char *str;
    int array[3];
};

やってみます。

int main () {
    struct s1 {
        int num;
        double db;
        char *str;
        int array[3];
    } data = { 1, 10.5, "foo", {0,1,2} };
    int i;
    
    printf("data.num = %d\n",data.num);
    printf("data.db = %f\n",data.db);
    printf("data.str = %s\n",data.str);
    for(i=0;i<3;++i) {
        printf("data.array[%d] = %d\n",i,data.array[i]);
    }
    return 0;
}
$ main
data.num = 1
data.db = 10.500000
data.str = foo
data.array[0] = 0
data.array[1] = 1
data.array[2] = 2

特別難しい部分もなかったのでさくっとできました。

問題2

2つのint型のメンバを持つ構造体を作ります。その構造体のポインタを引数とする関数を作り、2つのメンバのうち大きい方の値を戻り値として返すようにして下さい。構造体のメンバの値は、キーボードからの入力により受け取ります。

構造体のポインタ渡しの問題ですね。

struct snum {
    int num1;
    int num2;
};

int hikaku (struct snum *s) {
    if ( s->num1 >= s->num2 ) {
        return s->num1;
    }
    return s->num2;
}

int main () {
    struct snum s;
    
    printf("一つ目の整数\n");
    scanf("%d",&s.num1);
    printf("二つ目の整数\n");
    scanf("%d",&s.num2);
    
    printf("大きい数値は %d です",hikaku(&s));
    return 0;
}
$ main
一つ目の整数
10
二つ目の整数
0
大きい数値は 10 です

$ main
一つ目の整数
10
二つ目の整数
10
大きい数値は 10 です

$ main
一つ目の整数
10
二つ目の整数
12
大きい数値は 12 です

うまくいってます。

入力にfgetsを使おうと思ったのですが、よく考えたら整数値として受け取る方法が分からなかったので今回はscanfを使いました。

本来ならここはどうすべきなんでしょうかね。

答え合わせ

あってました。解答例でもscanfを使っていますね。とりあえずはscanfで良さそうです。

問題3

次のような2つの構造体宣言があります。構造体s1の配列を要素数2で作り、適当な値で初期化します。その後、0番目の要素と1番目の要素を交換して表示して下さい。

struct s2 {
    int num;
};

struct s1 {
    int num;
    char *str;
    struct s2 s;
};

ネストされた構造体の問題ですね。頑張ってみます。

struct s2 {
    int num;
};

struct s1 {
    int num;
    char *str;
    struct s2 s;
};

int main () {
    struct s1 s[] = {
        {10,"foo",{100}},
        {20,"bar",{200}},
    };
    struct s1 work;
    int i;
    
    work  = s[0];
    s[0] = s[1];
    s[1] = work;
    
    for(i=0;i<2;++i){
        printf("s[%d] = %d\n",i,s[i].num);
        printf("s[%d] = %s\n",i,s[i].str);
        printf("s[%d] = %d\n",i,s[i].s.num);
    }
    
    return 0;
}
$ main
s[0] = 20
s[0] = bar
s[0] = 200
s[1] = 10
s[1] = foo
s[1] = 100

できました。

値の交換処理はさすがにやり方が同じなので覚えましたよ。

答え合わせ

細かいところを除けばだいたいあってますね。

思ったより簡単でよかったです。

後は応用ですよね。コレばっかりは実装して慣れていくしかないでしょう。