電子書籍の厳選無料作品が豊富!

C言語の会員名簿処理問題の課題をしています。

次の条件でC言語で会員番号を入力するとその会員番号を持つ会員名を表示する
プログラミングを組んでいますが、コンパイルに失敗してしまいます。
何度も見直して修正を施してみたのですが、うまくいきません。
是非お力添えをお願いします。

<条件>
(1)会員番号と会員名は構造型でグローバル変数として宣言する。

(2)データ件数は10件とする。

(3)サブ関数で線形探索するプログラムを組み(my_search関数とする)、メイン関数で呼び出す。

(4)my_search関数の型はchar*とする。

(5)探索に成功したらmy_search関数の戻り値は該当会員の氏名とする。

(6)探索に失敗したらmy_search関数の戻り値はNULLとする。

(7)main関数では,関数my_searchの戻り値がNULLなら該当データがないことを
伝えるメッセージを出力して終了させる.
そうでなければ,該当の氏名を出力して終了させる.


下に組んだプログラムとコンパイル結果を貼り付けます。

/*
z:\情報システム論_2013>cl js010703_a106906.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

js010703_a106906.c
js010703_a106906.c(48) : warning C4047: '==' : 間接参照のレベルが 'int' と 'void
*' で異なっています。
js010703_a106906.c(58) : error C2040: 'my_search' : 'char *(int)' は 'int ()' と
間接操作のレベルが異なります。

z:\情報システム論_2013>
*/

#include <stdio.h>

#defineN10
#defineMAX20

struct Mystruct{
intnumber;
charname[MAX];
};

struct Mystruct meibo[N] = {
{10, "asaoka"},
{20, "ito"},
{23, "kawano"},
{25, "shimizu"},
{31, "setoguchi"},
{34, "tomiyama"},
{37, "murakami"},
{38, "yasuda"},
{46, "yoshino"},
{49, "yoshikawa"}
};

int main()
{
intx;
charp;

printf("会員番号を入力してください。\n");
printf("会員番号:");
scanf("%d", &x);
printf("入力された会員番号の会員は");

p = my_search(x);

if(p==NULL){
printf("存在しません。");
}else{
printf("%s", p);
}

return0;
}

char * my_search(int a)
{
intj = 0;

while(j<N){
if(a==meibo[j].number){
returnmeibo[j].name;
break;
}else{
++j;
}
returnNULL;
}
}


どうしても、この2つのエラーが消えません。
修正点を詳しく教えていただけないでしょうか。
よろしくお願いします。

A 回答 (4件)

C言語の大原則は「使う前に宣言/定義」です。


他の言語だと、この順番でも問題無い場合がありますが、C言語の場合は
> p = my_search(x);
ここで使うものを、この後で
> char * my_search(int a)
と宣言/定義してはいけません。

この場合、 int my_search() (引数任意、戻り値intの関数my_search) が宣言されているとして、コンパイルが進みます。
その結果、実際の char * my_search(int a) とは引数や戻り値違う、ということになり、エラーになります。
それが
「js010703_a106906.c(58) : error C2040: 'my_search' : 'char *(int)' は 'int ()' と間接操作のレベルが異なります。」
のメッセージの意味です。
明示的に宣言しようとしている 'char *(int)' と 暗黙に宣言された 'int ()' が違う、と言っているのです。

修正方法は2とおり。
・定義自体を使う前(この場合、main関数の前)に記述する。
・使う前のプロトタイプ宣言で引数と戻り値を明示しておく。

プロトタイプ宣言については、参考書等で調べてください。
「おまじない」と言われる #include <stdio.h> の役割りの一つが、「プロトタイプ宣言を他のファイルから読みこんで、定義済みの関数を正しく使えるようにする」というものです。


> js010703_a106906.c(48) : warning C4047: '==' : 間接参照のレベルが 'int' と 'void*' で異なっています。

こちらは正確には「警告(warning)」です。
「間違い」ではありません。コンパイルも終了します。
内容を理解し、問題無い場合は無視してもかまいません。
ただし、警告が出る箇所は、問題がある場所がほとんどです。警告を出さないプログラムを目指しましょう。

この場合も == の左右で型が違う、と言っています。
p と NULL です。
char 型は、演算するとき intに自動で変換されます。そのため、 片方が int になっています。
NULLはポインタです。汎用のポインタとして void*型になっていることがあります。
整数とポインタは通常比較したりしません。
よって「間違い」の可能性が高いです。

その前を見ると
p = my_search(x);
です。今は警告は出ませんが、上の関数宣言を修正すると、こんどはここで警告になるはずです。
p と my_searchの戻り値の型を考えれば、どこが間違いかわかるのでは。
    • good
    • 0
この回答へのお礼

詳しい説明ありがとうございました。
成功しました!!

お礼日時:2013/11/21 12:57

>char p;


>p = my_search(x);
>char * my_search(int a)

pの型が本当にcharでいいのか?
という点に尽きます。
    • good
    • 0
この回答へのお礼

ありがとうございました。
pの型も間違えていましたね。
参考になりました。

お礼日時:2013/11/21 13:00

以下のようにしてください。


-------------------


struct Mystruct{
int number;
char name[MAX];
};
char * my_search(int a);    ・・・ここにこの行を追加



int main()
{
int x;
char *p; ・・・この行を修正。(pを *pに修正)
-----------------------------------------------
    • good
    • 0
この回答へのお礼

わかりやすい回答ありがとうございました。
無事成功しました。

お礼日時:2013/11/21 13:01

関数は使う前に宣言すべし.

    • good
    • 0
この回答へのお礼

そうですね。
C言語の大原則を忘れていました。
ありがとうございました。

お礼日時:2013/11/21 13:03

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