プログラミング言語C – 関数呼び出し
津路です。
引き続き、プログラミング言語C 第2版 ANSI規格準拠 K&R著(共立出版)を読んで、気になるところを書いています。
付録A 参照マニュアルの以下のページを取り上げます。
A7.3.2 関数呼び出し page247
前回に続いて、関数呼び出しの節について
「この後置式(場合によっては、7.1節の暗黙の宣言とポインタ生成の後で)は、」
と記述されていますが、A7.1はポインタ生成ですので、係り受けが違います。
(場合によって、この暗黙の宣言と7.1節のポインタ生成の後で)、が正しいと思います。
続いて、「この後置式は、ある型Tに対して、型”Tを返す関数へのポインタ”でなければならない。」
もう少しわかりやすくしたいと思います。
「この後置き式では、ある型Tに対して、”Tを返す関数へのポインタ”という型でなければならない。」
とそこで、「この関数呼び出しの値は、型Tをもつ。」と続きます。「もつ」でもいいですが、できれば「値の型がTである」
続いて、小さな文字で、第一版とこの第2版の違いについて、記述されています。
「第1版では型は”関数”に限られ、関数へのポインタを介する呼び出しには、明示的な*演算子が必要であった。ANSI標準では、ある種のコンパイラを尊重して、関数への呼び出しとポインタで指定される関数に同じ構文を許している。もちろん古い構文も依然として使用可能である。」
「関数への呼び出しとポインタで指定される関数に同じ構文を許している」の部分の係り受けがおかしいです。
「第1版では、型は”関数”に限られていたので、ポインタを介する関数への呼び出しには、明示的な*演算子が必要であった。しかしANSI標準では、ある種のコンパイラを尊重して、関数への呼び出しとポインタ指定の呼び出しに同じ構文を許している。もちろん、古い構文も依然として使用可能である。」としてみました。
例としては、以下の構文が許されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h> void my_func(int x) { printf( "%d\n", x ); } int main() { void (*foo)(int); foo = &my_func; /* 新しいスタイル */ foo( 2 ); /* 古いスタイル */ (*foo)( 2 ); return 0; } |
続いて、引数とパラメータについて記述されています。
「引数ということばは関数呼び出しで渡される式に対して使われる。一方、パラメータということばは、関数定義によって受け取られる、あるいは関数宣言で記述された入力オブジェクト(あるいはその識別子)を表わす。”実引数(パラメータ)”および”仮引数(パラメータ)”ということばが同じ区別を示すのにそれぞれ使われることもある。」
前半は不明瞭で、後半には誤りがあります。
第一文と第二文は、引数とパラメータを比較しています。原文では、argumentとparameterです。
違いは、以下を見ていただければ、わかると思います。
1 2 3 4 5 6 7 8 | int add(int x, int y) //parameters x,y { return(x + y); } int ret = add(255, 100); //arguments 255, 100 int first=255; int second=100; ret = add(first,second); //arguments values of first,second |
ですので、第三文の、実引数は、ここではargumentsのことです。原文でも間違って、(parameters)と書かれています。
よく、引数だのパラメータだの、混同して使っていたりしますが、日本ではどちらも引数で、実引数と仮引数といって区別しているようです。
ですので、最初の「引数ということばは関数呼び出しで渡される式に対して使われる」という表現は、誤解を生みそうです。