第5回(10月26日)

Download Report

Transcript 第5回(10月26日)

プログラミングⅡ
第5回
http://www.fit.ac.jp/~matsuki/lecture.html
今日の内容
• 前回の課題説明
• 関数
– 関数の概要
– 関数の定義
– 関数の呼び出し
– 変数のスコープ
– 引数の受け渡し
関数の概要
関数の概要
• 預金をATMから引き出すときにすべきこと
(1)通帳をATMに入れる。
(2)暗証番号を入力する。
(3)金額を指定する。
(4)お金を受け取る。
(5)お金と通帳を確認する。
• 複雑なコードを、何度も行うことは面倒。
• 一連の処理を、まとめて記述する
⇒ 関数(function)という機能がある。
関数の概要
• これまで使った関数
– main関数・printf関数・scanf関数
⇒ C言語は関数で構成されている
• 関数とは,「一連の処理の集まり」
• プログラマが,独自の関数を作ることができる
関数の概要
• C言語で関数を利用するためには、次の手順
が必要。
(1) 関数を作成する(関数を定義する)
(2) 関数を利用する(関数を呼び出す)
関数の定義
戻り値の型 関数名(引数)
関数名には、
{
識別子を使う
文1;
文2;
処理をまとめえておく
文3;
・・・
return 式;
}
関数の定義
/* buy関数の定義 */
void buy(void)
関数名
{
printf(“車を買いました。\n”);
}
処理をまとめえておく
voidとは、特定の型を持たないという意味
関数の概要
• C言語で関数を利用するためには、次の手順
が必要。
(1) 関数を作成する(関数を定義する)
(2) 関数を利用する(関数を呼び出す)
関数の呼び出し
• 定義した関数を利用することを、
「関数の呼び出し」という。
関数を呼び出すには、関数名を記述する。
関数名(引数リスト);
buy();
#include <stdio.h>
/*buy関数の定義 */
void buy(void)
{
printf(“車を買いました\n”);
}
buy()関数の
処理内容
/*main関数(buy関数の呼び出し)*/
main()
buy()関数の処理が実行される
{
buy();
}
実行画面
車を買いました
実行の流れ
• C言語は、「main関数」から処理が始まる。
#include <stdio.h>
/*buy関数の定義 */
void buy(void)
{
printf(“車を買いました\n”);
}
①
/*main関数(buy関数の呼び出し)*/
main()
{
buy();
}
①関数を呼び出す
②関数内部の処理実行
③呼び出し元に処理が戻る
②
③
関数の呼び出し
• 定義した関数は、何度でも呼び出すことがで
きる
buy();
buy();
buy();
buy();
buy();
5回buy()関数が呼び出される
#include <stdio.h>
/*buy関数の定義 */
void buy(void)
{
printf(“車を買いました\n”);
}
実行画面
車を買いました
もう一台車を購入します
車を買いました
/*main関数(buy関数の呼び出し)*/
main()
buy()関数を呼び出し
{
buy();
printf(“もう一台車を購入します\n”);
buy();
もう一度、buy()関数を呼び出し
}
#include <stdio.h>
/*buy関数の定義 */
void buy(void)
{
printf(“車を買いました\n”);
}
②
⑥
/*main関数(buy関数の呼び出し)*/
main()
③
① {
buy();
printf(“もう一台車を購入します\n”); ④
⑤
⑦
buy();
}
#include <stdio.h>
/*main関数(buy関数の呼び出し)*/
main()
{
printf(“車を買いました\n”);
printf(“もう一台車を購入します\n”);
printf(“車を買いました\n”);
}
関数を使うほど面倒な処理ではない
/*buy関数の定義*/
複雑な処理もまとめられる
void buy(void)
{
printf(“通帳をATMに入れます\n”);
printf(“暗証番号を入力します\n”);
printf(“金額を指定します\n”);
printf(“お金を受け取ります\n”);
printf(“お金と通帳を確認します\n”);
printf(“車を買いました\n”);
}
buy();
この短い呼び出しで、上記の複雑
な処理を行うことが可能!
引数
引数を使って情報を「渡す」
• 呼び出し元から関数内に情報(値)を渡し、
その値に応じて、処理を行う。
• 関数に渡す値のことを、「引数」という
値段の情報を利
用した処理
値(値段)を一緒
に渡す
呼び出し
main関数
「車を買いました」と
表示
buy関数
呼び出し元に
戻る
20
x
/*buy関数の定義*/
void buy(int x)
int型の引数を用意
{
printf(“%d万円の車を買いました\n”, x );
}
引数を関数内で使う
20
#include <stdio.h>
実行画面
20万円の車を買いました
50万円の車を買いました
/*buy関数の定義 */
void buy( int x )
{
printf(“%d万円の車を買いました\n”, x );
}
仮引数
/*main関数(buy関数の呼び出し)*/
main()
実引数として20を渡して呼び出し
{
buy( 20 );
buy( 50 );
}
実引数として50を渡して呼び出し
実引数
• 実引数:関数を呼び出す際に渡す値
• 仮引数:関数の定義内で値を受け取る変数
複数の引数を持つ関数
• 複数の引数をカンマ(,)で区切って指定
• 実引数と仮引数の数が一致しておくこと
#include <stdio.h>
引数の数だけ「カンマ(,)」で区
切って変数を用意する(2個の
引数を持つ関数としている)
/*buy関数の定義 */
void buy( int x , int y )
{
printf(“%d万円と%d万円の車を買いました\n”, x, y );
}
/*main関数(buy関数の呼び出し)*/
main()
{
2個の引数
int num1 = 20;
を渡す
int num2 = 50;
buy( num1, num2 );
仮引数
}
x
←
y
←
実引数
num1の値
num2の値
20
50
x
y
void buy( int x , int y )
20
50
{
printf(“%d万円と%d万円の車を買いました\n”, x, y );
}
main()
{
buy( num1, num2 );
}
20
num1
50
num2
戻り値
• 関数の呼び出し元に、関数本体から特定の
情報を返す
呼び出し
関数で処理
main関数
buy関数
呼び出し元に
戻る
ある値を呼び出
し元に返す
関数の定義
戻り値の型 関数名(引数)
戻り値の型を
{
指定
文1;
文2;
式の値を呼び出し元
文3;
に返す
・・・
return 式;
return文はどこに書いても良い。
return文が実行されると、呼び
}
出し元に処理が戻る。
関数の定義
/*buy関数の定義*/
int buy(int x, int y)
{
int型の値を返す
ものとしている
int z;
printf(“%d万円と%d万円の車を買いました\n”, x, y );
z = x + y;
return z;
この値を呼び出し元に
}
返す
#include <stdio.h>
/*buy関数の定義*/
int buy(int x, int y)
{
int z;
printf(“%d万円と%d万円の車を買いました\n”, x, y );
z = x + y;
return z;
}
戻り値を返す
/*main関(buy関数の呼び出し)*/
戻り値は利用しなくても良い
main()
{
int num1, num2, sum;
num1 = 20;
戻り値を、sumに格納
num2 = 50;
sum = buy( num1, num2 );
printf(“合計で%d万円です”, sum);
}
関数の定義
• 戻り値を持たない関数
voidは「空の」とい
う意味
– 戻り値の型にvoid(ヴォイド)と指定する
void buy(int x)
{
printf(“%d万円の車を買いました\n”, x);
return;
}
戻り値を指定する必要はない(この場合,return文はなくてもOK)
変数とスコープ
変数の種類
• ローカル変数:
関数のブロック(中括弧で挟まれた部分)内で宣言
した変数
• グローバル変数:
関数のブロック外で宣言した変数
変数のスコープ(有効範囲)
• ローカル変数:関数の中で定義した変数
int func( )
{
int y;
…
}
main()
{
int x;
x = 3;
y = 5;
}
変数yのスコープ
変数xのスコープ
func()にあるyを
参照することはできない!
変数のスコープ(有効範囲)
• グローバル変数:関数の外で定義した変数
変数zのスコープ
int z; //グローバル変数
int func( ... )
グローバル変数
{
変数yのスコープ
int y;
z = 2;
}
ローカル変数
main()
{
int x;
z = 1;
}
変数xのスコープ
int y;
int z;
void myfunc(int a)
{
int z;
int x;
x = a;
y = a;
z = a;
}
main()
{
グローバル変数yとzのスコープ
グローバル変数と同じ名前の
ローカル変数があるときは,
ローカル変数が優先される
ローカル変数zとxのスコープ
同じ名前であっても,
ローカル変数は,別の変数と見なす
int x;
x = 10;
y = 10;
z = 10;
printf(“x, y, zの値は%d, %d, %d\n”,x, y, z);
myfunc( 5 );
printf(“x, y, zの値は%d, %d, %d\n”,x, y, z);
}
ローカル変数xのスコープ
変数の寿命
• 変数を宣言
⇒
メモリが確保される
• 利用しない変数のためにメモリを確保するこ
とは、非効率 ⇒ 利用が終わった変数のメ
モリは解放する
• 変数には、寿命がある⇒記憶領域(メモリ)を
確保しておく期間が決まっている。
変数の寿命
• ローカル変数:関数内で宣言してから、その
関数が終了するまで
関数の始まり
関数の終わり
変数の宣言
ローカル
変数X
x
メモリの
確保
メモリの
解放
x
変数の寿命
• グローバル変数:プログラム本体の処理が始
まる前から、プログラムが終了するまで
プログラムの始まり
グローバル
変数X
x
プログラムの終わり
メモリの
確保
メモリの
解放
x
変数の寿命
• 通常、ローカル変数の寿命は、宣言されてか
ら、その関数が終わるまで
staticというキーワード〈記憶クラス指定子)で変数を宣言すると、
グローバル変数と同じ寿命を持つことができる。
⇒「静的寿命を持つローカル変数」という
#include <stdio.h>
int a = 0;
void func(void)
{
int b = 0;
static int c = 0;
printf(“a = %d, b = %d, c = %d\n”, a, b, c);
a++;
b++;
ローカル変数b
はインクリメント
}
されていない
main()
実行結果
{
a = 0, b = 0, c = 0
func(); func(); func();
a = 1, b = 0, c = 1
a = 2, b = 0, c = 2
}
プロトタイプ宣言
関数の定義
関数の呼び出し
関数の呼び出し
関数の定義
プロトタイプ宣言:
関数のひな型を呼び出し前に宣言しておく
プロトタイプ宣言
戻り値の型 関数名
第1引数の型
プロトタイプ
宣言
int addnum(int, int);
関数の
呼び出し
n = addnum(2, 3);
関数の定義
int addnum(int a, int b)
{
…
}
第2引数の型
#include <stdio.h>
void dispnum(int a)
{
printf(“引数の値は%d\n”, a);
}
main()
{
int x = 10;
dispnum( 5 );
dispnum( x );
}
#include <stdio.h>
void dispnum(int a);
プロトタイプ宣言
main()
{
int x = 10;
dispnum( 5 );
dispnum( x );
}
void dispnum(int a)
{
printf(“引数の値は%d\n”, a);
}