プロトタイプ宣言

プログラミング論
第十八回
・よく使う処理は関数にしよう②
本日の内容

簡単な関数の例
–
–
–
–
–


関数の構成
ローカル変数の宣言
戻り値とreturn文
関数の呼び出し
関数のプロトタイプ宣言
戻り値のない関数
グローバル変数
演習(復習)


実数を四捨五入して整数にする処理を,
関数で実現するプログラムを作成しなさ
い。
ensyu45c.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)。