構造体について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kk

構造体について

#1

投稿記事 by kk » 5年前

構造体について勉強していてプログラムを調べながら作っていたのですが表示が終わった後にコアダンプしてしまいます。
どこがおかしいのか指摘をください。

コード:

#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じゃなくてこうなるのかを教えてください。->の意味がよくわかりません。

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 構造体について

#2

投稿記事 by みけCAT » 5年前

kk さんが書きました:構造体について勉強していてプログラムを調べながら作っていたのですが表示が終わった後にコアダンプしてしまいます。
どこがおかしいのか指摘をください。
1要素分しかメモリを確保していないのに、n要素分(n>1)のデータを書き込んだら、データが破壊され、おそらく未定義の挙動になります。
線形リストを作りたかったのですか?
kk さんが書きました:あとdata2->nameのところなんですけどここがなぜdata2.nameじゃなくてこうなるのかを教えてください。->の意味がよくわかりません。
data2がポインタだからですね。a->bは(*(a))->bとほぼ同じです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

kk

Re: 構造体について

#3

投稿記事 by kk » 5年前

やっぱ入れる分だけ準備しないといけないんですね。
static list data[10];
見たいにはじめに定義しなくていくらでも入れれる方法はないのでしょうか?
あと->が何をしているのかわからないので教えてください。

box
記事: 1746
登録日時: 9年前

Re: 構造体について

#4

投稿記事 by box » 5年前

kk さんが書きました:

コード:

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

コード:

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

kk

Re: 構造体について

#5

投稿記事 by kk » 5年前

ああそういう意味だったんですね。
ありがとうございます。

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: 構造体について

#6

投稿記事 by へろりくしょん » 5年前

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 のポインタ型ですので、このように記述します。

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 構造体について

#7

投稿記事 by みけCAT » 5年前

kk さんが書きました:やっぱ入れる分だけ準備しないといけないんですね。
static list data[10];
見たいにはじめに定義しなくていくらでも入れれる方法はないのでしょうか?
あります。線形リストを利用するのが1つの方法です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る