Download : sample-001.c
/* * 2018/05/18 sample-001.c */ /* * 最初のプログラムは "Hello, World" */ #include <stdio.h> /* * main 関数 */ int main ( void ) { printf ( "Hello, World\n" ); /* "Hello, World" という文字列と改行 ( "\n" ) を表示する */ return 0; }
$ ./sample-001.exe Hello, World $
Download : sample-003.c
/* * 2018/05/18 sample-003.c */ #include <stdio.h> /* * 「金糸雀(かなりや)」 * (c) 西條八十作詞・成田為三作曲 * http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/kanariya.html */ /* * 関数を使わずに愚直に命令を並べた * プログラミングの基本はこれ (実行したい内容をその順に並べる) */ /* * int main ( void ) */ int main ( void ) { printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "後の山に 棄てましょか\n" ); printf ( "いえ いえ それはなりませぬ\n" ); printf ( "\n" ); printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "背戸の小薮に 埋けましょか\n" ); printf ( "いえ いえ それはなりませぬ\n" ); printf ( "\n" ); printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "柳の鞭で ぶちましょか\n" ); printf ( "いえ いえ それはかわいそう\n" ); printf ( "\n" ); printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "象牙の船に 銀の櫂\n" ); printf ( "月夜の海に 浮べれば\n" ); printf ( "忘れた唄を おもいだす\n" ); return 0; }
$ ./sample-003.exe 唄を忘れた 金糸雀(かなりや)は 後の山に 棄てましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 背戸の小薮に 埋けましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 柳の鞭で ぶちましょか いえ いえ それはかわいそう 唄を忘れた 金糸雀(かなりや)は 象牙の船に 銀の櫂 月夜の海に 浮べれば 忘れた唄を おもいだす $
Download : sample-004.c
/* * 2018/05/18 sample-004.c */ #include <stdio.h> /* * 「金糸雀(かなりや)」 * (c) 西條八十作詞・成田為三作曲 * http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/kanariya.html */ /* * 共通する部分に名前を付け重複を減らす * 引数を利用しなくてもできる形 */ /* * void uta(void) * 「唄を忘れた 金糸雀(かなりや)は」を出力する */ void uta(void) { printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); } /* * void ieie(void) * 「いえ いえ それはなりませぬ」を出力する */ void ieie(void) { printf ( "いえ いえ それはなりませぬ\n" ); } /* * void kyoku_1(void) * 「歌詞 1 」を出力する */ void kyoku_1(void) { uta(); printf ( "後の山に 棄てましょか\n" ); ieie(); } /* * void kyoku_2(void) * 「歌詞 2 」を出力する */ void kyoku_2(void) { uta(); printf ( "背戸の小薮に 埋けましょか\n" ); ieie(); } /* * void kyoku_3(void) * 「歌詞 3 」を出力する */ void kyoku_3(void) { uta(); printf ( "柳の鞭で ぶちましょか\n" ); ieie(); } /* * void kyoku_4(void) * 「歌詞 4 」を出力する */ void kyoku_4(void) { uta(); printf ( "象牙の船に 銀の櫂\n" ); printf ( "月夜の海に 浮べれば\n" ); printf ( "忘れた唄を おもいだす\n" ); } /* * int main ( void ) * 四つの歌詞を、間に空行を入れて出力する */ int main ( void ) { kyoku_1(); /* 一曲目 */ printf ( "\n" ); /* 空行 */ kyoku_2(); /* ニ曲目 */ printf ( "\n" ); /* 空行 */ kyoku_3(); /* 三曲目 */ printf ( "\n" ); /* 空行 */ kyoku_4(); /* 四曲目 */ return 0; }
$ ./sample-004.exe 唄を忘れた 金糸雀(かなりや)は 後の山に 棄てましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 背戸の小薮に 埋けましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 柳の鞭で ぶちましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 象牙の船に 銀の櫂 月夜の海に 浮べれば 忘れた唄を おもいだす $
Download : sample-005.c
/* * 2018/05/18 sample-005.c */ #include <stdio.h> /* * 「金糸雀(かなりや)」 * (c) 西條八十作詞・成田為三作曲 * http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/kanariya.html */ /* * 1 〜 3 を引数付き関数でおきかえる */ /* * void uta(void) * 「唄を忘れた 金糸雀(かなりや)は」を出力する */ void uta(void) { printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); } /* * void ieie(void) * 「いえ いえ それはなりませぬ」を出力する */ void ieie(void) { printf ( "いえ いえ それはなりませぬ\n" ); } /* * void kyoku_123 ( char *center ) * char *center ; 曲 1 〜 3 で異る部分 * 曲 1 〜 3 で異る部分を引数にする事により、歌詞全体を出力する */ void kyoku_123 ( char *center ) { uta(); printf ( center ); /* kyoku 1 〜 3 で異る部分を変数 (center) にした */ ieie(); } /* * void kyoku_1(void) * 「歌詞 1 」を出力する * kyoku_123 を利用して、歌詞 1 固有の部分だけを指定する */ void kyoku_1(void) { kyoku_123 ( "後の山に 棄てましょか\n" ); } /* * void kyoku_2(void) * kyoku_123 を利用して、歌詞 2 を出力 */ void kyoku_2(void) { kyoku_123 ( "背戸の小薮に 埋けましょか\n" ); } /* * void kyoku_3(void) * kyoku_123 を利用して、歌詞 3 を出力 */ void kyoku_3(void) { kyoku_123 ( "柳の鞭で ぶちましょか\n" ); } /* * void kyoku_4(void) * 「歌詞 4 」を出力する * 形が 1 〜 3 と異るので、kyoku_123 は使えない */ void kyoku_4(void) { uta(); printf ( "象牙の船に 銀の櫂\n" ); printf ( "月夜の海に 浮べれば\n" ); printf ( "忘れた唄を おもいだす\n" ); } /* * int main ( void ) * 四つの歌詞を、間に空行を入れて出力する */ int main ( void ) { kyoku_1(); /* 一曲目 */ printf ( "\n" ); /* 空行 */ kyoku_2(); /* ニ曲目 */ printf ( "\n" ); /* 空行 */ kyoku_3(); /* 三曲目 */ printf ( "\n" ); /* 空行 */ kyoku_4(); /* 四曲目 */ return 0; }
$ ./sample-005.exe 唄を忘れた 金糸雀(かなりや)は 後の山に 棄てましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 背戸の小薮に 埋けましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 柳の鞭で ぶちましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 象牙の船に 銀の櫂 月夜の海に 浮べれば 忘れた唄を おもいだす $
Download : sample-006.c
/* * 2018/05/18 sample-006.c */ #include <stdio.h> #include <string.h> /* strcmp を利用する場合は必要 */ /* * 「金糸雀(かなりや)」 * (c) 西條八十作詞・成田為三作曲 * http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/kanariya.html */ /* * 4 の場合もまとめられないだろうか ? */ /* * void uta(void) * 「唄を忘れた 金糸雀(かなりや)は」を出力する */ void uta(void) { printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); } /* * void ieie(void) * 「いえ いえ それはなりませぬ」を出力する */ void ieie(void) { printf ( "いえ いえ それはなりませぬ\n" ); } /* * void kyoku_1234 ( char *center ) * char *center ; 曲 1 〜 4 で最初に異る部分 * 曲 1 〜 3 は異る部分を、定型で、出力する事により * 曲 4 は、if と strcmp を利用して、区別し、特別扱いする事により * それぞれ、歌詞全体を出力する */ void kyoku_1234 ( char *center ) { /* 1 〜 4 共通部分 */ uta(); printf ( center ); /* 1 〜 3 と 4 では異る部分 */ /* strcmp で、比較し、その結果を if で区別する */ if ( !strcmp ( center, "象牙の船に 銀の櫂\n" ) ) { /* 4 の場合だった */ printf ( "月夜の海に 浮べれば\n" ); printf ( "忘れた唄を おもいだす\n" ); } else { /* それ以外.. */ /* 1 〜 3 の場合だった */ ieie(); } } /* * void kyoku_1(void) * kyoku_1234 を利用して、歌詞 1 を出力 */ void kyoku_1(void) { kyoku_1234 ( "後の山に 棄てましょか\n" ); } /* * void kyoku_2(void) * kyoku_1234 を利用して、歌詞 2 を出力 */ void kyoku_2(void) { kyoku_1234 ( "背戸の小薮に 埋けましょか\n" ); } /* * void kyoku_3(void) * kyoku_1234 を利用して、歌詞 3 を出力 */ void kyoku_3(void) { kyoku_1234 ( "柳の鞭で ぶちましょか\n" ); } /* * void kyoku_4(void) * kyoku_1234 を利用して、歌詞 4 を出力 */ void kyoku_4(void) { kyoku_1234 ( "象牙の船に 銀の櫂\n" ); } /* * int main ( void ) * 四つの歌詞を、間に空行を入れて出力する */ int main ( void ) { kyoku_1(); /* 一曲目 */ printf ( "\n" ); /* 空行 */ kyoku_2(); /* ニ曲目 */ printf ( "\n" ); /* 空行 */ kyoku_3(); /* 三曲目 */ printf ( "\n" ); /* 空行 */ kyoku_4(); /* 四曲目 */ return 0; }
$ ./sample-006.exe 唄を忘れた 金糸雀(かなりや)は 後の山に 棄てましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 背戸の小薮に 埋けましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 柳の鞭で ぶちましょか いえ いえ それはなりませぬ 唄を忘れた 金糸雀(かなりや)は 象牙の船に 銀の櫂 月夜の海に 浮べれば 忘れた唄を おもいだす $
Download : sample-007.c
/* * 2018/05/18 sample-007.c */ #include <stdio.h> #include <string.h> /* * 木霊 */ /* * 引数を利用して振舞をかえる関数の例 */ /* * void echo ( char *message ) * char *message 与えらえたメッセージ、これをそのまま言い返す(木霊) * message が空の場合は、「言い返せない」と文句を言う */ void echo ( char *message ) { /* message の内容によって振舞を変える */ /* 「""」は「空文字列」を表す */ if ( !strcmp ( message, "" ) ) { /* もし、メッセージが空っぽならば.. */ printf ( "何か言わないと、言い返せないじゃないか.." ); } else { /* そうじゃなければ、そのまま答える */ printf ( message ); } } /* * void chat ( char *message ) * char *message 木霊に呼び掛けるメッセージ * こちらからの呼び掛けと、木霊の返答を表示する */ void chat ( char *message ) { printf ( "呼掛け : " ); printf ( message ); printf ( "\n" ); /* 呼掛けの言葉 */ printf ( "木霊 : " ); echo ( message ); printf ( "\n" ); /* 木霊の応答 */ } /* * main */ int main ( void ) { chat ( "ヤッホー" ); chat ( "オーイ" ); chat ( "" ); chat ( "生意気なやつだ" ); return 0; }
$ ./sample-007.exe 呼掛け : ヤッホー 木霊 : ヤッホー 呼掛け : オーイ 木霊 : オーイ 呼掛け : 木霊 : 何か言わないと、言い返せないじゃないか.. 呼掛け : 生意気なやつだ 木霊 : 生意気なやつだ $
Download : sample-008.c
/* * 2018/05/18 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
/* * 2018/05/18 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
/* * 2018/05/18 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
/* * 2018/05/18 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 : ******** $
#include <stdio.h> /* * メッセージを出力する関数 * 「メッセージ」の形出力 * 「」の中のメッセージは後から決めたい */ /* 引数付き関数の作り方と使い方 [作り方] 1) ふつうに引数なしの関数を作る 2) 命令の一部を変数に置き換える 変数の現れる部分は、あとから変更したい部分 3) 関数の頭の()の中に、その変数名を(複数ある場合は「,」で区切って) 並べる。 ! 引数が 0 個の時は、空っぽにせず void する 4) ここの変数の前にそれぞれ 「char *」を付ける [使い方] 5) 関数呼び出しの後ろの()の中に、変数に入ってほしい 値を入れる 複数ある場合は、「,」で区切る 頭から順に対応した変数に対応した値が入る */ void print_kakko ( char *message ) { printf ( "「" ); printf ( message ); /* メッセージ部分:後から決める => 変数(message)を出力 */ /* => 変数 message の値を決める => 引数で決める */ /* printf ( "Hello, World" ); => 「Hello, World」と出力 */ printf ( "」\n" ); } int main(void) { print_kakko( "Hello, World" ); /* 関数呼び出しの後ろの () 中に値を指定すると、 => それが、関数内の変数の値として利用される */ /* => 「Hello, World」[改行] と表示される */ print_kakko( "こんにちは、みなさん" ); /* 1) 関数 print_kakko が呼び出されるので、26 行目の void print_kakko ( char *message ) が利用される 2) message <-> "こんにちは、みなさん" の対応をするとともに、関数の中身 printf ( "「" ); printf ( message ); printf ( "」\n" ); を実行しようとする 3) printf ( "「" ); printf ( "こんにちは、みなさん" ); printf ( "」\n" ); 4) 「こんにちは、みなさん」[改行] */ return 0; }
/* p-002.c : Makefile の機能を説明するためのダミー */ #include <stdio.h> int main(void) { printf ( "Hello, World\n" ); return 0; }
#include <stdio.h> /* 挨拶を返すプログラム [1] 相手が、「おはよう」ときたら、「おはよう」と出力 [2] 相手が、「こんにちは」ときたら、「こんにちは」と出力 [3] 相手が、「さようなら」ときたら、「ばいばい」と出力 するプログラム 考え方(設計) [1].[2] は、相手のいうことをオウム返しすればよい [3] だけ、ちょっと、他と違うので、特別扱い step 1 : [1],[2] の方が簡単なので、それを作る => 確かに、不十分だが、適切に動く事を確認 step 2 : [3] への対応を考える 「!strcmp( message, "さよなら" )」 変数 message の値が、「さよなら」の時に条件成立 if 構文 if ( 条件 ) { 条件が成立したときの命令 } else { 条件が不成立の時の命令 } */ void aisatasu(char *message) { if ( !strcmp( message, "さようなら" ) /* [3] なら : message が 「さよなら」の時 */ ) { /* [3] */ printf ( "ばいばい" ); printf ( "\n" ); } else { /* そうでない場合(は、きっと [1]. [2]...) */ /* [1], [2] */ printf ( message ); /* 相手の言う事をオーム返し */ printf ( "\n" ); /* 改行する */ } } int main(void) { aisatasu ( "おはよう" ); aisatasu ( "こんにちは" ); aisatasu ( "さようなら" ); return 0; }
前回の復習 引数付き関数 関数:プログラムの一部(命令列)に、名前をつけたもの 「命令列」は「固定」されている (これまで..)プログラムは作成したら、毎回同じ作業しかしない 作業の一部を、あと(プログラムのその部分書いた時の)から決められると便利 => 後で、その部分を変化させる事により、 同じ表現、異なる機能が実現できるから 引数付き関数の効用(よい点 / why ) 一つの記述で、複数の事が実現 v.s 記述のコピーと対比 機能 記述 元に誤りがあった場合 引数付き関数 複数 一つ 修正は一か所 コピーして書き換え 複数 複数 修正が多数 引数付き関数を作るべき 引数は複数指定する事ができる => 課題は、このパターン make と Makefile の話 1. 最悪知らなくてもよい (試験は解ける) 2. しっていると、ものすごく、効率がよくなる => 色々遊びに参加できる make (コマンド) とは (what) Makefile (後述) に記述されている make rule (作成方法) に従って、作業を自動化してくれる !! 作業の時の細かい情報を Makefile に記録すれば、 !! 作業の時に、その「細かい情報」を忘れられる !! => プログラム記述に専念できる [例] ソフトウェア概論の課題 : プログラム作成/コンパイル/実行 編集 : foobar.c を作る コンパイラ : cc -c foobar.c でコンパイルする リンク : cc -o foobar.exe foobar.o でリンク 実行 : ./foobar.exe で実行 => 編集以外の作業を Makefile に記述する事によって、 make だけで、実行できてしまう。 Makefile make が作業を行うためのレシピが記述されている 1) make rule 作品 : 材料で どのように作くるか を記述 foobar.exe : foobar.c cc -c foobar.c cc -o foobar.exe foobar.o foobar.exe を作るには foobar.c を材料に、 料理方法は、 cc -c foobar.c cc -o foobar.exe foobar.o をする。 2) マクロ定義とマクロ参照 [マクロ定義] 「マクロ名=文字列」 で、マクロを定義できる [例] NAME=foobar [マクロ参照] 「${マクロ名}」 で、マクロの値を参照できる [例] ${NAME} マクロを利用すると、 2-1) make rule を「汎用化」できる 2-2) マクロの値を後から設定する事により、 Makefile を転用できる [例] make NAME=p-002 => NAME=p-002 としたのと同じ結果 Makefile を作るときの注意 a) 料理方法の行の頭は[TAB]にする b) 料理方法の行(複数行)の最後は、「空行(改行だけの行)」 c) 保存するときには、拡張子を付けない 名前は Makefile でも makefile でも大丈夫 使い方 a) make : Makefile 通りに作成 b) make マクロ=値 : Makefile のマクロの値を差し替える [課題] 20180511-01-9999.c main 関数があり、関数 sub_20180511_01_9999() を呼ぶ この中には、関数 sub_20180511_01_9999()の定義がない 20180511-01-01-9999.c 関数 sub_20180511_01_9999()の定義がある main 関数はない この二つの .c ファイルは二つで一つのプログラムになる => 個々にコンパイルして (実行ファイルを作る) リンク時にまとめる。 [手順] cc -c 20180511-01-9999.c => 20180511-01-9999.o ができる cc -c 20180511-01-01-9999.c => 20180511-01-01-9999.o ができる cc -o 20180511-01-9999.exe 20180511-01-9999.o 20180511-01-01-9999.o => 実行ファイルを作るには二つのオブジェクト(.o)ファイルが必要 ./20180511-01-9999.exe => 一つまとまったら、実行方法は同じ 一つのプログラムを複数のソース(.c)ファイルに分けて、 それぞれ、コンパイルして、あとからまとめてリンクする方法 => 分割コンパイルと呼ぶ (why) .c を再利用する事が目的 => 詳しくは後日 <= 結果として、作業量が増える => make を利用する Makefile 提出する前に Makefile-20180511-9999.txt に名前を変更して、提出する == [条件分岐] 条件分岐とは、条件(変数の値)によって、異なる命令の どちらか一方を実行する仕組み cf. 順接: 異なる命令を、順に実行する仕組み ! 条件分岐も順接も、命令の組み合わせ方に関する「構文」 [例で説明する]
# # Makefile # p-001.exe のレシピ # p-001.exe : p-001.c cc -c p-001.c cc -o p-001.exe p-001.o
# # Makefile # ${NAME} のレシピ # # 「NAME」というマクロに「p-001」という値を設定 # 以下、${NAME} の部分は、「p-001」に置き換わる NAME=p-001 ${NAME}.exe : ${NAME}.c cc -c ${NAME}.c cc -o ${NAME}.exe ${NAME}.o
# # Makefile # ${NAME} のレシピ # # 「NAME」というマクロに「p-001」という値を設定 # 以下、${NAME} の部分は、「p-001」に置き換わる NAME=p-001 ${NAME}.exe : ${NAME}.c cc -c ${NAME}.c cc -o ${NAME}.exe ${NAME}.o # makefile には、実際にファイルを作らず、作業だけをさせる事もできる # レシピのところで、実際にファイルをつくらなければよい # => 作成対象は、「実行をするためのラベル」になる # [例] # a) プログラムの実行をしたい # b) 後始末 (作成したファイルを削除する) # # a) プログラムの実行 # test をするには、${NAME}.exe を作成し、そのあとに # ${NAME}.exe を実行する # !! make は、特に指定されないと、できるだけ Makefile の先頭 # !! rule を実行する # !! => もし、他の場所から始めたい場合は、make の引数に # !! に、そのターゲットを指定すればよい # !! [例] test をしたい場合は # !! make test # !! とすればよい test : ${NAME}.exe ./${NAME}.exe # b) 後始末 (作成したファイルを削除する) # ${NAME}.exe や ${NAME}.o は、作る事ができる # 普段はなくてもよいので、削除する # 利用方法 : make clean # !! rm は、「ファイルを削除する」コマンド clean : rm ${NAME}.exe ${NAME}.o
20180511-01
/* * 20180511-01-01-QQQQ.c * 分割コンパイルの sub */ #include <stdio.h> /* * sub_20180511_01_9999 */ void sub_20180511_01_9999 ( void ) { printf ( "これは、9999 番のサブルーチンです\n" ); /* 三か所ある 9999 を自分の番号にする */ }
/* * 20180511-01-QQQQ.c * 分割コンパイルの main */ #include <stdio.h> /* * main */ int main ( void ) { sub_20180511_01_9999(); /* サブルーチンを呼ぶ */ /* 自分の課題では、 9999 を学生番号に変更 */ return 0; }
# # Makefile-20180511-9999.txt # 分割コンパイルの Makefile # 20180511-01-9999.exe : 20180511-01-9999.o 20180511-01-01-9999.o cc -o 20180511-01-9999.exe 20180511-01-9999.o 20180511-01-01-9999.o 20180511-01-9999.o : 20180511-01-9999.c cc -c 20180511-01-9999.c 20180511-9999-01-01.o : 20180511-01-01-9999.c cc -c 20180511-01-01-9999.c clean: rm 20180511-01-9999.exe 20180511-01-9999.o 20180511-01-01-9999.o test: 20180511-01-9999.exe ./20180511-01-9999.exe
Download : 20180518-01.c
/* * 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 ( "」" ); } void iu ( char *message ) { kakko ( message ); printf ( "っていうと" ); /* ** この部分を完成させなさい */ } /* * main */ int main ( void ) { iu ( "遊ぼう" ); iu ( "馬鹿" ); iu ( "もう遊ばない" ); printf ( "そうして、あとでさみしくなって、\n" ); iu ( "ごめんね" ); printf ( "こだまでしょうか、いいえ、誰でも。\n" ); return 0; }
$ ./20180518-01-QQQQ.exe 「遊ぼう」っていうと「遊ぼう」っていう。 「馬鹿」っていうと「馬鹿」っていう。 「もう遊ばない」っていうと「遊ばない」っていう。 そうして、あとでさみしくなって、 「ごめんね」っていうと「ごめんね」っていう。 こだまでしょうか、いいえ、誰でも。 $
Download : 20180518-02.c
/* * 20180518-02-QQQQ.c * 底辺の長さが指定した文字列の二倍の長さ - 1 の横向のピラミッドを作成するプログラムを作成する */ #include <stdio.h> #include <strings.h> /* */ void down ( char *edge ) { if ( !strcmp ( edge, "" ) ) { /* なにもする必要はない */ } else { printf ( edge ); printf ( "\n" ); down ( edge + 1 ); } } void up ( char *edge ) { if ( !strcmp ( edge, "" ) ) { /* なにもする必要はない */ } else { up ( edge + 1 ); /* ** この部分を完成させなさい */ } } void pyramid ( char *edge ) { up ( edge + 1 ); printf ( edge ); printf ( "\n" ); /* ** この部分を完成させなさい */ } /* * main */ int main ( void ) { pyramid ( "*****" ); printf ( "\n" ); pyramid ( "**********" ); return 0; }
$ ./20180518-02-QQQQ.exe * ** *** **** ***** **** *** ** * * ** *** **** ***** ****** ******* ******** ********* ********** ********* ******** ******* ****** ***** **** *** ** * $