Download : sample-001.c
/* * 2020/05/15 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-006.c
/* * 2020/05/15 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
/* * 2020/05/15 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
/* * 2020/05/15 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
/* * 2020/05/15 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
/* * 2020/05/15 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
/* * 2020/05/15 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 : ******** $
/* キラキラ星 (英語版)の歌詞を出力する 20200508-02-9999.c */ #include <stdio.h> void twinkle(void) { printf ( "Twinkle, twinkle, little star,\n" ); printf ( "How I wonder what you are!\n" ); } int main(void) { twinkle(); printf ( "Up above the world so high,\n" ); printf ( "Like a diamond in the sky.\n" ); twinkle(); twinkle(); return 0; }
/* * 20200515-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 ( "っていうと" ); if ( !strcmp ( message, "もう遊ばない" ) ) { kakko ( "遊ばない" ); } else { kakko ( message ); } printf ( "っていう。\n" ); } /* * main */ int main ( void ) { iu ( "遊ぼう" ); /*「遊ぼう」っていうと「遊ぼう」っていう。 */ iu ( "馬鹿" ); /*「馬鹿」っていうと「馬鹿」っていう。*/ iu ( "もう遊ばない" ); printf ( "そうして、あとでさみしくなって、\n" ); iu ( "ごめんね" ); printf ( "こだまでしょうか、いいえ、誰でも。\n" ); return 0; } /* [出力] 「遊ぼう」っていうと「遊ぼう」っていう。 「馬鹿」っていうと「馬鹿」っていう。 「もう遊ばない」っていうと「遊ばない」っていう。 そうして、あとでさみしくなって、 「ごめんね」っていうと「ごめんね」っていう。 こだまでしょうか、いいえ、誰でも。 $ */
#include <stdio.h> void hello_world(void) { printf ( "Hello, World\n" ); } int main(void) { hello_world(); return 0; }
#include <stdio.h> void hello_world(void) { printf ( "Hello, World\n" ); } int main(void) { hello_world(); hello_world(); /* 二度目に関数を呼び出しても、同じ振舞をする */ hello_world(); hello_world(); hello_world(); return 0; }
#include <stdio.h> void hello_world(void) { printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); } int main(void) { hello_world(); /* 10 行表示 */ hello_world(); /* 上と同じことをする (10 行表示) */ return 0; }
#include <stdio.h> int main(void) { printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); printf ( "Hello, World\n" ); return 0; }
#include <stdio.h> void hello_world(void) { printf ( "Hello," ); printf ( "World" ); /* "World" を毎回変更したい */ printf ( "\n" ); } int main(void) { hello_world(); return 0; }
#include <stdio.h> void hello_world(char *X) { /* 2. 仮引数「()」の中に変数名を入れる */ /* 3. 変数名の前に 「char *」挿入 */ printf ( "Hello," ); printf ( X ); /* "World" を毎回変更したい */ /* 1. 「変更したい部分」を変数「X」に置き換え */ printf ( "\n" ); } int main(void) { hello_world( "World" ); /* 4. 実引数を指定する */ hello_world( "World" ); /* 同じ実引数を指定すれば、同じ結果 */ hello_world( "世界" ); /* 異なる実引数を指定すれば、違う結果 */ return 0; }
#include <stdio.h> void hello_world(char *X) { printf ( "Hello," ); printf ( X ); /* 変数は、何度でも参照可能 */ printf ( X ); /* 同じ変数は、同じ値を持つ */ printf ( "\n" ); } int main(void) { hello_world( "World" ); /* 4. 実引数を指定する */ hello_world( "World" ); /* 同じ実引数を指定すれば、同じ結果 */ hello_world( "世界" ); /* 異なる実引数を指定すれば、違う結果 */ return 0; }
#include <stdio.h> /* 引数が二つの関数 */ void hello_world(char *X, char *Y) { /* 変数が複数ある場合は、それぞれ名前つける */ /* 宣言も複数 ( 「,(カンマ)」で区切って並べて ) 記述する */ printf ( "Hello," ); printf ( X ); /* 変数は、何度でも参照可能 */ printf ( " & " ); printf ( Y ); /* 異なる変数は、異なる値を持つ */ printf ( "\n" ); } int main(void) { hello_world( "World", "世界" ); /* 仮引数の個数と同じだけ実引数を指定する */ hello_world( "トム", "ジェリー" ); hello_world( "ジェリー", "トム" ); /* 実引数(式)と仮引数(変数)の対応は、順番で対応する */ return 0; } /* makefile を作ったので、便利 */
#include <stdio.h> int main(void) { printf ( "abc" ); /* prinf 関数は、引数に「文字列」を指定すると、 */ /* その引数に指定された「文字列」を画面に出力する */ /* ここでは、文字列は「"abc"」で表現されていて */ /* これは、「a」、「b」、「c」の三文字からなる文字列 */ printf ( "日本語\n" ); /* 日本語文字の場合、文字列の(見かけ上の)長さと、 実際のバイト数は異なるので、直観に反する.. */ /* しばらくは、「文字列」と言ったら、「ASCII 文字列」 */ /* 「一文字」=「1 byte」な文字に制限して考える */ return 0; }
#include <stdio.h> int main(void) { printf ( "a\n\n\nb" ); /* a 改行が三つ b */ printf ( "\"\n" ); /* 「"」を出力する */ printf ( "abc\n" ); printf ( "\"abc\"\n" ); printf ( "\"\\\"\n" ); /* 「"\"」改行 */ printf ( "\"\\\" を表現するには、「\"\\\"\\\\\"\\\"」と書く\n" ); return 0; }
#include <stdio.h> int main(void) { printf ( "abc\n" ); /* a,b,c,\n の四文字文字列 */ printf ( "abc\n" + 1 ); /* 「"abc\n"」という文字列に、整数値「1」を加えた */ /* => 先頭の文字が一文字削れた文字列になる */ /* => 「"abc\n"+1」=「"bc\n"」 */ printf ( "abc\n" + 2 ); /* 「"abc\n"+2」=>「("abc\n" + 1) + 1」*/ /* => 「"bc\n" + 1」*/ /* => 「"c\n"」*/ printf ( "abc\n" + 3 ); /* => 「"\n"」*/ printf ( "abc\n" + 4 ); /* => 「""」(「空『文字列』」と呼ばれる) */ /* => 何も出ない */ return 0; }
#include <stdio.h> /* * 引数値をそのまま、利用 * => 引数の値を、printf に、そのまま渡している * 関数 hello_world の振る舞いは、 * X の変化に対して、同じように変化する */ void hello_world(char *X) { printf ( "Hello, " ); printf ( X ); /* 変数 X の値が、そのまま printf へ */ printf ( " & " ); printf ( X ); printf ( "\n" ); } int main(void) { hello_world( "World" ); hello_world( "a" ); hello_world( "b" ); hello_world( "c" ); return 0; }
#include <stdio.h> /* 引数 : "a", "b", "c", "d", "e" 振る舞い : "c" の時だけ "C" で、そのほかは、そのまま */ void hello_world(char *X) { printf ( "引数 : " ); printf ( X ); printf ( ", 結果 : " ); printf ( X ); printf ( "\n" ); /* hello_world ( "a" ) => 「引数 : a, 結果 : a」 */ } int main(void) { hello_world( "a" ); hello_world( "b" ); hello_world( "c" ); hello_world( "d" ); hello_world( "e" ); return 0; }
#include <stdio.h> /* 引数 : "a", "b", "c", "d", "e" 振る舞い : "c" の時だけ "C" で、そのほかは、そのまま */ void hello_world(char *X) { printf ( "引数 : " ); printf ( X ); printf ( ", 結果 : " ); /* ここで、X が "c" の時 "C" を、そうでないとき X を出す */ if ( !strcmp ( X, "c" ) ) { /* X が "c" の時 */ printf ( "C" ); /* <= X が "c" の時 */ } else { printf ( X ); /* <= X が "c" でない時 */ } printf ( "\n" ); /* hello_world ( "a" ) => 「引数 : a, 結果 : a」 */ /* hello_world ( "c" ) => 「引数 : c, 結果 : C」 */ } int main(void) { hello_world( "a" ); hello_world( "b" ); hello_world( "c" ); hello_world( "d" ); hello_world( "e" ); return 0; }
/* * 2020/05/08 sample-005.c */ #include <stdio.h> /* * 「金糸雀(かなりや)」 * (c) 西條八十作詞・成田為三作曲 * http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/kanariya.html */ void common_uta(char *X) { printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( X ); printf ( "いえ いえ それはなりませぬ\n" ); } void uta(void) { common_uta ( "後の山に 棄てましょか\n" ); } void uta2(void) { common_uta ( "背戸の小薮に 埋けましょか\n" ); } int main ( void ) { uta(); printf ( "\n" ); uta2(); printf ( "\n" ); printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "柳の鞭で ぶちましょか\n" ); printf ( "いえ いえ それはかわいそう\n" ); printf ( "\n" ); printf ( "唄を忘れた 金糸雀(かなりや)は\n" ); printf ( "象牙の船に 銀の櫂\n" ); printf ( "月夜の海に 浮べれば\n" ); printf ( "忘れた唄を おもいだす\n" ); return 0; }
abc
前回(2020/05/08)の内容 引数無し 命令列(固定)に名前つけたもの 名前を指定して、命令列実行できる 「『同じ名前』を指定すれば、『同じ命令』が実行される」事が保証される 引数付き関数 関数の内部の「変化する部分」を、「仮変数」で表す。 「変数」の「値(実際に実行する時に定まる値)」は、関数の実引数に指定する 引数付き関数は、関数の振舞いを「後」から決められる。 「後」; プログラムの実行時(関数の呼び出し)で定まる 「前(今)」:プログラムの作成(関数の定義だけ)時で定まる 引数付き関数の振る舞いは、実引数の値(関数呼び出し)で確定する 引数付き関数 汎用的になっている 同じような(にた)プログラム(関数)を複数つくらなくてもよい 再利用(効率化) 抽象的になっている 具体的なものに対して、「一部が決まっていない」 抽象化をすると、理解しやすくなる場合がある 「理解しやすい」というのは、「自分に取り入れやすい」 引数付き関数の引数の個数 複数指定できる それぞれ、別々の名前をつけて、別々に宣言 実引数も、仮引数と同じ個数指定する 実引数の値と仮引数の変数の対応は、順番で決まる == make と makefile make : 色々なコマンドを実行してくれる ファイルを「作る(make)」コマンド コマンド : cc もコマンド ( ./実行ファイル ), ls ubuntu に対して、「何をしろ」という命令 makefile make が参照するレシピ ファイルの作り方が書いてある make は makefile に従って「作る」 makefile の形式 makefile の中に、作成規則をたくさん書ける 作成規則(複数) 作りたいもの : 材料 作る命令列 make を実行すると.. 先頭の作成規則を適用しようとする ただし、その作成規則の命令の前に、 その規則の材料に対する作成規則も適用する 作りたいもの(ターゲット)と材料の作成時間を比較し、 ターゲットの方が古い場合だけ、作くる命令を実行する そうでなければ、実行しない ダミーターゲット 生成規則の中で、コマンドを実行してもターゲットが作られない物がある => ものを作るためには、使えない <= 命令列に名前をつけて、その名前で命令が実行できる make ターゲット名 と make を実行する場合に、「ターゲット名」を指定すると、 その「ターゲット名」に対応した生成規則を適用しようとする 演習 引数付き関数を作る [2020/05/15] C 言語における「文字列」 二つの「" (ダブルクォーテーション)」で挟んだ「『文字』の列」 例: 「"abc"」は、三つの文字 「a」, 「b」, 「c」から成る、長さ 3 の文字列 C 言語における「文字」 : 「(ASCII) 文字」 基本は、キーボードから「1 キー」で入力されて、画面に表示される「モノ」 aAb123 $% キーボードで「a」を入力すると、画面に「a」と入る (これが『文字』) ASCII Code 表 ( 1 byte で表現可能な「文字」表 ) 「"abc"」は、3 つの文字からなるので、3 byte のサイズ C 言語における「文字」は、 ASCII Code 表の 1 byte で表現できる「モノ」 「日本語文字」は、1 byte で表現できない ( ASCII Code 表にない ) 「日本語文字列」は扱えるが、今は説明しない (UTF-8 にする事だけ注意) キーボードに表記されていない文字の表現 キーボード上で表現されていない「文字」がある (キーボードは 256 もない) ASCII Code 表は、 1 byte = 8bit = 2^8 = 256 だけある # ASCII 7bit -> 128 通り C 言語で、表示できない文字表現する表現方法 => エスケープシーケンス エスケープシーケンスを利用して、色々な「文字」を表現する C 言語におけるエスケープ文字 「\ (バックスラッシュ)」が利用される (ubuntu : UTF-8 ) windows では「¥(エンマーク)」になる (Windows : JIS X 0201 ) TeX の時も、同じ話をした... # 日本の環境では、「\」マークがエスケープコードになる # 海外の環境は、バックスラッシュがエスケープコードになる # => 実は、コンピュータの内部では、円マークとバックスラッシュは同じもの # 表示するときに、円マークにするかバックスラッシュにするかが違う エスケープシーケンス エスケープ文字(「\」) + 「文字列」で、一つの「文字」を表現 複数の文字からなる文字列で、一つの文字を表現する その複数の文字からなる文字列の開始文字がエスケープ文字 n => 普通の文字「n」を表す表現 \n => 「\(エスケープ文字)」から始まっているので、 エスケープシーケンスになる => 「改行」の位置文字を表す エスケープシーケンスの例 \n 「改行コード」(改行を表す文字) \\ 「\(バックスラッシュ)」 そのもの \" 「" 」を表す => 文字列の中で「"」を表す場合。 「文字列」の計算 「文字列」に、正の整数値を加える事ができる +1 の結果は、「先頭の文字」が失われて、 1 文字短くなった「文字列」になる 例 : "abc" + 1 -> "bc" 空文字列 長さ 0 の文字列 (「""」で表現可能) !! 空文字列に +1 すると何がおきるか ? !! => なにがおきるかわからない !! => 最悪の場合は、コンピュータの振る舞いがおかしくなる 「文字列」の比較 (条件式) 表現 「!strcmp ( 文字列1, 文字列2 )」で、 「文字列比較」が可能 「文字列1」と「文字列2」が「同じ」ならば「真」になる そうでなければ、「偽」になる 空文字列「""」と比較する事で、 「!strcmp("",文字列)」と、「文字列」の長さが 0 の時、真になる 文字列の「長さが 0 かどうか」が解る 条件分岐 引数の内容によって振舞いを「大幅」に変更したい これまでの、引数付き関数の場合は、 引数の変化と、関数の振る舞いの変化は、「対応」している # 連続な振る舞いをしているようにみえる <= 引数が連続的に与えられても、 動作が、不連続な場合を考えたい。 例: 引数 : "a", "b", "c", "d", "e" 振る舞い : "c" の時だけ "C" で、そのほかは、そのまま if 文と strcmp 関数を利用して対応できる strcmp 関数 : 二つの文字列を比較する if ( !strcmp ( A, B ) ) { X } else { Y } A と B が同じなら X を、 そうでなければ Y を行う 「else if」を使うと更に複数の命令が選べる if ( C1 ) { P1 } else if ( C2 ) { P2 } .. else { Pn } C1 の時 P1、そうでなく C2 の時は P2 .. いずれでもないと Pn おまじない ( strcmp を利用する場合に使う ) #include <string.h> strncmp ( A, B, N ); A と B の先頭の N 文字だけを比較する !strncmp ( "abc", "abz", 3 ); : 等しくない !strncmp ( "abc", "abz", 2 ); : 等しい
# # Makefile の中で「#」はコメント # 「コメント」: 人間に取ってだけ意味がある(コンピュータには無視される) # 備忘録(人間が自分の理解や記憶[説明]のために使う) # # Makefile の中身 # # 作りたいファイル(ターゲット) : 材料の並び # <TAB> 実行するコマンド # <TAB> 実行するコマンド.. # # 20200508-02-9999.exe # 作りたいファイル : 20200508-02-9999.exe # 材料となるファイル : 20200508-02-9999.o # 作り方(作るための命令) : cc -o 20200508-02-9999.exe 20200508-02-9999.o 20200508-02-9999.exe : 20200508-02-9999.o cc -o 20200508-02-9999.exe 20200508-02-9999.o # echo 20200508-02-9999.exe を作りました。 # 20200508-02-9999.o # 作りたいファイル : 20200508-02-9999.o # 材料となるファイル : 20200508-02-9999.c # 作り方(作るための命令) : cc -c 20200508-02-9999.c 20200508-02-9999.o : 20200508-02-9999.c cc -c 20200508-02-9999.c # # 命令を実行しても、ファイルを作らない場合もある # ダミーターゲット(命令を実行しても、ファイルができない) # => 命令に名前が付けられる # この例では、「test」がダミーターゲット # test は、プログラムを実行し、確認する命令 # test : 20200508-02-9999.exe ./20200508-02-9999.exe
# # Makefile の中で「#」はコメント # 「コメント」: 人間に取ってだけ意味がある(コンピュータには無視される) # 備忘録(人間が自分の理解や記憶[説明]のために使う) # # Makefile の中身 # # 作りたいファイル(ターゲット) : 材料の並び # <TAB> 実行するコマンド # <TAB> 実行するコマンド.. # # p-008.exe # 作りたいファイル : p-008.exe # 材料となるファイル : p-008.o # 作り方(作るための命令) : cc -o p-008.exe p-008.o p-008.exe : p-008.o cc -o p-008.exe p-008.o echo p-008.exe を作りました。 # p-008.o # 作りたいファイル : p-008.o # 材料となるファイル : p-008.c # 作り方(作るための命令) : cc -c p-008.c p-008.o : p-008.c cc -c p-008.c # # 命令を実行しても、ファイルを作らない場合もある # ダミーターゲット(命令を実行しても、ファイルができない) # => 命令に名前が付けられる # この例では、「test」がダミーターゲット # test は、プログラムを実行し、確認する命令 # test : p-008.exe ./p-008.exe
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20200515-01.c
/* * 20200515-01-QQQQ.c * */ #include <stdio.h> #include <string.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; }
$ ./20200515-01-QQQQ.exe 「遊ぼう」っていうと「遊ぼう」っていう。 「馬鹿」っていうと「馬鹿」っていう。 「もう遊ばない」っていうと「遊ばない」っていう。 そうして、あとでさみしくなって、 「ごめんね」っていうと「ごめんね」っていう。 こだまでしょうか、いいえ、誰でも。 $
Download : 20200515-02.c
/* * 20200515-02-QQQQ.c * 底辺の長さが指定した文字列の二倍の長さ - 1 の横向のピラミッドを作成するプログラムを作成する */ #include <stdio.h> #include <string.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; }
$ ./20200515-02-QQQQ.exe * ** *** **** ***** **** *** ** * * ** *** **** ***** ****** ******* ******** ********* ********** ********* ******** ******* ****** ***** **** *** ** * $