• ベストアンサー

プロトタイプ宣言の説明

プロトタイプ宣言でkansu(int a, int b[][3], *p,*q)と表現したときこれを説明してほしいのですが、どう説明したらいいでしょうか。できるだけ詳しく解説してほしいのですが、よろしくお願いいたします。 あとdouble型でscanfを使うときは%lfを使うのに対しprintf関数で使うときは%fと教科書に表現されていたのですが、%lfにしてはいけないのでしょうか。

質問者が選んだベストアンサー

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

> kansu(int a, int b[][3], *p,*q) kansuu関数の戻り値の型と、第3・第4引数の型が不明なため、 うまく説明できません。 > %lfにしてはいけないのでしょうか。 してもいい処理系としてはいけない処理系の両方があるかもしれません。複数の処理系が使えるようでしたら、試してみてはいかがでしょうか。 そして、どちらにも対応できるためにはどうすればよいかを考えてみてください。

その他の回答 (5)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.6

前者の質問は置いといて、後者の質問だけに回答します。 これには明確な理由があります。 まず、printf、scanfの引数は、原理的に、どの型の引数が 与えられるかわかりません。これを、「関数原型を含まない」と言います。 そして、C言語規格(X 3010)の§6.3.2.2にこういう記述があります。 「関数を表す式が、関数原型を含まない型をもつ場合、各実引数に対して 汎整数拡張を行い、型floatをもつ実引数は型doubleに拡張する。 この操作を『規定の実引数拡張』と呼ぶ」 「汎整数拡張」という概念も覚えておくべきですが(検索してね)、 ここでは、「型floatをもつ実引数は型doubleに拡張する。」 というところが重要です。 さて、scanfの引数は、一般にポインタ型です。 ということは、「float * 型」は持っていても、 「float型」の実引数はありません。だから、上記の規定は適用される 場面がありません。 これに対して、printfの引数は、floatだったり、doubleだったりします。 つまり、printfの引数がfloatだったとき、上記の規定が働いて、 「float→double」 という型変換が、(頼まないのに)自動的に行われるのです。 余計な処理のように思いますが、 CPUによっては(特に多く使われているx86系にとっては)、 floatよりもdouble型のデータを扱う方が自然なので、こうなっています。 つまり、printf関数にfloat型を与えてもdouble型を与えても 「規定の実引数拡張」により、実際に評価される段階では同じになります。 「型として同じ」なので、doubleだけ%lfとすることに意味がありません。 なので、どちらも%fという決まりになっています。 これに対して、scanfの方は、「float * の型」と「double * の型」 に対して違った扱いをする必要があります。なにしろ、 メモリ上のバイト数が違う(場合がある)ので。 このため%fと%lfを分けています。これは必要な処理です。 なお、これに対して疑問に思うのは当然だと思います。 「同じなのは迷信」と言う方もいらっしゃいますが、 「規定の実引数拡張」という概念は、学習者が自分で思いつくほど自然な概念ではありません。 (これについても検索してください)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

printfの書式に%lfを使えるのはC99に対応した処理系と、独自拡張で%lfをサポートする処理系だけです。他の処理系では未定義の動作を引き起こします。もちろん、C++でも、標準規格の範囲では%lfは使えません。

参考URL:
http://www.kijineko.co.jp/tech/superstitions/printf-format-for-double.html
  • sorokuku
  • ベストアンサー率25% (1/4)
回答No.4

まずはprintfでの %lf と %f は同じ意味になります.同じなので教科書では文字数の短い%fを使ったのでしょうか. また,少数の桁数は %0.5f とかで変えることも可能です.この例では少数点以下5桁になります. kansu関数については,何を説明すればよいのか分からないのですが,引数について解説します. ポイントとなるのはやはり int b[][3] だと思います. 1次元の配列の場合 p[] と書いても *p と書いても違いがありません. しかし,2次元の配列の場合は **b と書くとコンパイルエラーが起こるります. 以下に例を示します. #include <stdio.h> void f (int a[][3]){ for (int i = 0 ; i < 10 ; i++) for (int j = 0 ; j < 3 ; j++) printf ("%d\n" , a[i][j]); } int main (){ int a[10][3] ={0}; f (a); return 0; } 2次元の配列を関数に渡す場合,3という情報が重要になるわけです.

  • pick52
  • ベストアンサー率35% (166/466)
回答No.3

> 教科書に表現されていたのですが、 教科書にそのように書いてあったのなら、なぜなのかも教科書に書いて ありませんでしたか。

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

> %lfにしてはいけないのでしょうか。 そもそも、ティーチャーにクエスチョンしてみたのでしょうか。

関連するQ&A