Download presentation
Presentation is loading. Please wait.
Published byまれあ さわまつ Modified 約 8 年前
1
プログラミング 関数編 情報科学科
2
プログラミングにあたって C 言語では、 main 内に処理を記述 1000 行になるような大きなプログラムでは、 プログラム全体が何をしているのかを把握 することが困難になる 他人が見ると非常に理解しにくい 作成者であっても時が経てば内容を忘れて、他 人が見た時と同じ状況になる プログラムの一部分を再利用することが困 難 一連の処理を構成する意味のある部分処理をそ れぞれまとめたい
3
関数 汎用的に使用するコードや意味のある 部分処理を関数として一つの単位にま とめる main は一つの「関数」である 関数を使用するためには以下の部分が 必要となる プロトタイプ宣言 関数の定義 関数の呼び出し ( 関数の使用 ) p.126 ~
4
関数について 「関数呼出し」と「関数定義」 「プロトタイプ宣言」 「引数」 → 「実引数」と「仮引数」 「戻り値 ( 返り値 ) 」 「値渡し (Call by value) 」
5
機能と関数 ある一連の処理 ( 目的 : 機能 ) を実現する 手段が関数である 機能 f 引数 戻り値 x y z
6
#include float triangle(float,float); /* ← プロトタイプ宣言 */ int main(void) { float w, h, a; char line[100]; printf( “ width = "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &w); printf( “ highth = "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &h); area = triangle( w, h ); /* ← 関数呼び出し */ printf( “ size = %f\n", a); return 0; } float triangle ( float width, float height ) { float area; /* 変数定義 */ area = width * height / 2.0; /* 関数の計算本体 */ return area; } w とhの入力 変数の宣言 結果の出力
7
プロトタイプ宣言 コンパイラに対して、以下のことを教える どういう名前の関数で、 どのような型を戻り値にするか、 どのような型の引数を いくつ取るかを教える 例 : float triangle ( float, float ); プロトタイプ宣言には引数名は必要ない
8
関数に渡すパラメータ 引数(実引数) 関数の呼出し 関数をプログラム中で「使う」部分 代入文の右辺や条件式の一部に現れる 例 : area = triangle( w, h ); : if ( triangle(w, 3.2) < 40.9) { : printf(" %f\n", triangle(width, height)); :
9
関数の戻り値は一つ 通常、関数からの戻り値が 1 つだけ返される 計算結果や処理の終了状態 ( 正常終了 / 異常終了 ) 等 を戻り値として呼び出し側に返す。 例外 …… 0 個の場合 ( 関数の型が void) なにか仕事をして終ったことを通知 ( 関数からぬける ) 、呼出し側に戻る 2 個以上の値 ( 結果 ) を呼出し側に返したい場合 どの関数からも読み書きできる大域変数を用いる ポインタ (Call by reference) を使う → 詳細はポインタの所で
10
関数定義 関数の内容を詳細に記述する部分 例 : float triangle ( float width, float height ) { float area; /* 変数定義 */ area = width * height / 2.0; /* 関数の計算本体 */ return area; } 関数の型 関数名 (仮)引数 プロトタイプ宣言 と 型、名前、個数が 一致すること 引数の変数は、関 数の中で宣言しな くても使用できる 戻り値を返すため の return 文 関数の型 と戻り値の 型は一致
11
#include void printpage(int); int main(void) { int x; n = 1; printpage(n); n = n + 1; printpage(n); n = n + 1; printpage(n); return 0; } void printpage(int x) { printf("- %d -\n", x); printf("\n"); return; } 例1
12
実行結果 - 1 - - 2 - - 3 -
13
#include void printpage(int); int main(void) { int x; n = 1; printpage(n); return 0; } void printpage(int x) { printf("- %d -\n", x); printf("\n"); x = x + 1; return; } nの更新も関数内で 失敗する どうなるだろう? なぜだろう? 例2
14
どうなるだろう? - 1 -
15
なぜだろう? 関数の仮引数 x には、 実引数 n そのものではなく 実引数 n のコピーが渡るためです。 コピーを書き換えても オリジナルは破壊されません。 これを値渡し (call by value) といいます。
16
#include void printpage(void); int main(void) { int x; printpage(); return 0; } void printpage(void) { static int x = 0; printf("- %d -\n", x); printf("\n"); x = x + 1; return; } 例3例3 静的変数 静的変数を使うと、それが 属する関数が何回呼ばれて も、その変数はプログラム が動いている間ずっと値を 保持し続けることが出来る。
17
関数を利用する利点 プログラム作成の際、見通しが良くな る。 関数を使用すれば、そこで「何をするの か」が分かり、詳細に「どうする」まで考 えなくてもよい。 関数の定義では、「どうする」だけに集中 してプログラミングできる。 関数をくり返し利用することができて 効率がよくなる。 別のプログラムにも再利用が容易にな る。
18
変数のスコープ 教科書 p.123 ~を参照 ローカル変数 ( 局所変数 ) グローバル変数 ( 大域変数 )
19
ローカル変数 ( 局所変数 ) ブロック ("{" と "}" で括られた部分 ) 内 だけで使用できる変数 "{" の直後 ( ブロックの先頭 ) で宣言される 宣言されたブロック中だけで有効 → ブロックの外側では使用できない ブロック内のブロックで同名の変数が宣言 された場合には、最も内側のブロックで宣 言されている変数が使用される
20
グローバル変数 ( 大域変数 ) main を含む関数の一番外側のブロック よりも外側で宣言された変数 どの関数からも参照できる変数 極力グローバル変数の使用は避ける 名前の衝突が起こり安くなる 別の関数で変更される可能性があり、プログラ ム修正の波及効果が大きくなる → バグを埋め込んでしまう可能性が高くなる
21
#include void printx(void); int main(void) { int x; char line[100]; printf("x = "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &x); printx(); return 0; } void printx(void) { printf( “ x = %d ”, x); /* エラー */ return; } X の入力 例4例4
22
#include void printx(int); int main(void) { int x; char line[100]; printf("x = "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &x); printx( x ); return 0; } void printx(int x) { printf( “ x = %d ”, x); /* エラー */ return; } X の入力 例5例5
23
#include int x; void printx(void); int main(void) { char line[100]; printf("x = "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &x); printx(); return 0; } void printx(void) { printf( “ x = %d ”, x); return; } X の入力 例6例6
24
プリプロセッサ プリプロセッサとは プログラムのコンパイル段階で行わ れる 前処理 プリプロセッサの機能 1)ファイルを取り込む 2)マクロ定義をする
25
ファイルを取り込む #include #include :指定したファイルを読み込み、そ の内容を あたかもそこに記述したように組 み込む #include 指定したファイルが、コンパイラのパスがと おっている場所から探索されて取りこまれる。 #include “ ファイル名 ” 指定したファイルが、作成者が示した場所から 探索されて取りこまれる。
26
ヘッダーファイル( ○○ .h) 関数の定義をヘッダーファイルとしてファイル化し、 #include で取り込んで利用する ヘッダーファイルの作り方 1)関数内で標準ライブラリ関数を使う場合は #include のように必要なヘッダーファイルを取り込 んでおく。 2)自作関数のプロトタイプ宣言を書く。 3)関数の定義を書く。 4)拡張子 "h" で好きな名前にして保存する。 ヘッダーファイルの取り込み方 1)標準で用意されているヘッダーファイル → 例 )#include 2)自分で作ったヘッダーファイル → 例 )#include "jisaku.h"
27
マクロを定義する #define マクロとは: ある特定の数値、値を、 指定した特定の文字列に置き換えるこ と
28
マクロの使用例 例1) #define kuku 81; ・・・ printf( “ %d ”,kuku) 例2) #define OUT(x) printf(" 数値の値は %d です。 \n",x); ・・・ OUT(a);
29
マクロの使用例 注意! #define square(x) x * x ; ・・・ a=3; b=1; ・・・ printf( “ (a+b)*(a+b)=%d ”,square(a+b));
30
square(a+b) a+b*a+b 3+1*3+1 3+3+1 7 単なる文字列の書き換え
31
まとめ 関数は、一連の処理を構成する意味の ある部分処理のまとまりに名前を付け たもの 似た処理の共通部分を関数化すること で、再利用ができる 呼出し側で複雑な処理を考えなくてよ くなるのでプログラムの見通しが良く なる main 関数の記述をできるだけ簡素化し、 main 関数を見れば処理全体の流れを把握で きるようにプログラムを作ろう
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.