ページ 11

構造体について

Posted: 2014年8月20日(水) 21:59
by kk
構造体について勉強していてプログラムを調べながら作っていたのですが表示が終わった後にコアダンプしてしまいます。
どこがおかしいのか指摘をください。

コード:

#include <stdio.h>
struct list{
  char name[50];//名前
    int age;//年齢
};
int main(void){
  struct list data;
  struct list *data2;//ポインタ保存用
  data2 = &data;//アドレスセット
  int i,t=0;
  /*入力*/
  while(i){
    printf("名前:");scanf("%s",data2->name);
    printf("年齢:");scanf("%d",&data2->age);
    t++;
    data2++;
    puts("続けるyes:no=1:0");scanf("%d",&i);
  }
  data2 = &data;
  /*出力*/
  puts("list出力______________________");
  for(i=0;i<t;i++){
    printf("名前:%s\n",data2->name);
    printf("年齢:%d\n",data2->age);
    data2++;
  }
  return 0;
}

あとdata2->nameのところなんですけどここがなぜdata2.nameじゃなくてこうなるのかを教えてください。->の意味がよくわかりません。

Re: 構造体について

Posted: 2014年8月20日(水) 22:17
by みけCAT
kk さんが書きました:構造体について勉強していてプログラムを調べながら作っていたのですが表示が終わった後にコアダンプしてしまいます。
どこがおかしいのか指摘をください。
1要素分しかメモリを確保していないのに、n要素分(n>1)のデータを書き込んだら、データが破壊され、おそらく未定義の挙動になります。
線形リストを作りたかったのですか?
kk さんが書きました:あとdata2->nameのところなんですけどここがなぜdata2.nameじゃなくてこうなるのかを教えてください。->の意味がよくわかりません。
data2がポインタだからですね。a->bは(*(a))->bとほぼ同じです。

Re: 構造体について

Posted: 2014年8月20日(水) 22:23
by kk
やっぱ入れる分だけ準備しないといけないんですね。
static list data[10];
見たいにはじめに定義しなくていくらでも入れれる方法はないのでしょうか?
あと->が何をしているのかわからないので教えてください。

Re: 構造体について

Posted: 2014年8月20日(水) 22:25
by box
kk さんが書きました:

コード:

  int i,t=0;
iに何が入っているかわからない状態で
kk さんが書きました:

コード:

  while(i){
ループの制御用に使うのはまずいような気がします。コアダンプの件と関係があるかどうかはわかりませんが…。
kk さんが書きました: あとdata2->nameのところなんですけどここがなぜdata2.nameじゃなくてこうなるのかを教えてください。->の意味がよくわかりません。
->
アロー演算子は、
pが構造体を指すポインターで
メンバーmにアクセスしたいときに
p->m
のように使います。意味は
(*p).m
と同じです。

Re: 構造体について

Posted: 2014年8月20日(水) 22:28
by kk
ああそういう意味だったんですね。
ありがとうございます。

Re: 構造体について

Posted: 2014年8月20日(水) 22:34
by へろりくしょん
kk さんが書きました:どこがおかしいのか指摘をください。
アルゴリズムの意図をくみ取るならば、19行目です。

まず7行目で、struct list を 1つ data という名前で宣言・定義しています。
9行目で、data2 には data のアドレスを代入しています。
19行目で、data2 は data の次のアドレスを計算しています。

しかし、data は struct list を1つだけしか持っていませんので
次なんてありません。

次なんてありませんので、data の次のアドレスにアクセスした時点で未定義です。


提示されたコードを忠実に読み取るならば、12行目です。

変数 i は、10行目で宣言されていますが、この時点では初期化されていません。
続く12行目で変数 i が読まれていますが、未だ未初期化の為、変数 i の値は不定です。
従って、while(i) が実行された時点で、鼻から悪魔が飛び出します。

kk さんが書きました:あとdata2->nameのところなんですけどここがなぜdata2.nameじゃなくてこうなるのかを教えてください。->の意味がよくわかりません。
struct list hoge;
struct list *foo = &hoge;  //hoge のアドレスを foo にセット

とした場合、変数 foo の値は、変数 hoge のアドレスだというのは分かると思います。
変数 hoge の値は、構造体の中身そのものですので、hoge.name あるいは hoge.age とすることで、直接中身にアクセスが可能ですが、
変数 foo の値は、アドレスですのでワンクッション必要です。 このため、関節演算子 * を使い、(*foo).name あるいは (*foo).age とする必要があります。

ですが、機械のくせに人間様にいちいちそのような手間を取らせるのは業腹物ですので、簡易的な記法が特別に用意されています。
それが、-> です。

変数 data2 の型は、struct list のポインタ型ですので、このように記述します。

Re: 構造体について

Posted: 2014年8月20日(水) 23:35
by みけCAT
kk さんが書きました:やっぱ入れる分だけ準備しないといけないんですね。
static list data[10];
見たいにはじめに定義しなくていくらでも入れれる方法はないのでしょうか?
あります。線形リストを利用するのが1つの方法です。