1 C言語入門 第15週 プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。) 2 補足 return 文 return 戻り値; • 関数から抜けて呼び出し元へ戻り値を渡す return_test1.c int sub() { return 123; printf("hello\n"); } return文を実行すると 呼び出し元に戻るので それ以降の文は 実行されない void main() { int x = sub(); printf("%d\n", x); } return文に与えた値が 関数の戻り値になり 演算に使用される mintty + bash + GNU C $ gcc return_test1.c && ./a 123 return 文 • 戻り値の型は必要に応じて適切な型を選ぶ return_test2.c 例えばもし 浮動小数点数の値を 戻したいなら 戻り値の型は doubleでないといけない int sub() { return 1.23; } この例では戻り値の型はintなので return文にdoubleを与えても 戻り値はint型にキャストされるので 整数になる void main() { double = sub(); printf("%f\n", x); } mintty + bash + GNU C $ gcc return_test2.c && ./a 1.000000 5 教科書 pp.265-272., [1] pp.139-144., 講義資料第7週pp.21-22.,第11週pp.24-27. コマンドライン引数 第13週pp.4-10. • char *argv[] は char* 型の配列 mintty + bash 正確には 関数の引数で最初の [] は * と同じだったので char *argv[] は char **argv と同じ つまり char 型へのポインタへのポインタ $ ./argtest a b "c d" "e\"f" argc = 5 argv[0] = "./argtest" argv[1] = "a" argv[2] = "b" argv[3] = "c d" argv[4] = "e"f" argv[1] argv[2] argv[3] argv[4] 'a' '\0' 'b' '\0' 'c' ' ' 'd' '\0' 'e' '"' f '\0' データ型の制限: <limits.h> CHAR_BIT CHAR_MAX char 型のビット数 UCHAR_MAX または SCHAR_MAX CHAR_MIN 0 または SCHAR_MIN SCHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN signed の char, short, int, long の最小値 SCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX signed の char, short, int, long の最大値 UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX unsigned の char, short, int, long の最大値 なお unsigned 型は負の数がないので最小値は 0 である データ型の制限: <float.h> FLT_RADIX, DBL_RADIX 指数表現の基数 FLT_DIG, DBL_DIG 精度の10進桁数 FLT_MANT_DIG, DBL_MANT_DIG 仮数部における基数(RADIX)の桁数 FLT_EPSILON, DBL_EPSILON 1.0 + 𝑥 ≠ 1.0となる最小の𝑥 FLT_MAX, DBL_MAX float, double の最大値 FLT_MIN, DBL_MIN float, double の正規化された最小の浮動小数値 FLT_MAX_EXP, DBL_MAX_EXP RADIX 𝑛 − 1が表現可能な𝑛の最大値 FLT_MIN_EXP, DBL_MIN_EXP 10𝑛 を正規化された浮動小数値として表現可能な𝑛の最小値 この授業で扱わなかったこと • 構造体と共用体: struct, union • 型定義: typedef • 可変長引数: <stdarg.h> • va_list, va_start, va_arg, va_end • 非局所ジャンプ: <setjmp.h> • シグナル処理: <signal.h> 9 C言語の開発支援ツール 10 分割コンパイル • ファイルが多くなるとコンパイルが大変 mintty + bash + GNU C $ gcc strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c $ cmd + Borland C++ >bcc32 strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland strtoi_test.c: 一度実行すれば strtoi.c: strtosign.c: カーソルキーの上下で strtobase.c: コマンドの実行履歴から basetoint.c: base36toint.c: 選べるが、最初が面倒 Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland 1ファイルしか変更してないのに 全ファイルコンパイルし直すのは非効率 11 make コマンド • 依存関係を記述し必要な処理だけ行う • Makefile に依存関係と作成方法を記述する Makefile.cygwin.strtoi_test,1 all: strtoi_test.exe strtoi_test.exe: strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c $(CC) -o $@ $^ clean: -rm strtoi_test.exe 作成するファイル: 材料のファイル ... タブ...→作成方法 Makefile.bcc32.strtoi_test all: strtoi_test.exe strtoi_test.exe: strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c $(CC) strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c clean: -DEL strtoi_test.exe *.obj *.tds 12 make コマンド • make と打つだけで自動的にコンパイル mintty + bash + GNU C $ make -f Makefile.cygwin.strtoi_test,1 cc -o strtoi_test.exe strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c cmd + Borland C++ >make -f Makefile.bcc32.strtoi_test MAKE Version 5.2 Copyright (c) 1987, 2000 Borland bcc32 strtoi_test.c strtoi.c strtosign.c strtobase.c basetoint.c base36t oint.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland strtoi_test.c: strtoi.c: strtosign.c: strtobase.c: basetoint.c: base36toint.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland 13 make コマンド • 依存関係の記述 作成するファイル: 材料のファイル ... タブ...→作成方法 Makefile.cygwin.strtoi_test,2 all: strtoi_test.exe strtoi_test.exe: strtoi_test.o strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o $(CC) -o $@ $^ strtoi_test.o: strtoi_test.c myfunc_week10.h strtoi.o: strtoi.c myfunc_week10.h myfunc_week11.h myfunc_week12.h strtosign.o: strtosign.c myfunc_week12.h strtobase.o: strtobase.c myfunc_week12.h basetoint.o: basetoint.c myfunc_week11.h 標準的な作成方法で良い場合は base36toint.o: base36toint.c myfunc_week11.h 作成方法は省略出来る clean: -rm strtoi_test.exe strtoi_test.o strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o 14 make コマンド • 依存関係の解決 コンパイルが完了しているので 改めてコンパイルする 必要がなかった mintty + bash + GNU C $ make -f Makefile.cygwin.strtoi_test,2 直前に削除したため改めて cc -c -o strtoi_test.o strtoi_test.c コンパイルが必要になった cc -c -o strtoi.o strtoi.c cc -c -o strtosign.o strtosign.c ファイルだけ処理し直して cc -c -o strtobase.o strtobase.c てくれている cc -c -o basetoint.o basetoint.c cc -c -o base36toint.o base36toint.c cc -o strtoi_test.exe strtoi_test.o strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o $ make make: Nothing to be done for 'all'. $ rm strtosign.o $ make cc -c -o strtosign.o strtosign.c cc -o strtoi_test.exe strtoi_test.o strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o 15 make コマンド • 依存関係の解決 • 必要に応じて適宜作成方法を実行する • 例: • 材料のファイルが不足している場合 • 作成するファイル(旧)、材料のファイル(新)の場合 16 make コマンド • 同じmakeという名前が付いていて基本は同じ だが方言があり、細かい違いがある • • • • • • Wikipedia / make GNU Make Embarcadero / MAKE JM / make (1) FreeBSD 9.0-RELEASE-K / make (1) MSDN / NMAKE Reference 17 その他のビルドツール • Autotools • autoconf, automake, libtool の総称 • UNIX 系のソフトウェアでは標準的なビルドツール • 以下の標準的な手順でビルド出来るようになる mintty + bash + GNU C $ ./configure $ make $ make install • 書籍 • GNU AUTOCONF, AUTOMAKE, AND LIBTOOL https://sourceware.org/autobook/ (無料オンライン版) • Wikipedia / Autotools 18 その他のビルドツール • CMake - http://www.cmake.org/ • マルチプラットフォームな Makefile 作成ツール • Wikipedia / CMake 19 教科書pp.203-206. ライブラリの自作 • 標準ライブラリ関数はアーカイブやライブラリ と呼ばれる複数のオブジェクトファイルを1つ にまとめたファイルとして提供されている • cygwinでは/usr/lib/libc.a等 • Borland C++ではC:\boland\bcc32\Lib\cw32.lib等 • 標準ライブラリはコンパイル時に自動的にリ ンクされる • 但し <math.h> 等は -lm 等として明示的に /usr/lib/libm.aをリンクする必要がある場合もある 20 ライブラリの自作 • 複数のオブジェクトファイルを1つのファイルにまとめる にはアーカイバやライブラリアンと呼ばれるツールを 用いる • JM / ar (1) • 作成方法: ar q ライブラリ名 オブジェクトファイル名 ... • embarcadero / ライブラリマネージャ TLIB.EXE • 作成方法: tlib ライブラリ名 -+オブジェクトファイル名 ... 21 ライブラリの自作(Cygwin) • 複数のオブジェクトファイル(.oファイル)を1つ の.aファイルにまとめる • まとめたファイルをアーカイブ(archive)または スタティックライブラリ(static library)と呼ぶ mintty + bash + GNU C $ gcc -c strtoi.c strtosign.c strtobase.c basetoint.c base36toint.c $ ar q myfunc.a strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o ar: myfunc.a を作成しています $ gcc strtoi_test.c myfunc.a 必要な .o ファイルを myfunc.a から探してリンクし 実行ファイルを作成 複数の .o ファイルをまとめた .a ファイルの作成 22 ライブラリの自作(Borland C++) • 複数のオブジェクトファイル(.objファイル)を1 つの.libファイルにまとめる • まとめたファイルをライブラリと呼ぶ cmd + Borland C++ >bcc32 /c strtoi.c strtosign.c strtobase.cbasetoint.c base36toint.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland strtoi.c: 複数の .o ファイルをまとめた 必要な .obj ファイルを strtosign.c: strtobase.c: .lib ファイルの作成 myfunc.lib から探してリンクし basetoint.c: 実行ファイルを作成 base36toint.c: >tlib myfunc.lib -+strtoi.obj -+strtosign.obj -+strtobase.obj -+basetoint.obj -+base36toint.obj TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation >bcc32 strtoi_test.c myfunc.lib Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland strtoi_test.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland 23 ライブラリの自作 • make によるアーカイブの作成 Makefile.cygwin.myfunc.a all: myfunc.a myfunc.a: strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o $(AR) q $@ $^ strtoi_test.o: strtoi_test.c myfunc_week10.h strtoi.o: strtoi.c myfunc_week10.h myfunc_week11.h myfunc_week12.h strtosign.o: strtosign.c myfunc_week12.h strtobase.o: strtobase.c myfunc_week12.h basetoint.o: basetoint.c myfunc_week11.h base36toint.o: base36toint.c myfunc_week11.h clean: -rm myfunc.a strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o 24 ライブラリの自作 • make によるアーカイブの作成 mintty + bash + GNU C $ make -f Makefile.cygwin.myfunc.a cc -c -o strtoi.o strtoi.c cc -c -o strtosign.o strtosign.c cc -c -o strtobase.o strtobase.c cc -c -o basetoint.o basetoint.c cc -c -o base36toint.o base36toint.c ar q myfunc.a strtoi.o strtosign.o strtobase.o basetoint.o base36toint.o ar: myfunc.a を作成しています 教科書pp.188-189. ユニットテスト(単体テスト) • 標準ライブラリヘッダ <assert.h> • assert マクロの利用 • ユニットテストツールの利用 • CUnit http://cunit.sourceforge.net/ 25 26 assert マクロ void assert(int expression) • expression がゼロの場合以下のメッセージを stderr に出力し abort する Assertion failed: expression, file filename, line nnn • <assert.h>をインクルードする時点で NDEBUG マクロが定義されていると assert マクロは無 視される • ユニットテストだけでなくデバッグ時のみ有効に する不正値のチェック等でも利用される 27 assert マクロ • 専用のテストルーチンで使用した例 is_leap_year_assert.c is_leap_year_assert.c void test_leap_year() { assert(is_leap_year(-400) assert(is_leap_year(- 56) assert(is_leap_year(- 4) assert(is_leap_year( 0) assert(is_leap_year( 4) assert(is_leap_year( 56) assert(is_leap_year( 400) assert(is_leap_year(1996) assert(is_leap_year(2000) assert(is_leap_year(2004) } void test_normal_year() { assert(is_leap_year(-300) assert(is_leap_year(-200) assert(is_leap_year(-100) assert(is_leap_year(- 3) assert(is_leap_year(- 2) assert(is_leap_year(- 1) assert(is_leap_year( 1) assert(is_leap_year( 2) assert(is_leap_year( 3) assert(is_leap_year( 100) assert(is_leap_year( 200) assert(is_leap_year( 300) assert(is_leap_year(1900) assert(is_leap_year(1997) assert(is_leap_year(1998) assert(is_leap_year(1999) assert(is_leap_year(2001) assert(is_leap_year(2002) assert(is_leap_year(2003) } is_leap_year_assert.c int main() { test_leap_year(); test_normal_year(); return EXIT_SUCCESS; } == == == == == == == == == == 1); 1); 1); 1); 1); 1); 1); 1); 1); 1); == == == == == == == == == == == == == == == == == == == 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 0); 28 assert マクロ • 専用のテストルーチンで使用した例 • エラーがなければ何も起きない mintty + bash + GNU C $ gcc is_leap_year_assert.c is_leap_year_func_4_2.c && ./a • エラーがあるとそこで実行が中断する mintty + bash + GNU C $ gcc is_leap_year_assert.c is_leap_year_func_4_2.c && ./a assertion "is_leap_year( 0) == 1" failed: file "is_leap_year_assert.c", line 10, function: test_leap_year Aborted (コアダンプ) 29 CUnit • 専用のテストルーチンを作成して使用 is_leap_year_cunit.c is_leap_year_cunit.c static CU_TestInfo test_is_leap_year[] = { {"leap year", test_leap_year}, {"normal year", test_normal_year}, CU_TEST_INFO_NULL, }; void test_leap_year() { CU_ASSERT_EQUAL(is_leap_year(-400), CU_ASSERT_EQUAL(is_leap_year(- 56), CU_ASSERT_EQUAL(is_leap_year(- 4), CU_ASSERT_EQUAL(is_leap_year(1996), CU_ASSERT_EQUAL(is_leap_year(2000), CU_ASSERT_EQUAL(is_leap_year(2004), } static CU_SuiteInfo suites[] = { {"is_leap_year test", NULL, NULL, test_is_leap_year}, CU_SUITE_INFO_NULL, }; int main() { CU_initialize_registry(); CU_register_suites(suites); CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CU_cleanup_registry(); return EXIT_SUCCESS; } 1); 1); 1); 1); 1); 1); is_leap_year_cunit.c void test_normal_year() { CU_ASSERT_EQUAL(is_leap_year(-300), CU_ASSERT_EQUAL(is_leap_year(-200), CU_ASSERT_EQUAL(is_leap_year(-100), CU_ASSERT_EQUAL(is_leap_year(- 3), CU_ASSERT_EQUAL(is_leap_year(2002), CU_ASSERT_EQUAL(is_leap_year(2003), } 0); 0); 0); 0); 0); 0); 30 CUnit • 専用のテストルーチンを作成して使用 • ユニットテストの達成状況がレポートされる mintty + bash + GNU C $ gcc is_leap_year_cunit.c is_leap_year_func_4_2.c -lcunit && ./a CUnit - A unit testing framework for C - Version 2.1-2 http://cunit.sourceforge.net/ Suite: is_leap_year test Test: leap year ...passed Test: normal year ...passed Run Summary: Type suites tests asserts Elapsed time = Total 1 2 29 0.000 seconds Ran Passed Failed Inactive 1 n/a 0 0 2 2 0 0 29 29 0 n/a 31 差分パッチツール • diff : 差分比較、パッチ作成ツール • JM / diff (1) • Wikipedia / diff 単一ファイルのパッチの作成 $ diff -c myfile.orig myfile > myfile.patch ディレクトリ以下のパッチの作成 $ diff -crN mydir.orig mydir > mydir.patch • patch : 差分適用(パッチ適用)ツール • JM / patch (1) • Wikipedia / patch パッチの適用 $ patch < myfile.patch カレントディレクトリへのパッチの適用 $ patch -p0 -d. < mydir.patch 32 バージョン管理ツール • RCS • Wikipedia / Revision Control System • CVS • Wikipedia / Concurrent Version System • Subversion • Wikipedia / Apache Subversion • Mercurial • Wikipedia / Mercurial • Bazaar • Wikipedia / Bazaar • git • Wikipedia / git 過去の改変の記録を残したり 複数人で共同で作業する際に 役立つ github の登場で 人気になっている 33 参考文献 • [1] B.W.カーニハン/D.M.リッチー著 石田晴久 訳、プログラミング言語C 第2版 ANSI 規格準 拠、共立出版(1989) おつかれさまでした。 来週の試験です。しっかり復習しておきましょう。 おしまい お か だ
© Copyright 2025 ExpyDoc