プログラミング論 第十六回 よく使う処理は関数にしよう 本日の内容 簡単な関数の例 – – – – – 関数の構成 ローカル変数の宣言 戻り値とreturn文 関数の呼び出し 関数のプロトタイプ宣言 戻り値のない関数 グローバル変数 簡単な関数の例 では,関数を作ってみよう! 数学における関数を思い出しましょう。 関数 f に x を与えたときの結果を y に代入する これは,こう書きましたね。 y f (x) 実際に,関数 f が x をもらってどういう計算をしているかは,・・ f ( x) x 3x 2 2 と定義しましたね。 簡単な関数の例 では,関数を作ってみよう! プログラミング言語の場合も同じです。 f ( x) x 2 3x 2 y f (3) と関数を宣言して, のように利用します。 関数の宣言は,main関数の外で行います。 関数は,main関数など他の関数の中で利用されます。 自分自身の中で呼び出すこともできます(再帰処理) 簡単な関数の例 では,関数を作ってみよう! #include <stdio.h> double f( double x) { double y; int main(void) { double x,y; printf("x=?"); scanf("%lf", &x); y = x*x+3*x+2; y = f(x); return y; } printf("y=%f\n",y); } ここが関数の宣言部です 簡単な関数の例 では,関数を作ってみよう! #include <stdio.h> double f( double x) { 引数 double y; ローカル変数 y = x*x+3*x+2; return y; } 関数の処理は,{ }で囲んで 表します。 プログラム内では,変数は型 指定されなければなりません。 関数が呼び出されたところか ら受け取るデータを引数とい います。 関数の答えが何型になるの か,の指定も行います。 計算した後,関数の答えとし て出力する変数の値はreturn 文で返します。 関数の中で宣言される変数を ローカル変数と言います。関 数の中だけで有効です。 簡単な関数の例 では,関数を作ってみよう! 必ず,main関数から実行されます #include <stdio.h> int main(void) { double f( double x) 引数の値が double x,y; 渡されます。 { 両方ともロー カル変数の double y; printf("x=?"); ため,変数名 scanf("%lf", &x); は同じですが y = x*x+3*x+2; まったく別の 変数です。 渡された引数を元に y = f(x); 関数が呼び 処理を行います。 出されます return y; } printf("y=%f\n",y); 処理結果のyが関数の結果 として呼び出し元に返されます。 } 結果が画面に表示されます。 演習 ensyu44.cを完成させ,結果を確認しなさい。 引数として,直接数値を指定しても良いことを 確認しなさい。 ローカル変数名(引数と関数の結果の変数名) は,main関数と関数fとで異なっていても問題な いことを確認しなさい。 最後のprintfにて,変数yの値を出力する代わ りに,直接printf内にて関数fの呼び出しを行っ ても結果が出力されることを確認しなさい。 演習 実数を四捨五入して整数にする処理を, 関数で実現するプログラムを作成しなさ い。 ensyu45.cを完成させなさい。 プロトタイプ宣言 ensyu46.cは,ensyu44.cを改訂したもの です。 main関数を最初に配置し,後ろに関数f を配置しています。 コンパイルするとどうなるでしょうか? プロトタイプ宣言 こんなエラーが出ます。 警告 W8065 ensyu46.c 12: プロトタイプ宣言のない 関数 'f' の呼び出し(関数 main ) エラー E2356 ensyu46.c 20: 'f' の再宣言で型が一致していない では,一つずつ考えていきましょう。 プロトタイプ宣言 警告 W8065 ensyu46.c 12: プロトタイプ宣言のない 関数 'f' の呼び出し(関数 main ) #include <stdio.h> int main(void) { double x, y; printf("x="); scanf("%lf",&x); y = f(x); printf("y=%f\n",y); } double f(double x) { double y; y = x*x+3*x+2; return y; } ここの段階でこのメッセージ が出力されます。 ここでいきなり初めて関数fと いうのが出てきた。 こんなものは聞いたことがない から勝手に解釈して先に進み ます。 プロトタイプ宣言 エラー E2356 ensyu46.c 20: 'f' の再宣言で型が一致していない #include <stdio.h> int main(void) { double x, y; printf("x="); scanf("%lf",&x); y = f(x); printf("y=%f\n",y); } double f(double x) { double y; y = x*x+3*x+2; return y; } ここの段階でこのメッセージ が出力されます。 さっき初めて見たからこっちで 勝手に解釈していたのに, こんなところで教えてくれたって もう遅い! プロトタイプ宣言 というわけで,初めて作って利用する関数は, 「呼び出す関数の前に宣言をすませておかな いと,コンパイル時に解釈できなくてエラーが出 る」ということになります。 プリプロセッサの位置に,「これからこういう関 数を使いますよ」という関数の形の宣言をしま す。これを「プロトタイプ宣言」といいます。 関数名,引数の数・型,返り値(関数の結果)の 型を宣言します。 ensyu47.cでプロトタイプ宣言の方法を確認し て下さい。 プロトタイプ宣言 #include <stdio.h> double f(double); int main(void) { double x, y; printf("x="); scanf("%lf",&x); y = f(x); printf("y=%f\n",y); } double f(double x) { double y; y = x*x+3*x+2; return y; } プロトタイプ宣言 double f(double); 引数の型と数 関数名 関数の結果(返り値)の型 printfやscanfは,標準ライブラリ 関数と言われ,stdio.hの中に記載 してあるため,エラーとならない。 返り値のない関数 返り値がない関数の場合は,関数宣言時の返 り値の型はvoidで宣言をします (ensyu48.c) #include <stdio.h> void putd(int); int main(void) { int dt=100; putd(dt); return 0; } void putd(int a) { printf("%d\n",a); } 関数の型宣言 はvoid型となる 関数が値を返さない =return文がない 演習:よく間違う例 ensyu49.cは,変数xと変数yの値を交換 するプログラムとして作ってみたものです。 実行して,変数値が交換できることを確 認しなさい。 ensyu50.cは,交換の機能をswapという 関数で実現しようとしたものです。しかし, これでは変数値が交換されません。この 理由を考えなさい。 グローバル変数 関数内で宣言された変数はローカル変数と呼 ばれ,その関数内でのみ有効です。 同じ名前の変数があったとしても,異なる関数 内で宣言されていれば,「違う家に住んでいる 同姓同名の人」という扱いになり,まったく別の 変数,と言うことになります。 ただし,関数の外,プリプロセッサの位置で宣 言された変数は「グローバル変数」と呼ばれ, どの関数からでも共通して利用できる変数にな ります。 ensyu51.cで確認しましょう。 グローバル変数 #include <stdio.h> double r; グローバル変数 double pi=3.141592; double menseki(void); double ensyu(void); この値を共通 int main(void) に利用できる { double c, s; printf("r="); scanf("%lf",&r); c=ensyu(); s=menseki(); printf("ensyu=%f, menseki=%f\n",c,s); return 0; } double ensyu(void) { return 2*r*pi; } double menseki(void) { return r*r*pi; } 共通に利用できる 演習 int型引数一つを受け取り,その数値の階 乗を計算する関数int kaijo(int n)を完成 させなさい(ensyu52.c)。 グローバル変数を用いることによりデータ 交換を可能にした関数void swap(void) を完成させなさい(ensyu53.c)。
© Copyright 2025 ExpyDoc