アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下のソースをうごかすと「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++;
}
}



どこを直せばうごきますか?教えてください。。

A 回答 (7件)

つまり、同じ *pA という表記でも、


どういう局面で書くかによって
 ・pA という、何か別の変数のアドレスを格納するための箱の定義
 ・pA に入っている、何か別の変数(例えば n)のアドレスを介して、当該変数(例えば n)の値を取得する、という行為
という違いがあります。
    • good
    • 0
この回答へのお礼

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」はアドレスを渡している





「&」と「*」の使いかたが理解不足でした
ありがとうございました!

お礼日時:2008/05/17 08:18

> *pAっていうのはポインタのポインタ??



いいえ、そうではありません。
変数の定義時に
int *pA;
と書けば、「pAは、int型のアドレスを格納する箱」という意味です。

一方、
int *pA;
int n = 123;
pA = &n; // pAは、nのアドレス
と書けば、*pAは、nのアドレスが指している場所の値(つまり、123)です。

この回答への補足

int *pA = pAはint型のアドレスを格納する箱


int *pA; /*int型のアドレスを格納する箱を用意*/
int n = 123; /*int型を格納する箱を用意*/
pA = &n; /*pAにはnのアドレスが格納される*/

結果…
 pAにはnのアドレス値が格納されていて*pAはnのアドレスが咲いている場所の値を指す


ソースを書いてみます。。

補足日時:2008/05/17 07:48
    • good
    • 0
この回答へのお礼

【確認ソース】


#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の値*/
でした!!!

お礼日時:2008/05/17 08:08

> 配列に&をつけることで正常に始動しました



&を付けることは正しいですが、「配列に」付けたわけではありません。
scanf()を使って、stu[i].bangou という変数に格納するから、
stu[i].bangou のアドレスを指定しているのです。

仮に、
int n;
という変数定義があるとして、
scanf()を使って n に値を格納するとき、
scanf("%d", &n);
と書くのと同じことです。

この回答への補足

変数に格納するときにはアドレスを指定する。。。

変数を「箱」とみなして、箱の場所をはっきりさせないといけないんですよね。基本がうやむやでしたっ。

最初のポインタに戻りますが
「ポインタはアドレスを格納する変数」
int a;
int *pA;
a=5;
pA=&a;

*pA と a はイコールで結ばれる


*pAっていうのはポインタのポインタ??
「ポインタに対して*演算子(間接参照演算子)をつけるとそのポインタから逆にたどってもとの変数の値を知ることができる」

少し頭がこんがらがっていますっ。ですがなんとなく変数とアドレス、ポインタが見えてきたような気がします。


ありがとうございました!

補足日時:2008/05/16 23:39
    • good
    • 0

> while( (scanf("%d %d",stu[i].bangou,stu[i].sintyou)!=EOF)&&i<N){



ここに大きな問題があります。
コンパイルエラーにはなりませんが、正しく実行できません。
scanf関数の第2引数以降はポインタであることを再確認してください。

この回答への補足

何度もありがとうございます(泣)

while( (scanf("%d %d",&stu[i].bangou,&stu[i].sintyou)!=EOF)&&i<N){


配列に&をつけることで正常に始動しました

自分なりの理解がまだできていません。。。言葉で説明できるまでもう少し待ってください。。。

補足日時:2008/05/16 23:06
    • good
    • 0
この回答へのお礼

一つだけわかったことがあります

#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]);

お礼日時:2008/05/16 23:28

配列名は、当該配列の先頭要素へのポインタである、


という大原則があります。

で、&stu が Student ** 型であれば、何が Student * 型であるのかは
少し考えればわかるはずです。

ここで答えを書くのは簡単ですが、一度ご自分で
ウンウンうなりながら考えてみてください。

この回答への補足

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

補足日時:2008/05/16 22:34
    • good
    • 0
この回答へのお礼

参考書に「プログラムの中で[ ]がなく単独で現れた配列名はその配列の一番初めの要素アドレスとなります」とあります

ですので「 &stu 」を渡すのではなく「 stu 」のみを渡す、つまり単独で現れた「 stu 」自体がすでにアドレスをあらわしているという理解でいいのでしょうか?


プログラムを指導してみたところ正常に動きました。が・・・。
プリントができませんでした。今度は「 print_dt( ) 」関数の方でミスがあるみたいです。。。

ボロボロでスイマセン。。。

お礼日時:2008/05/16 22:46

> print_dt(&stu);



渡している引数の型が合っていません。
print_dt関数はStudent * 型の引数を期待していますが、
実際に渡しているのはStudent ** 型です。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます

ダブルポインタを渡してしまっているとの事。。。
自分のコードでは「アドレス値を渡さないといけないところを中身の数値を渡してしまっている」ということでしょうか?

渡すものを考えて 「 print_dt(&stu[N+1]) 」にしてみたら動いたのですが正常な数値は得られませんでしたっ


ポインタのところがぜんぜん理解できていないのだと思います。
もう一度 「 print_dt( ) 」に何を渡せばいいのか教えてくださいませんか?

お願いします。。。

お礼日時:2008/05/16 22:27

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

この回答への補足

閲覧ありがとうございます!!

「 21 : Warning: illegal pointer combination (param) 」

という表示です。。。
よろしくお願いします。

補足日時:2008/05/16 21:41
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!