html5-img
1 / 20

第 7 週 関数(1)

第 7 週 関数(1). プログラミング言語  2014 立命館大学情報理工学部. 関数の種類 P.114. main 関数 C 言語のプログラムでただ1つ存在. 必ず main 関数から実行される. ライブラリ関数 あらかじめ提供されている関数 ソースコード内でヘッダファイルを #include し, コンパイル時にライブラリをリンクして使う(後述) 自分で作る関数 ソースコード内 で main 関数とは別の関数を定義 次から のスライドで記述方法を説明 main 関数の前に置く場合,後に置く場合で書き方に違い

Download Presentation

第 7 週 関数(1)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7週関数(1) プログラミング言語 2014 立命館大学情報理工学部

  2. 関数の種類 P.114 • main関数 • C言語のプログラムでただ1つ存在. • 必ず main関数から実行される. • ライブラリ関数 • あらかじめ提供されている関数 • ソースコード内でヘッダファイルを#includeし,コンパイル時にライブラリをリンクして使う(後述) • 自分で作る関数 • ソースコード内でmain関数とは別の関数を定義 • 次からのスライドで記述方法を説明 • main関数の前に置く場合,後に置く場合で書き方に違い • 最初は,前に置く場合を説明

  3. List6-1 P.115 関数の定義と呼出し               (必須知識) 実行してみよう Fig.6-4 (P.116) も参考に /* 2つの整数の大きい方の値を返す関数 */ #include <stdio.h> intmaxof(int x, int y) { if( x > y ) return x; else return y; } int main(void) { intna, nb; puts(“2つの整数を入力 “); printf(“整数1 : “); scanf(“%d”, &na); printf(“整数2 : “); scanf(“%d”, &nb); printf(“大きい方の値は%dです.\n”, maxof(na, nb)); return 0; } main関数から開始 xに83,yに45を代入 maxof(83,45)を 関数呼び出し 2つの整数を入力 整数1 : 83 整数2 : 45 大きい方の値は83です. naの値は83 nbの値は45 main関数に戻った時の maxof(83,45)の値はreturn された値, つまり,83

  4. 関数定義 P.114, p.116, p.117(必須知識)呼び出される側の書き方 関数頭部: 型 関数名(型 仮引数1, 型 仮引数2, …) この関数が返す返却値の型   仮引数の型 intmaxof( int x, int y) { if(x > y) return x; else return y; } return 式; で示された式の 評価値が この関数が返す 返却値(戻り値) 関数本体 ={} で囲まれた複合文

  5. 関数呼び出し P.115(必須知識)呼び出す側の書き方 • 関数呼び出し式: 関数名(実引数1,実引数2, …) • 関数呼び出し式を評価すると,returnで返却される値 • 返却値の型は,前スライドにあった「関数が返す返却値の型」 int main(void) { intna, nb; naに83, nbに45を入力する printf(“大きい方の値は%dです.\n”, maxof(na, nb)); return 0; }

  6. List6-3 P.119 関数は複数あってもよい 左からの続き int main(void) { int p, q, p2, q2; puts("2つの整数を入力してください\n"); printf("整数p : "); scanf("%d", &p); printf("整数q : "); scanf("%d", &q); p2 = sqr(p); q2 = sqr(q); printf(“pの2乗とqの2乗の差は%d\n",diff(p2, q2)); return 0; } /* 2整数の2乗の差 */ #include <stdio.h> intsqr(int x) { return x * x; } int diff(int x, int y) { return x>y ? x-y: y-x; } 右へ続く printf(“pの2乗とqの2乗の差は%d\n", diff( sqr(p), sqr(q) ); と書いてもよい.

  7. List6-4P.120ループを持つ関数関数本体はmain関数と同じような構造List6-4P.120ループを持つ関数関数本体はmain関数と同じような構造 局所変数: 関数内で定義される変数(後述) 左からの続き /* べき乗 */ #include <stdio.h> double power(double dx, int no) { inti; double tmp = 1.0; for( i = 1; i <= no; i++) tmp*= dx; return tmp; } intmain(void) { intn; double x; printf(“実数は?:"); scanf("%lf",&x); printf(“整数は?:"); scanf("%d",&n); printf("%.2fの%d乗は%.2fです.\n", x, n, power(x, n)); return 0; } 右へ続く [注] scanf(“%lf”,&x): 変数 xが,float型ならf,double 型なら lf

  8. 値渡し P.120必須知識 List 6-4 の power() が main()から呼ばれるとき • 呼出されると,関数内の変数用のメモリ出現 • 呼出し側の値が,呼ばれる側の変数に複製 • 呼ばれる側の変数を変更しても,呼出し側の変数に影響なし • 返却値を返す • 関数の局所変数はreturn後, 呼ばれる側 power() 関数内の局所変数 tmp 関数内の局所変数 i 関数の仮引数 n 消滅 関数の仮引数 x 関数の返却値(関数値) 呼び出し側 main() ( ,) = power 呼出し側の変数 実引数 n 実引数 x

  9. List6-5 P.121  仮引数の変更値渡しを活かしてコンパクト化 /* 局所変数をループ変数に利用*/ double power(double dx, int no) { double tmp = 1.0; while( no-- > 0) tmp*= dx; return tmp; } double power(double dx, int no) { inti; double tmp = 1.0; for( i = 1; i <= no; i++) tmp*= dx; return tmp; } power() を変更 呼ばれる側の変数を変更しても,呼出し側の変数に影響なし この例では,仮引数をループ変数に使って,コンパクト化

  10. List6-6 P.121  関数を呼び出す関数 intmaxof(int x, int y) { if( x > y ) return x; else return y; } int max4(int w, int x, int y, int z) { return maxof(maxof(w,x), maxof(y,z)); } int main(void) {        : max4(a, b, c, d);        : } ここでmax4()の値が求められる

  11. 関数呼び出しとメモリ y y y maxof maxof maxof x x x 返却値 返却値 返却値 maxof( maxof( w, x ), maxof( y, z ) ) z y x w max4() max4の返却値 関数実行終了後,そのためのメモリは消滅 max4( , , , ) c d a b main()

  12. List6-7 P.122値を返さない関数 関数の型が void 実行してみよう /* 直角三角形 */ #include <stdio.h> void put_starts(int no) { while( no-- > 0) putchar('*'); } int main(void) { inti, ln; printf("何段ですか: "); scanf("%d", &ln); for(i = 1; i <= ln; i++) { put_stars(i); putchar('\n'); } return 0; } % ./triangle 何段ですか: 6 * ** *** **** ***** ****** % i行目に i個の* i個の印字をひと塊の機能とみなす

  13. 今回押さえるべきプログラム List 6-8 P.123汎用性P.129 印字する文字を引数に /* 左に空白がある直角三角形 */ #include <stdio.h> void put_nchar(intch, int no) { while( no-- > 0) putchar(ch); } int main(void) { inti, ln; printf("何段ですか: "); scanf("%d", &ln); for(i = 1; i <= ln; i++) { put_nchar(' ', ln -i); put_nchar('*', i); putchar('\n'); } return 0; } 何段ですか:6 i個の* ln-i個の空白 * ** *** **** ***** ****** これを1からlnまでループ この関数は2つの機能に使え,汎用性が高い

  14. List6-9 P.124 仮引数を受け取らない関数 仮引数が void 実引数は空 intrev_int(intnum) { inttmp = 0; if(num > 0) { do { tmp = tmp*10+num%10; num /= 10; } while(num > 0); } return tmp; } int main(void) { intnx = scan_unit(); printf("反転した値は%d\n", rev_int(nx)); return 0; } #include <stdio.h> intscan_unit(void) { inttmp; do { printf("非負の整数: "); scanf("%d", &tmp); if(tmp < 0) puts(“\a間違い"); } while( tmp < 0 ); return tmp; } 右へ続く 関数の返却値で 初期化 \a は「警告音を鳴らせ」

  15. ブロック有効範囲(block scope)P.125必須知識 { }内で定義された変数は{ }の内側で有効 • ブロック(block): { と } で囲まれた部分 • 変数の有効範囲をスコープという • ブロックで定義された変数のスコープは,ブロック内 intscan_unit(void) { inttmp; printf("非負の整数: "); scanf("%d", &tmp); return tmp; } intrev_int(intnum) { inttmp = 0; do { tmp = tmp*10+num%10; num /= 10; } while(num > 0); return tmp; } このtmp これらは このtmp scan_unit() rev_int() これらは main() tmp tmp 関数内の局所変数を格納したメモリは 関数実行終了後,消滅するので, 当たり前といえば当たり前 返却値 返却値

  16. ファイル有効範囲(file scope) P.126 • どのブロックにも定義が含まれない変数のスコープは,その定義からファイルの最後まで • ファイル・スコープを持つ変数は,使いにくいので,薦められない. 宣言と定義 P.127 • 定義:変数や関数がメモリ上に割付けられる • 宣言:変数や関数の型など使い方(仕様)を示す

  17. プロトタイプ 関数の原型宣言(P.127)(必須知識) #include <stdio.h> void put_starts(intnumber); int main(void) { inti, ln; printf("何段ですか: "); scanf("%d", &ln); for(i = 1; i <= ln; i++) { put_stars(i); putchar('\n'); } return 0; } void put_starts(int no) { while( no-- > 0) putchar('*'); } List6-7 を修正 • main()のあとで,関数を定義する場合 • main()が,関数の • 返却値の型 • 引数の数 • 引数の型  を知る手段が必要 プロトタイプ宣言を前に(最後に ; を忘れずに)

  18. ヘッダファイルと #includeP.128 (必須知識) • プロトタイプ宣言は,関数の仕様を示す. • これが最初にあると,いろいろな関数を使える. • printf(), scanf()などを使うためのプロトタイプ宣言はヘッダファイルstdio.hに入っている. • #include • その1行が,ファイルの内容と入れ替わる [例]#include <stdio.h> C言語であらかじめ用意されている,関数をそのファイルで使用できるようになる

  19. クイズ:プログラムを実行した結果を求めよ #include <stdio.h> #define MAX_NUMBER (4) int M(int left, int right) { return left > right ? left : right; } int m(int left, int right) { return left > right ? right : left; } int main(void) { int d[MAX_NUMBER] = {1, 9, 3, 8}; printf("答えは%d\n", m( M(d[0], d[1]), M(d[2], d[3]))); return 0; }

  20. 正解 • M()は2つの整数のうち,大きいほうを返す • m()は2つの整数のうち,小さい方を返す. • 最初にM(1,9)の値は9 • ついでM(3,8)の値は8 • 最後にm(9,8)の値は8 • よって,正解は8

More Related