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

第2種情報処理技術者試験 平成7年春 午後 問7
http://www.bohyoh.com/ITEE/C/1995A07.html


中盤の
「while (fgets( (char*)&rbuf , sizeof(ADR), fp )!= NULL ) 」
が読めません

(char*)&rbuf , sizeof(ADR), fp
ファイルポインタからsizeof(ADR)サイズの分だけ取り出した文字を変数(char*)&rbufにほおりこむ

これが自分なりの解釈です
ですが「(char*)&rbuf」が意味不明。。。


根本的に解釈が間違っているのだと思います


詳しくわかる方教えてください

A 回答 (3件)

rbufはADR型の構造体です。



&rbufは、ADR型の構造体rbufの実体へのポインタです。

つまり「&rbuf」は「(ADR *)&rbuf」です。

fgetsの引数は「char *」「size_t」「FILE *」ですから
fgets(&rbuf,sizeof(ADR),fp)
と書くと「char *」であるべき引数に「ADR *」を渡す事になります。

すると、コンパイラは「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」って言って、エラーになります。

なので「&rbufはADR *じゃなくて、char *だと思ってくれ」と書く必要があります。それが「(char *)&rbuf」と言う書き方です。

これを「型キャスト」と言います。

以下の例を参考に、考えてみて下さい。

typedef struct {
  (略)
} ADR;
(略)
  union PTR {
    char *char_ptr;
    ADR *adr_ptr;
  } ptr;
  ADR rbuf;
(略)
  ptr.adr_ptr = &rbuf;
(略)
  fgets(ptr.char_ptr,sizeof(ADR),fp);

この例は、ADR *とchar *を共有する共用体「ptr」を使用し「rbufのポインタ」を「ADR *型のadr_ptr」で受け取り、そのポインタを「char *型のchar_ptr」で参照しています。

つまり「型キャストを使用しないで書くと、上記のように共用体を使うなど、面倒な事をしなきゃなんない」のです。

これが、型キャストを使えば、
typedef struct {
  (略)
} ADR;
(略)
  ADR rbuf;
  fgets((char *)&rbuf,sizeof(ADR),fp);
だけで済んじゃうのです。
    • good
    • 0
この回答へのお礼

「型キャスト」だったんですね!
キャストという言葉自体頭から抜けていました。。。論外ですねっ。

「なにしてんねん。fgetsの1番目の引数はchar *やねんで。ADR *を渡されても困るねん」
この説明が一番わかりやすかった!!!


ありがとうございます♪

お礼日時:2008/02/19 05:18

C言語の場合、ある型へのポインタ型から別の型へのポインタ型へは暗黙的に型変換されます。

したがって、「(char*)&rbuf」のキャスト演算子がなくても意味は変わりません。(警告になることはあっても)エラーになることもありません。

ただ、異なるポインタへの暗黙的な型変換は、多くの場合バグにつながります。そのため、本当に型変換したい場合は明示的にキャスト演算を行っているのです。また、C++ではこのような異なるポインタ型間の暗黙的な型変換は禁止されているので、それにならって明示的なキャストを行うことが多いのです。
    • good
    • 0
この回答へのお礼

そうなんです。
暗黙的了解で省略されているものが多すぎて参考書によって書き方が違ってくる。そこで混乱を自分の中で招いています。

常に省略なしで書くよう心がけていこうと思います

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

お礼日時:2008/02/19 05:24

因みにfgetsは


「1番目の引数のポインタで示したメモリ領域に、2番目の引数で指定したバイト数だけ、3番目の引数のファイルポインタで示したファイルから読み出したデータを格納し、失敗した場合はNULLを返す」
と言う動作をします。

つまり
「jusho.txtファイルからADR構造体の大きさだけ読み込んで、構造体rbufに格納する。失敗した場合はファイルの最後まで読んだんだから、もう止める」
と言う事。
    • good
    • 0
この回答へのお礼

「取り出した文字」=「構造体の大きさ」なんですね!

感謝です☆

お礼日時:2008/02/19 05:20

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