情報処理技法 (Cプログラミング)I 第8回 ー 関数 ー 担当: 荻田 武史 本日の授業内容 • 代入と演算の組み合わせ • 関数 • return文 • プロトタイプ宣言 • グローバル変数・ローカル変数 2 代入と演算の組み合わせ • 以下のような省略した表記が可能。 演算子 += -= *= /= 記述例 a += b; a -= b; a *= b; a /= b; 意味 a = a + b; a = a - b; a = a * b; a = a / b; 3 関数 • 自分で関数を定義することができる。 戻り値の型 引数の型 int func(int a, int b) { 関数の内容 return 戻り値 ; } 関数名(funcの部分)は自由に名前を付けて良い。 4 func.c #include <stdio.h> int func(int a, int b) { printf("a..%d, b..%d\n", a, b); return a + b; } int main(void) { int return_value; printf("Start of function main()\n"); return_value = func(3, 5); printf("return_value..%d\n", return_value); return 0; } 5 func.c の説明 • C言語では、プログラム実行は main()関 数から開始される。 • "Start of function main()"が表示。 • main()の中で関数 func()を呼び出してい る。 • func()の中の最後のreturn文で、2つの 引数を足した値を返している。 • 結果(return_value)の表示。 6 戻り値や引数のない関数 • 戻り値のない関数 void func(int a,……) { } • 引数のない関数 double func(void) { } 7 return文 • 関数の最後で呼び出し元に戻り値を返す機能。 • 関数の途中で実行を打ち切って呼び出し元に戻る機能。 ⇒ return文は関数の途中に書くこともできる。 void func(void) { if (評価式) { return; } returnした場合は この部分は実行されない } 8 プロトタイプ宣言(1) • C言語では、関数は呼び出し元より先(ソース コードの中で、上側)に定義または宣言されて いなければならない(試しにfunc.cを書き換えて みよう)。 $ cp func.c func2.c $ xemacs func2.c & (関数の定義の順序を自分で変更) $ gcc -Wall func2.c (警告をすべて出力) func2.c: In function `main': func2.c:9: warning: implicit declaration of function `func' 9 プロトタイプ宣言(2) • 関数の「定義」を先に書くことができな い場合は、「宣言」だけを先に書く。 int func(int a, int b); ⇒ 関数の定義から、最初の部分だけ取り出 して、最後にセミコロンを付けたもの。 10 func2.c #include <stdio.h> int func(int a, int b); int main(void) { int return_value; printf("Start of function main()\n"); return_value = func(3, 5); printf("return_value..%d\n", return_value); return 0; } int func(int a, int b) { printf("a..%d, b..%d\n", a, b); return a + b; } 11 関数を使ったソートプログラム • 「my_sort5.c」では、プログラムのすべてが main関数に書かれているため全体の見通しが 悪い。 ⇒ 関数を使ってプログラムを書き換え、見通しを 良くする。 プログラムを以下の3つのパートに分離する。 1. データを読む関数: read_data() 2. ソートする関数: sort_data() 3. データを出力する関数: print_data() 12 my_sort6.c の全体像 #include <stdio.h> #include <stdlib.h> #define SCORE_ARRAY_SIZE 100 int score[SCORE_ARRAY_SIZE]; int score_count; void read_data(void) { } 関数の外側で宣言されている: グローバル変数 ⇒ すべての関数から参照できる void sort_data(void) { } void print_data(void) { } int main(void) { } 13 関数 main() int main(void) { read_data(); sort_data(); print_data(); return 0; } ⇒ 単純明快! 14 関数 read_data() void read_data(void) { int status; int temp_score; score_count = 0; while (1) { status = scanf("%d", &temp_score); if (status == EOF) { break; } else if (status != 1) { fprintf(stderr, "input error\n"); exit(1); } if (score_count >= SCORE_ARRAY_SIZE) { fprintf(stderr, "data are too many\n"); exit(1); } score[score_count] = temp_score; score_count++; } } 関数の内側で宣言されている: ローカル変数 ⇒ この関数の中でしか参照できない 15 関数 sort_data() void sort_data(void) { int sorted_count; int minimum_index; int temp; int i; for (sorted_count = 0; sorted_count < score_count; sorted_count++) { minimum_index = sorted_count; for (i = sorted_count + 1; i < score_count; i++) { if (score[i] < score[minimum_index]) { minimum_index = i; } } temp = score[minimum_index]; score[minimum_index] = score[sorted_count]; score[sorted_count] = temp; } } 16 関数 print_data() void print_data(void) { int i; for (i = 0; i < score_count; i++){ printf("score[%d]..%d\n", i, score[i]); } } 17 プログラムが完成したら・・・ $ gcc -Wall my_sort6.c -o my_sort6 $ ./my_sort6 < data.txt 結果が正しいか確認する。 18
© Copyright 2024 ExpyDoc