Download : sample-001.c
/* * DATE sample-001.c */ #include <stdio.h> #include "s_turtle.h" /* 亀プログラムの場合に必要 */ /* * 亀プログラム */ /* * void move_ten(void) * * 現在向いている方向に 10 歩、足跡を残しながら進む */ void move_ten(void) { /* 「一歩進む」事を、10 回行う.. */ s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); } /* * main */ int main ( void ) { /* * 最初は真中 (0,0) で上を向いている */ /* * 二十歩前に足跡を残しながら進む * 矩形の左辺を下から上に引く (0,0) -> (0,20) */ move_ten(); move_ten(); /* * 時計回りに 45 度を二回、すなわち 90 度向きを変える * 矩形の左上隅で右に向きを変える */ s_turtle_turn(); s_turtle_turn(); /* * 矩形の上辺を左から右に引く (0,20) -> (20,20) */ move_ten(); move_ten(); /* * 矩形の右上隅で下に向きを変える */ s_turtle_turn(); s_turtle_turn(); /* * 矩形の右辺を上から下に引く (20,20) -> (0,20) */ move_ten(); move_ten(); /* * 矩形の右下隅で左に向きを変える */ s_turtle_turn(); s_turtle_turn(); /* * 矩形の下辺を右から左に引く (0,20) -> (0,0) */ move_ten(); move_ten(); /* * 元の左下隅 (0,0) に戻った */ putchar ( '>' ); getchar(); s_turtle_stop(); return 0; }
$ ./sample-001.exe $
Download : sample-002.c
/* * DATE sample-002.c */ #include <stdio.h> #include "s_turtle.h" /* 亀プログラムの場合に必要 */ /* * 亀プログラム */ /* * void jump_ten(void) * * 現在向いている方向に 10 歩、足跡を残こさずに跳ねる */ void jump_ten(void) { /* 「一歩跳ねる」事を、10 回行う.. */ s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); } /* * void move_ten(void) * * 現在向いている方向に 10 歩、足跡を残しながら進む */ void move_ten(void) { /* 「一歩進む」事を、10 回行う.. */ s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); } /* * void turn_90(void) * * 現在向いている方向から時計回りに 90 度向きを * 進行方向の「右」に向きを変える */ void turn_90(void) { /* 「45 度向きを変える」事を、2 回行う.. */ s_turtle_turn(); s_turtle_turn(); } /* * void turn_270(void) * * 現在向いている方向から時計回りに 270 度向きを * 進行方向の「左」に向きを変える */ void turn_270(void) { /* 「90 度向きを変える」事を、3 回行う.. */ turn_90(); turn_90(); turn_90(); } /* * void move_and_turn(void) * * 現在向いている方向から 20 歩進んで右を向く * 四角形の一辺を書く */ void move_and_turn(void) { /* 20 歩進む */ move_ten(); move_ten(); /* 向きを変える */ turn_90(); } /* * void draw_sqare( void ); * * 一辺が 20 の長さの四角形を書く */ void draw_sqare( void ) { /* 「長さ 20 の辺を書いて右を向く」という事を 4 回繰り返す */ move_and_turn(); move_and_turn(); move_and_turn(); move_and_turn(); } /* * int main ( void ) */ int main ( void ) { /* * 最初は真中 (0,0) で上を向いている */ draw_sqare(); /* まず四角を書く */ turn_270(); /* 270 度回転 */ jump_ten(); /* 10 歩跳ねる */ draw_sqare(); /* また四角 */ turn_270(); jump_ten(); draw_sqare(); turn_270(); jump_ten(); draw_sqare(); putchar ( '>' ); getchar(); s_turtle_stop(); return 0; }
$ ./sample-002.exe $
Download : sample-003.c
/* * DATE sample-003.c */ #include <stdio.h> /* * 文字の出力 */ /* * int main ( void ) */ int main ( void ) { putchar ( 'a' ); /* 「a」という『文字』を出力する */ return 0; }
$ ./sample-003.exe a$
Download : sample-004.c
/* * DATE sample-004.c */ #include <stdio.h> /* * 文字の出力 */ /* * int main ( void ) */ int main ( void ) { putchar ( 'a' ); /* 「a」という『文字』を出力する */ putchar ( 'b' ); /* 同 「b」という『文字』を出力する */ putchar ( 'c' ); /* 「c」 */ putchar ( '\n' ); /* 「\n」は改行を表す */ return 0; }
$ ./sample-004.exe abc $
Download : sample-005.c
/* * DATE sample-005.c */ #include <stdio.h> /* * 文字の入力 */ /* * int main ( void ) */ int main ( void ) { printf ( "[Enter] キーを押してください : " ); getchar(); /* 文字を入力する (入力されるまで待つ) */ /* 目的は「入力」より「待つ」事が目的 */ return 0; }
$ ./sample-005.exe < sample-005.in [Enter] キーを押してください : $
Download : sample-006.c
/* * DATE sample-006.c */ #include <stdio.h> /* * 文字の echo Back */ /* * int main ( void ) */ int main ( void ) { printf ( " 2 文字入力して [Enter] キーを押してください : " ); putchar ( getchar() ); /* 一文字目を入力して出力 */ putchar ( getchar() ); /* ニ文字目を入力して出力 */ putchar ( getchar() ); /* 三文字目(改行)を入力して出力 */ /* [Enter] は、「改行」一文字になる */ return 0; }
3G
$ ./sample-006.exe < sample-006.in 2 文字入力して [Enter] キーを押してください : 3G 3G $
Download : sample-007.c
/* * DATE sample-007.c */ #include <stdio.h> /* * 文字の echo Back */ /* * int main ( void ) */ int main ( void ) { printf ( " 2 文字入力して [Enter] キーを押してください : " ); putchar ( getchar() + 1 ); /* 一文字目を入力して + 1 してから出力 */ putchar ( getchar() - 1 ); /* ニ文字目を入力して - 1 してから出力 */ putchar ( getchar() ); /* 三文字目(改行)を入力して出力 */ /* [Enter] は、「改行」一文字になる */ return 0; }
3G
$ ./sample-007.exe < sample-007.in 2 文字入力して [Enter] キーを押してください : 3G 4F $
Download : sample-008.c
/* * DATE sample-008.c */ #include <stdio.h> #include <string.h> /* * 文字列に 1 を加えると.. ? * 文字の長さが短くなる (頭の部分がなくなる..) */ /* * main */ int main ( void ) { printf ( "abcde\n" ); /* 当然 「abcde」が表示される.. */ printf ( "abcde\n" + 1 ); /* 文字列に 1 を加えるってどうゆうこと.. ? */ printf ( "abcde\n" + 2 ); printf ( "abcde\n" + 1 + 1 ); /* ("abcde\n" + 1) + 1 => "bcde\n" + 1 => "cde\n" */ return 0; }
$ ./sample-008.exe abcde bcde cde cde $
Download : sample-009.c
/* * DATE sample-009.c */ #include <stdio.h> #include <string.h> /* * void recursive ( char *string ) * char *string 指定した文字列からなる三角形を作る * 実行例 * recursive( "abc\n" ); * -> * abc "abc\n" * bc "bc\n" * c "c\n" * "\n" * 再帰呼出しを利用 */ void recursive ( char *string ) { if ( !strcmp ( string, "" ) ) { /* もし空文字列 ( "" ) ならば */ printf ( "" ); /* これで御仕舞い */ } else { /* そうでなければ、 */ printf ( string ); recursive ( string + 1 ); /* 再帰呼び出しする */ /* +1 を忘れると悲惨な事に.. */ } } /* * main */ int main ( void ) { recursive ( "abcdefg\n" ); recursive ( "xyz\n" ); return 0; }
$ ./sample-009.exe abcdefg bcdefg cdefg defg efg fg g xyz yz z $
Download : sample-010.c
/* * DATE sample-010.c */ #include <stdio.h> #include <string.h> /* * 再帰呼出しを利用して、"Hello, World\n" を沢山出力する */ /* * void rec_hello ( char *count ) * char *count 文字列を指定し、その長さで、繰り返えし回数の指数を指定 * 与えられた文字列の長さを n とすると 2^n 回だけ出力する */ void rec_hello ( char *count ) { if ( !strcmp ( count, "" ) ) { /* カラッポなら.. */ printf ( "Hello, World\n" ); /* 一つだけ表示してみる */ } else { /* そうでなければ.. */ rec_hello ( count + 1 ); /* 二倍にして再帰よびだし */ rec_hello ( count + 1 ); } } /* * main */ int main ( void ) { rec_hello ( "****" ); /* 2^4 = 16 回出力 */ /* 2^10 = 1024 だから、 "**********" を与えれば... */ return 0; }
$ ./sample-010.exe Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World Hello, World $
Download : sample-011.c
/* * DATE sample-011.c */ #include <stdio.h> #include <string.h> /* * フィボナッチ数の計算 */ /* * void fib ( char *n ) * char *n n の長さで何番目の項かを表す * n 番目のフィボナッチ数だけ '*' を表示する */ void fib ( char *n ) { if ( !strcmp ( n, "" ) ) { /* カラッポ(0)なら.. */ printf ( "*" ); /* 一つだけ : fib(0) = 1 だから */ } else if ( !strcmp ( n, "*" ) ) { /* 一つ(1)なら */ printf ( "*" ); /* 一つだけ : fib(1) = 1 だから */ } else { /* そうでなければ.. */ fib ( n + 1 ); /* fib ( n - 1 ) と */ fib ( n + 2 ); /* fib ( n - 2 ) だけだす */ } } /* * main */ int main ( void ) { printf ( "fib 3 : " ); fib ( "***" ); printf ( "\n" ); printf ( "fib 5 : " ); fib ( "*****" ); printf ( "\n" ); return 0; }
$ ./sample-011.exe fib 3 : *** fib 5 : ******** $
Download : sample-012.c
/* * DATE sample-012.c */ #include <stdio.h> #include <string.h> /* strcmp に必要 */ #include "s_turtle.h" /* 亀プログラムの場合に必要 */ /* * 亀プログラムと再帰呼出し */ /* * void jump_n( char *n ) * char *n 足跡の長さを表す * 指定された長さだけ現在向いている方向に足跡を残こさず跳ねる */ void jump_n( char *n ) { if ( !strcmp ( n, "" ) ) { /* n が空文字列 ("") なら何もしない */ } else { s_turtle_jump(); /* とりあえず、一歩跳ねる */ jump_n ( n + 1 ); /* 文字列を短くして、再帰呼出し */ } } /* * void move_n( char *n ) * * char *n 足跡の長さを表す * 指定された長さだけ現在向いている方向に足跡を残こして歩く */ void move_n(char *n) { if ( !strcmp ( n, "" ) ) { /* n が空文字列 ("") なら何もしない */ } else { s_turtle_move(); /* とりあえず、一歩歩く */ move_n ( n + 1 ); /* 文字列を短くして、再帰呼出し */ } } /* * void turn_n(char *n) * * 現在向いている方向から時計回りに n * 45 度向きを変える */ void turn_n(char *n) { if ( !strcmp ( n, "" ) ) { /* n が空文字列 ("") なら何もしない */ } else { s_turtle_turn(); /* とりあえず、45 度向きをかえる */ turn_n ( n + 1 ); /* 文字列を短くして、再帰呼出し */ } } /* * void turn_90(void) * * 現在向いている方向から時計回りに 90 度向きを * 進行方向の「右」に向きを変える */ void turn_90(void) { turn_n ( "**" ); } /* * void turn_270(void) * * 現在向いている方向から時計回りに 270 度向きを * 進行方向の「左」に向きを変える */ void turn_270(void) { turn_n ( "******" ); } /* * void move_n_and_turn(char *n) * * 現在向いている方向から n 歩進んで右を向く * 四角形の一辺を書く */ void move_n_and_turn( char *n ) { move_n ( n ); /* 向きを変える */ turn_90(); } /* * void draw_n_sqare( char *n ); * * 一辺が n の長さの四角形を書く */ void draw_n_sqare( char *n ) { /* 「長さ n の辺を書いて右を向く」という事を 4 回繰り返す */ move_n_and_turn(n); move_n_and_turn(n); move_n_and_turn(n); move_n_and_turn(n); } /* * int main ( void ) */ int main ( void ) { /* * 最初は真中 (0,0) で上を向いている */ draw_n_sqare( "********************" ); /* まず四角を書く */ turn_270(); /* 270 度回転 */ jump_n( "**********" ); /* 10 歩跳ねる */ draw_n_sqare( "********************" ); /* また四角 */ turn_270(); jump_n( "**********" ); draw_n_sqare( "********************" ); turn_270(); jump_n( "**********" ); draw_n_sqare( "********************" ); putchar ( '>' ); getchar(); s_turtle_stop(); return 0; }
$ ./sample-012.exe $
/* * 20180518-01-QQQQ.c * 引数付き関数で、if 文で条件判断をするプログラムを作成しなさい */ #include <stdio.h> #include <strings.h> /* * こだまでしょうか * (c) 金子みすゞ * http://www.ad-c.or.jp/campaign/self_area/03/index.html */ void kakko ( char *message ) { printf ( "「" ); printf ( message ); printf ( "」" ); } /* 基本 iu ( "遊ぼう" ); =>「遊ぼう」っていうと「遊ぼう」っていう。 iu ( "馬鹿" ); =>「馬鹿」っていうと「馬鹿」っていう。 「」の中 (二か所) => 異なる部分 => 変数になる */ void iu ( char *message ) { kakko ( message ); /* 「もう遊ばない」 */ printf ( "っていうと" ); /* っていうと */ if ( !strcmp ( message, "もう遊ばない" ) ) { /* [もう遊ばない]の場合 */ kakko ( "遊ばない" ); /* 「遊ばない」 */ } else { /* [基本] */ kakko ( message ); /* 「遊ぼう」 */ } printf ( "っていう。\n" ); /* っていう。*/ } /* * main */ int main ( void ) { iu ( "遊ぼう" ); /* <= 基本 : 引数をそのまま出す */ iu ( "馬鹿" ); iu ( "もう遊ばない" ); /* <= この時は例外 */ printf ( "そうして、あとでさみしくなって、\n" ); iu ( "ごめんね" ); printf ( "こだまでしょうか、いいえ、誰でも。\n" ); return 0; }
/* * DATE-02-QQQQ.c * 底辺の長さが指定した文字列の二倍の長さ - 1 の横向のピラミッドを作成するプログラムを作成する */ #include <stdio.h> #include <strings.h> /* */ void down ( char *edge ) { /* down ( "****" ); */ if ( !strcmp ( edge, "" ) ) { /* なにもする必要はない */ } else { printf ( edge ); printf ( "\n" ); /* **** */ down ( edge + 1 ); /* *** */ /* ** */ /* * */ /* 最初にプリントして、残りを再帰 => 下向き */ } } void up ( char *edge ) { if ( !strcmp ( edge, "" ) ) { /* なにもする必要はない */ } else { up ( edge + 1 ); printf ( edge ); printf ( "\n" ); /* 残りを再帰、あとからプリント => 上向き */ } } void pyramid ( char *edge ) { up ( edge + 1 ); printf ( edge ); printf ( "\n" ); down ( edge + 1 ); } /* * main */ int main ( void ) { pyramid ( "*****" ); printf ( "\n" ); pyramid ( "**********" ); /* * ** *** **** <= up ***** <= down **** *** ** * */ /* down ( "*****" ); printf ( "\n" ); down ( "**********" ); */ /* up ( "*****" ); printf ( "\n" ); up ( "**********" ); */ return 0; }
#include <stdio.h> /* 引数付き関数の例 引数で指定された文字列を、三度出力する */ void threetimesprint( char *message ) { printf ( message ); printf ( message ); printf ( message ); } int main(void) { printf ( "[a]\n" ); threetimesprint ( "a\n" ); printf ( "[ab]\n" ); threetimesprint ( "ab\n" ); printf ( "[abc]\n" ); threetimesprint ( "abc\n" ); return 0; }
#include <stdio.h> /* 引数付き関数の例 引数で指定された文字列を、三度出力する ただし、 引数が "ab\n" の時だけ、一度にする => 引数が "ab\n" の時と、そうでないときは「全く」違う 命令を実行 => if 構文 if 構文 if ( 条件 ) { 条件が成立した時の命令 } else { 条件が不成立(上の命令を実行しない)時の命令 } 1. 二つの命令は、どちらか一方だけが実行される 2. 命令を実行する条件がかける => (数学的) 場合分けの場合に利用される 「条件」の書き方 「!strcmp(A,B)」=> 「文字列 A, B が等しい」という「条件」 */ void threetimesprint( char *message ) { if ( !strcmp( message, "ab\n" ) /* 引数 message の値が "ab\n" である */ ) { /* "ab\n" の時 */ printf ( message ); } else { /* "ab\n" 以外の時 */ printf ( message ); printf ( message ); printf ( message ); } } int main(void) { printf ( "[a]\n" ); threetimesprint ( "a\n" ); printf ( "[ab]\n" ); threetimesprint ( "ab\n" ); printf ( "[abc]\n" ); threetimesprint ( "abc\n" ); return 0; }
#include <stdio.h> /* 挨拶を返す 基本は、言われた事をそのまま「」をつけて、表示する おはよう => 「おはよう」 こんにちは => 「こんにちは」 さよならの時だけ別扱い さようなら => 「バイバイ(^o^)/~~~」 */ void echo( char *message ) { if ( !strcmp ( message, "さようなら" ) ) { /* message が「さようなら」の時 */ printf ( "「バイバイ(^o^)/~~~」\n" ); } else { /* 基本 */ printf ( "「" ); printf ( message ); printf ( "」\n" ); } } int main(void) { printf ( "[おはよう]\n" ); echo ( "おはよう" ); printf ( "[こんにちは]\n" ); echo ( "こんにちは" ); printf ( "[さようなら]\n" ); echo ( "さようなら" ); return 0; }
#include <stdio.h> int main(void) { printf ( "Hello, World\n" ); printf ( "Hello, World\n" + 1 ); /* printf ( "ello, World\n" ); と同じ */ /* 文字列に 1 を加えると... 先頭の文字が一文字なくなって短くなる */ printf ( "Hello, World\n" + 2 ); printf ( "[\n" ); printf ( "Hello, World\n" + 13 ); /* printf ( "" ); と同じ : 「""」空文字列(長さ 0 の文字列) */ printf ( "]\n" ); return 0; }
#include <stdio.h> void triangle ( char *message ) { printf ( message ); printf ( "\n" ); printf ( message + 1 ); printf ( "\n" ); printf ( message + 2 ); printf ( "\n" ); } int main(void) { triangle ( "abc" ); triangle ( "123" ); triangle ( "Hello" ); return 0; }
#include <stdio.h> void triangle ( char *message ) { printf ( message ); printf ( "\n" ); if ( !strcmp ( message, "" ) ) { /* ここはなにも書いていないので、何もしない */ } else { triangle ( message + 1 ); /* 関数 triangle を定義するのに、 その中で triangle を利用している 「再帰呼び出し」 (what)ある関数を定義するとき、 その定義の中で、自分自身を呼び出す事 */ } } int main(void) { triangle ( "abc" ); /* 1. triangle ( "abc" ); 「triangle」を調べる void triangle ( char *message ) { .. } が見つかる。 message = "abc" { printf ( message ); printf ( "\n" ); if ( !strcmp ( message, "" ) ) { } else { triangle ( message + 1 ); } } 2. printf ( "abc" ); printf ( "\n" ); => 「abc」 if ( !strcmp ( "abc", "" ) ) { } else { triangle ( "abc" + 1 ); } 3. triangle ( "bc" ); 「triangle」を調べる void triangle ( char *message ) { .. } が見つかる。 message = "bc" { printf ( message ); printf ( "\n" ); if ( !strcmp ( message, "" ) ) { } else { triangle ( message + 1 ); } } 4. printf ( "bc" ); printf ( "\n" ); => 「bc」 if ( !strcmp ( "bc", "" ) ) { } else { triangle ( "bc" + 1 ); } 5. triangle ( "c" ); 「triangle」を調べる void triangle ( char *message ) { .. } が見つかる。 message = "c" { printf ( message ); printf ( "\n" ); if ( !strcmp ( message, "" ) ) { } else { triangle ( message + 1 ); } } 6. printf ( "c" ); printf ( "\n" ); => 「c」 if ( !strcmp ( "c", "" ) ) { } else { triangle ( "c" + 1 ); } 7. triangle ( "" ); 「triangle」を調べる void triangle ( char *message ) { .. } が見つかる。 message = "" { printf ( message ); printf ( "\n" ); if ( !strcmp ( message, "" ) ) { } else { triangle ( message + 1 ); } } 8. printf ( "" ); printf ( "\n" ); => 「」 if ( !strcmp ( "", "" ) ) { } else { triangle ( "" + 1 ); } 9.おしまい */ triangle ( "123" ); triangle ( "Hello" ); return 0; }
#include <stdio.h> void infty_loop(void) { printf ( "Hello\n" ); infty_loop(); /* 再帰呼び出し */ } int main(void) { infty_loop(); return 0; }
[復習] 引数付き関数 関数作成 => 既存の命令に名前を付る 1. 名前を決める foobar 2. それを main 関数の外に書く foobar 3. その前と後ろに、void, (void) void foobar (void) 4. {} を追加 void foobar (void) { } 5. {} の中に、名前を付けたい、命令をかく void foobar (void) { printf ( "Hello, World\n" ); } => 1 から 5 を「関数定義」 <= この形式(引数なし)の関数 毎回、同じ操作(命令)しかできない 6. 呼び出す度に、異なるふるまいをさせたい => 実行するときに、命令の一部が「変化」 「変更」される、データの部分を、「変数」に変更する void foobar (void) { printf ( "Hello, " ); printf ( X ); 「X」という変数 printf ( "\n" ); } 7. 変数の値は、「引数」で指定する void foobar (char *X) { 引数で X の値を決める printf ( "Hello, " ); printf ( X ); 「X」という変数 printf ( "\n" ); } => 引数付き関数 => 関数呼び出しに、関数の引数に、 命令内の変数に入れる値を指定する事が可能になる 命令を実行するときに、変数の部分が、 引数で指定したものに変化する => 引数を追加する事により、関数の「汎用性」が増した 「汎用性」:それが、どの範囲で利用できるかの指標 汎用性が高い => 利用できる範囲が広くなる make make と Makefile Makefile : 何かの作業の手順が記述されている ! 一種のプログラム(だが、C 言語などとは、動作原理) make コマンドにより Makefile が読み取られ、 作業が、「自動的おこなれる」 => プログラム開発の作業が自動化される [ポイント] [基本] Makefile があったら、make する [応用] make の後ろにマクロ定義可能で、これによって、 自分のプログラムの自動化が可能になる 課題として、「Makefile を作る」 分割コンパイル 一つのプログラムを、複数のソースコード(*.c)の中に記述して、 個々にコンパイルする事 cf. (最初は..) 一つのソースコードに、プログラムの内容をすべて 記述する(例 : helloworld.c) コンパイルは、このファイル一個 => オブジェクトファイル(*.o)が一つできる リンク時も、そのオブジェクトファイル一個を指定して、 実行ファイル (*.exe) を作成 プログラム = *.c => *.o => *.exe (分割コンパイル) プログラム = 1.c, 2.c, .., k.c ( k 個に分割 ) => 1.o, 2.o, ..., k.o ( k 個のオブジェクトファイル) => k 個のすべてのオブジェクトを一つ実行にファイルにリンクする => 実行ファイルは一つ [欠点] 作業量が増える <= make を作った [利点] ソースコードを分けた => 個々の関数(ここのソースファイルで定義されている)が 互いに、独立に利用できる cf. 事例 p1 => main(固有), sub1, sub2, sub3 p2 => main(固有), sub2, sub3, sub4 sub2, sub3 は同じものでよい ここで、もし、分割しないと p1.c の中に main, sub1, sub2, sub3 p2.c の中に main, sub2, sub3, sub4 二つの .c の中に sub2, sub3 が同時にあられる => 一方に、他方を Copy する事になる => 原理的に「バグ(プログラムの誤り)」の増殖につながる 一方、分割コンパイルの場合 p1.c => main sub1.c => sub1 sub2.c => sub2 sub3.c => sub3 p2.c => main (sub2.c => sub2) (sub3.c => sub3) # p1 の時のものをそのまま利用 sub4.c => sub4 # => sub2 の記述は一か所にしかない # => 万が一、sub2 にバグがあっても # 修正は、一か所で済む(事が保証される) [今日の話] 引数付き関数 => 関数の振る舞いを引数の値によって、変化させられる => 振る舞いの変化は、引数の変化に同調している(連続的) 変更の対象が、データだけで、命令そのものは変化していない 変数で変わったは、命令の対象が変わった <= 振る舞いそのものを変えたい 例: 出力の回数を変化させたい (今回の例では、必ず 3 回 => 場合によって 1 回とか 2 回にしたい) => 条件分岐 条件分岐 条件分岐とは(what) 条件によって、複数の命令のどちらか一方を実行する機構 C 言語で、条件分岐をするには(How To) 「if 構文」を利用する 複数の命令(A,B)を組み合わせる方法 1. 順接 (プログラムの記述量と実行する量が同じ) A B => A をやってから B を行う 2. 条件分岐(プログラムの記述量に比べ実行する量が少ない) if ( .. ) { A } else { B } => A, B のどちらか一方 => 1, 2 の組み合わせだけで記述されたプログラムは、 そのプログラムの長さ以下の実行しかしない 3. 繰り返し(同じ命令を何度も実行する仕組み) => 1 度しか書いていない命令が、何度も実行される可能性がある 文字列について C 言語では、「文字列に 1 を加える」と、文字列の先頭が失われて、 文字列の長さが、その一文字分短くなる 再帰呼び出し利用して、関数を定義すると、 その関数の命令の一部(再帰呼び出しをしていない部分)が、繰り返される。 [数学] 階乗 : 5! = 5 * 4 * 3 * 2 * 1 = 120 1 (n=0 の時) n! = { n * ((n-1)!) (その他) # 帰納的定義 => これの性質は数学的帰納法で示す事ができる 漸化式 数列 { a_n } が初項 a_0 で、公差が d の等差数列とする a_n = a_0 + (n-1) d 漸化式 a_0 (n=0) a_n = { a_{n-1} + d (その他 ! 「数学」では当たり前のように、帰納的定義がなされている ! C 言語では、それが、再起呼び出しになっている
Download : 20180525-01.c
/* * 20180525-01-QQQQ.c * * 漢字の「回」という文字(にみえる..) 絵を Turtle Graphics で書きなさい */ #include <stdio.h> #include "s_turtle.h" /* * sub */ void jump_ten(void) { /* 10 歩跳ねる */ s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); s_turtle_jump(); } void move_ten(void) { /* 10 歩進む */ s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); s_turtle_move(); } void turn_90() { /* 90 度向きをかえる */ s_turtle_turn(); s_turtle_turn(); } void small_square() { move_ten(); turn_90(); /* ** この部分を完成させなさい */ } void big_square() { move_ten(); move_ten(); move_ten(); turn_90(); /* ** この部分を完成させなさい */ } int main ( void ) { small_square(); /* ** この部分を完成させなさい */ big_square(); putchar ( '>' ); getchar(); s_turtle_stop(); return 0; }
$ ./20180525-01-QQQQ.exe >$