• 締切済み

エラーが出てしまいます

以下のソースをうごかすと「21行目」の「print_dt(&stu);」でエラーが出てしまいます。 エラーコード Warning: illegal pointer combination (param) #include <stdio.h> #define N 20 typedef struct{ int bangou; /*学生番号*/ int sintyou; /*身長*/ }Student; void print_dt(Student *p); int main( ){ Student stu[N+1]; int i = 0; printf("学生番号、身長を入力(終了条件:Ctrl+Z)\n"); while( (scanf("%d %d",stu[i].bangou,stu[i].sintyou)!=EOF)&&i<N){ i++; } stu[i].bangou = 0; /*ストッパー*/ stu[i].sintyou = 0; /*ストッパー*/ print_dt(&stu); return 0; } /*** データ表示処理 ***/ void print_dt(Student *p){ printf("学生番号  身長\n"); while( p->bangou != 0 && p->sintyou != 0 ){ /*ストッパーまでループ*/ printf("%-10d %5d\n",p->bangou, p->sintyou); p++; } } どこを直せばうごきますか?教えてください。。

みんなの回答

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.7

つまり、同じ *pA という表記でも、 どういう局面で書くかによって  ・pA という、何か別の変数のアドレスを格納するための箱の定義  ・pA に入っている、何か別の変数(例えば n)のアドレスを介して、当該変数(例えば n)の値を取得する、という行為 という違いがあります。

xxxcocoxxx
質問者

お礼

void print_dt(Student *p); ここでの「*p」は構造体配列「stu」のアドレスをうけとる while( (scanf("%d %d",&stu[i].bangou,&stu[i].sintyou)!=EOF)&&i<N){ ここでの「&stu[i].bangou」はアドレスに値を格納する print_dt(stu); ここでの「stu」はアドレスを渡している 「&」と「*」の使いかたが理解不足でした ありがとうございました!

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.6

> *pAっていうのはポインタのポインタ?? いいえ、そうではありません。 変数の定義時に int *pA; と書けば、「pAは、int型のアドレスを格納する箱」という意味です。 一方、 int *pA; int n = 123; pA = &n; // pAは、nのアドレス と書けば、*pAは、nのアドレスが指している場所の値(つまり、123)です。

xxxcocoxxx
質問者

お礼

【確認ソース】 #include <stdio.h> main( ){ int *pA; int n = 123; pA = &n; printf("%d \n", pA); printf("%d \n", *pA); return 0; } 以上の結果は   pA = 3912   /*nのアドレス値*/ *pA = 123 /*nの値*/ でした!!!

xxxcocoxxx
質問者

補足

int *pA = pAはint型のアドレスを格納する箱 int *pA; /*int型のアドレスを格納する箱を用意*/ int n = 123; /*int型を格納する箱を用意*/ pA = &n; /*pAにはnのアドレスが格納される*/ 結果…  pAにはnのアドレス値が格納されていて*pAはnのアドレスが咲いている場所の値を指す ソースを書いてみます。。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.5

> 配列に&をつけることで正常に始動しました &を付けることは正しいですが、「配列に」付けたわけではありません。 scanf()を使って、stu[i].bangou という変数に格納するから、 stu[i].bangou のアドレスを指定しているのです。 仮に、 int n; という変数定義があるとして、 scanf()を使って n に値を格納するとき、 scanf("%d", &n); と書くのと同じことです。

xxxcocoxxx
質問者

補足

変数に格納するときにはアドレスを指定する。。。 変数を「箱」とみなして、箱の場所をはっきりさせないといけないんですよね。基本がうやむやでしたっ。 最初のポインタに戻りますが 「ポインタはアドレスを格納する変数」 int a; int *pA; a=5; pA=&a; *pA と a はイコールで結ばれる *pAっていうのはポインタのポインタ?? 「ポインタに対して*演算子(間接参照演算子)をつけるとそのポインタから逆にたどってもとの変数の値を知ることができる」 少し頭がこんがらがっていますっ。ですがなんとなく変数とアドレス、ポインタが見えてきたような気がします。 ありがとうございました!

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

> while( (scanf("%d %d",stu[i].bangou,stu[i].sintyou)!=EOF)&&i<N){ ここに大きな問題があります。 コンパイルエラーにはなりませんが、正しく実行できません。 scanf関数の第2引数以降はポインタであることを再確認してください。

xxxcocoxxx
質問者

お礼

一つだけわかったことがあります #include <stdio.h> int main(void){ int test[5] int i, j; printf("5人の点数を入力してください\n"); for(i=0; i<5 ; i++){ scanf("%d", &test[i]); } for(j=0; j>5; j++)[ pirntf("%d番目の人の点数は%dです\n", j+1, test[j]);

xxxcocoxxx
質問者

補足

何度もありがとうございます(泣) while( (scanf("%d %d",&stu[i].bangou,&stu[i].sintyou)!=EOF)&&i<N){ 配列に&をつけることで正常に始動しました 自分なりの理解がまだできていません。。。言葉で説明できるまでもう少し待ってください。。。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.3

配列名は、当該配列の先頭要素へのポインタである、 という大原則があります。 で、&stu が Student ** 型であれば、何が Student * 型であるのかは 少し考えればわかるはずです。 ここで答えを書くのは簡単ですが、一度ご自分で ウンウンうなりながら考えてみてください。

xxxcocoxxx
質問者

お礼

参考書に「プログラムの中で[ ]がなく単独で現れた配列名はその配列の一番初めの要素アドレスとなります」とあります ですので「 &stu 」を渡すのではなく「 stu 」のみを渡す、つまり単独で現れた「 stu 」自体がすでにアドレスをあらわしているという理解でいいのでしょうか? プログラムを指導してみたところ正常に動きました。が・・・。 プリントができませんでした。今度は「 print_dt( ) 」関数の方でミスがあるみたいです。。。 ボロボロでスイマセン。。。

xxxcocoxxx
質問者

補足

今から「ウ~~~~~ン」とうなりながら考えて見ます!もう少し待っていてください☆

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

> print_dt(&stu); 渡している引数の型が合っていません。 print_dt関数はStudent * 型の引数を期待していますが、 実際に渡しているのはStudent ** 型です。

xxxcocoxxx
質問者

お礼

ご指摘ありがとうございます ダブルポインタを渡してしまっているとの事。。。 自分のコードでは「アドレス値を渡さないといけないところを中身の数値を渡してしまっている」ということでしょうか? 渡すものを考えて 「 print_dt(&stu[N+1]) 」にしてみたら動いたのですが正常な数値は得られませんでしたっ ポインタのところがぜんぜん理解できていないのだと思います。 もう一度 「 print_dt( ) 」に何を渡せばいいのか教えてくださいませんか? お願いします。。。

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.1

ところで どんなエラーが出るの?

xxxcocoxxx
質問者

補足

閲覧ありがとうございます!! 「 21 : Warning: illegal pointer combination (param) 」 という表示です。。。 よろしくお願いします。

関連するQ&A