Download : sample-001.c
/* * 2017/06/02 sample-001.c */ /* * コマンドライン引数 */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { /* main 関数の引数が変化 */ /* main 関数の引数は、どちらでも良い 「引数を宣言」する事により、「利用が可能」になる */ /* このプログラムを実行する場合は ./sample-001.c.exe abc の様に、コマンド引数を指定する必要がある コマンドラインを指定しなかったりすると、 エラー (core dumped) になったりする。 */ printf ( "一つ目のコマンドライン引数は「" ); printf ( argv[1] ); printf ( "」でした。\n" ); return 0; }
$ ./sample-001.exe abc 一つ目のコマンドライン引数は「abc」でした。 $
Download : sample-002.c
/* * 2017/06/02 sample-002.c */ /* * コマンドライン引数 (2) */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { /* main 関数の引数が変化 */ /* このプログラムを実行する場合は ./sample-002.c.exe abc 123 zzzzz の様に、コマンド引数を 2 つ以上、指定する必要がある */ printf ( "プログラムファイル名は「" ); printf ( argv[0] ); /* argv[0] はプログラムファイル名 */ printf ( "」でした。\n" ); printf ( "一つ目のコマンドライン引数は「" ); printf ( argv[1] ); printf ( "」でした。\n" ); printf ( "二つ目のコマンドライン引数は「" ); printf ( argv[2] ); printf ( "」でした。\n" ); return 0; }
$ ./sample-002.exe abc 123 zzzz プログラムファイル名は「./sample-002.exe」でした。 一つ目のコマンドライン引数は「abc」でした。 二つ目のコマンドライン引数は「123」でした。 $
Download : sample-003.c
/* * 2017/06/02 sample-003.c */ /* * 再起の利用 */ #include <stdio.h> /* * triangle ( N ) -- サイズ N の三角を作る */ void triangle ( char *N ) { if ( !strcmp ( N, "" ) ) { /* サイズ 0 の時 */ /* 何もしない */ } else { /* サイズが一般の N の時 */ triangle ( N + 1 ); /* 文字列は 1 を加えると短かくなる */ /* 再起呼び出し */ printf ( N ); /* N を表示 */ printf ( "\n" ); /* 改行 */ } } /* * main 関数 */ int main ( void ) { /* main 関数の引数を利用しないので */ triangle ( "***" ); /* サイズ 3 の三角 */ printf ( "---\n" ); /* 仕切り */ triangle ( "1234567" ); /* サイズ 7 の三角 */ return 0; }
$ ./sample-003.exe * ** *** --- 7 67 567 4567 34567 234567 1234567 $
/* * 20170602-01-QQQQ.c * 高さ3 のハノイの塔を手動で解く */ #include <stdio.h> /* * ハノイプログラムには、s_hanoi.h が必要 */ #include "s_hanoi.h" /* * ハノイの塔 プログラム */ int main ( void ) { /* * 最初は "1" に全ての円盤が置いてある * これを "2" に全ての円盤を移動する */ /* * ハノイで、できること * s_hanoi_init() : ハノイプログラムの開始 : 最初に一度だけ呼び出す * s_hanoi_size ( char *discs ) : ハノイの塔の高さを設定する * s_hanoi_move ( char *from, char *to ) : from にある円盤を to に移す * s_hanoi_clear () : 最初の状態に戻す * s_hanoi_stop() : ハノイ塔プログラムの終了 : return 0 の前に呼び出す */ s_hanoi_init(); /* ハノイの塔のプログラムの初期変化 */ /* s_hanoi_set ( char *discs ) を呼ばなければ、高さは 3 */ printf ( "これから解答を開始します。[Enter] キーを押してください\n" ); putchar ( '>' ); putchar ( getchar() ); /* 開始前に、一旦停止 */ /* 解答開始 */ /* 高さが、具体的な小さい数(3)で指定されているので、 解答手順を実際に書き下すだけ */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 1 の)円盤を移動 */ s_hanoi_move ( "1", "3" ); /* 1 から 3 に、(大きさ 2 の)円盤を移動 */ s_hanoi_move ( "2", "3" ); /* 1 から 3 に、(大きさ 2 の)円盤を移動 */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 3 の)円盤を移動 */ s_hanoi_move ( "3", "1" ); /* 3 から 1 に、(大きさ 1 の)円盤を移動 */ s_hanoi_move ( "?", "?" ); /* ? から ? に、(大きさ 2 の)円盤を移動 */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 1 の)円盤を移動 */ /* 解答終了 */ printf ( "プログラムを終了するには [Enter] キーを押してください\n" ); putchar ( '>' ); /* 終了前に確認 */ putchar ( getchar() ); /* ハノイの終了 */ s_hanoi_stop(); return 0; }
/* * DATE-02-QQQQ.c * コマンドライン引数で指定した長さのハノイの塔を解く */ #include <stdio.h> #include <stdlib.h> /* exit を利用するために必要 */ /* * ハノイプログラムには、s_hanoi.h が必要 */ #include "s_hanoi.h" /* * hanoi ( char *f, char *t, char *w, char *size ) * 高さ size のハノイの塔を、 * f で表されている棒から * t で表されている棒へ * w で表されている棒を * 作業領域として利用して移動する * w は空っぽか、size より大きな円盤しかない */ void hanoi ( char *f, char *t, char *w, char *size ) { if ( !strcmp ( size, "" ) ) { /* 空っぽだったら*/ /* する事はない */ } else { /* まだ仕事があるなら */ /* やりたい事は、 「size の大きさの塔を f から t に動かしたい」事 そのためには、最終的に、size の大きさの円盤を動かす必要がある。 そのためには、 size の大きさの上の塔を t を利用して、一旦、f から w に移し size の大きさ円盤を f から t に移し size の大きさの上の塔を f を利用して、w から、t に動かせば良い */ /* f の所にある size の円盤の上の塔を w に移動して退かす (再帰呼出し) */ hanoi ( f, w, t, size + 1 ); /* f の所にある size の円盤を t に移動 */ s_hanoi_move ( f, t ); /* サイズ size の円盤(1 枚)を f から t に移動 */ /* size の円盤の上に w に退かした塔を載せる (再帰呼出し) */ hanoi ( ?, ?, ?, size + 1 ); /* ? の処には、f, w, t が一度ずつ現れる */ } } /* * ハノイの塔 プログラム */ int main ( int argc, char *argv[] ) { /* コマンドライン引数を用いるので、 int main ( int argc, char *argv[] ) と、main 関数の引数を宣言する。 */ if ( argc < 1 ) { /* 引数が指定されていない */ printf ( "ハノイの塔の高さを指定する文字列を指定してください\n" ); /* エラーメッセージの出力 */ exit ( -1 ); /* エラーコード : -1 でプログラム終了 */ /* main 関数内であれば return -1; でも可 */ } /* else {} */ /* 「else {}」は省略可 */ /* * 最初は "1" に全ての円盤が置いてある * これを "2" に全ての円盤を移動する */ /* * ハノイで、できること * s_hanoi_init() : ハノイプログラムの開始 : 最初に一度だけ呼び出す * s_hanoi_size ( char *discs ) : ハノイの塔の高さを設定する * s_hanoi_move ( char *from, char *to ) : from にある円盤を to に移す * s_hanoi_clear () : 最初の状態に戻す * s_hanoi_stop() : ハノイ塔プログラムの終了 : return 0 の前に呼び出す */ s_hanoi_init(); /* ハノイの塔のプログラムの初期変化 */ /* コマンドライン引数の一つ目 (argv[1]) で、問題の高さを初期化 */ /* s_hanoi_size を呼び出す */ s_hanoi_size ( argv[1] ); /* 引数で指定した文字列の長さの塔ができる */ printf ( "これから解答を開始します。[Enter] キーを押してください\n" ); putchar ( '>' ); putchar ( getchar() ); /* 開始前に、一旦停止 */ /* 解答開始 */ hanoi ( "1", "2", "3", argv[1] ); /* 解答終了 */ printf ( "プログラムを終了するには [Enter] キーを押してください\n" ); putchar ( '>' ); /* 終了前に確認 */ putchar ( getchar() ); s_hanoi_stop(); return 0; }
#include <stdio.h> int main(void) { putchar ( getchar() ); putchar ( '\n' ); /* 改行 */ /* getchar() で、キーボードから一文字入力し、 それを putchar() で出力する -> キーボードから入力した文字がそのまま画面に表示される */ return 0; }
#include <stdio.h> int main(void) { putchar ( getchar() + 32 ); putchar ( '\n' ); /* 改行 */ /* getchar() で、キーボードから一文字入力し、 それを putchar() で出力する -> キーボードから入力した文字がそのまま画面に表示される */ return 0; }
#include <stdio.h> int main(void) { putchar ( 'A' ); /* 「A」という「文字」を出力する */ putchar ( 65 ); /* 「65」という「数値」を指定すると、 その数値に(ASCII Code 表で)対応した文字 「A」という「文字」を出力する */ /* 要するに、'A' と 65 は C 言語の世界では (ほとんど)区別されない */ putchar ( '\n' ); /* 改行 */ return 0; }
#include <stdio.h> /* void printLower ( char *string ) 引数で指定されている大文字列を、すべて小文字にしてプリントする */ void printLower ( char *string ) { if ( *string == '\0' ) { /* する事はなにもない */ } else { /* 先頭の文字だけ処理する : 先頭の文字を小文字にして出力 */ putchar ( *string +32 ); /* 先頭の文字(コード)を取り出し、 大文字に対応するコードなら、 小文字に対応するコードにする */ /* 残りの部分は、再帰呼出しで OK */ printLower ( string + 1); } } int main(void) { printLower ( "ABC" ); putchar ( '\n' ); printLower ( "OPQRSTU" ); putchar ( '\n' ); return 0; }
先週の内容 文字列と文字の関係 文字 : 'A' 「A」という文字(1文字)を表す(C 言語の表現) # 実は、C 言語に於ける「文字」は、小さな整数値(文字コード) # 「文字」と「文字コード」の関係は、ASCII 表を参照 コンピュータの中では、全ての情報は「数値」 実際に扱える情報は、「数値」以外(音声、画像、Yes/No, etc..)もある 何故、数値しか利用できないコンピュータで、様々な形の情報が扱えるか ? Coding されているから Coding : あるルールで、対応付けする事 例 : ASCII Code : 文字と数値の対応 コンピュータ<-Coding->現実 'A'=65 A +32 | 大文字を小文字に変関する(情報処理) (計算) v 'a'=97 a 文字の出力は putchar(C); C で指定した「文字」を出力 文字の入力は getchar(); 文字列 "ABC" : 「A」、「B」、「C」の三つの文字からなる文字の列 "ABC" '=, { 'A', 'B', 'C', '\0' } '\0' : (数値としては 0) で、文字列最後に必ずあるので、 End Of String ( EOS ) と呼ぶ ( 「NULL 文字」と呼ぶ人も居る ) "" (空文字) '=, { '\0' } "ABC" '=, { 'A', 'B', 'C', '\0' } *"ABC" -> 'A' : 先頭に * を付けると、先頭の文字になる "ABC" | +--- 'A' : *"ABC" | +--- "BC" : "ABC" + 1 | +--- 'B' | +--- "C" | +--- 'C' | +--- "" | +--- '\0' *"ABC" -> 先頭の文字 *("ABC"+0) -> 先頭の文字 ( 0 番目 ) *("ABC"+1) -> *("BC") -> 'B' -> 次の文字 ( 1 番目 ) *("ABC"+2) -> *(("ABC"+1)+1) -> *("BC"+1) -> *"C" -> 'C' -> 2 番目 *(文字列 + k) -> 「k 」番目 -> 文字列[k] と書くもできる # 'A' + 1 -> 'B' (ASCII Code 表によって整数値になっている) 様々な「再帰呼び出し」をしてみよう -> 文字列の再帰性に着目すると、文字列の処理は、再帰呼出しで実現すると簡単 文字列 : 1) "" 空文字列は、文字列 2) C 文字で、S が文字列なら S の前に C を追加したものも文字列 "ABC" -> 'A' @ "BC" # "ABC" が文字列かどうかを判定するために "BC" が文字列である事を利用する 3) 1), 2) だけが文字列 <参考> ペアノの公理(自然数の定義) 1) 0 は自然数 2) n が自然数ならば n + 1 も自然数 # n+1 が自然数かどうかを n が自然数かどうかで判断 3) 1), 2) だけが自然数 # この自然数の定義から数学的帰納法が導かれる # -> それを C 言語で処理する表現が再帰呼出し
Download : 20170602-01.c
/* * 20170602-01-QQQQ.c * 高さ3 のハノイの塔を手動で解く */ #include <stdio.h> /* * ハノイプログラムには、s_hanoi.h が必要 */ #include "s_hanoi.h" /* * ハノイの塔 プログラム */ int main ( void ) { /* * 最初は "1" に全ての円盤が置いてある * これを "2" に全ての円盤を移動する */ /* * ハノイで、できること * s_hanoi_init() : ハノイプログラムの開始 : 最初に一度だけ呼び出す * s_hanoi_size ( char *discs ) : ハノイの塔の高さを設定する * s_hanoi_move ( char *from, char *to ) : from にある円盤を to に移す * s_hanoi_clear () : 最初の状態に戻す * s_hanoi_stop() : ハノイ塔プログラムの終了 : return 0 の前に呼び出す */ s_hanoi_init(); /* ハノイの塔のプログラムの初期変化 */ /* s_hanoi_set ( char *discs ) を呼ばなければ、高さは 3 */ printf ( "これから解答を開始します。[Enter] キーを押してください\n" ); putchar ( '>' ); putchar ( getchar() ); /* 開始前に、一旦停止 */ /* 解答開始 */ /* 高さが、具体的な小さい数(3)で指定されているので、 解答手順を実際に書き下すだけ */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 1 の)円盤を移動 */ s_hanoi_move ( "1", "3" ); /* 1 から 3 に、(大きさ 2 の)円盤を移動 */ /* ** この部分を完成させなさい */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 3 の)円盤を移動 */ s_hanoi_move ( "3", "1" ); /* 3 から 1 に、(大きさ 1 の)円盤を移動 */ /* ** この部分を完成させなさい */ s_hanoi_move ( "1", "2" ); /* 1 から 2 に、(大きさ 1 の)円盤を移動 */ /* 解答終了 */ printf ( "プログラムを終了するには [Enter] キーを押してください\n" ); putchar ( '>' ); /* 終了前に確認 */ putchar ( getchar() ); /* ハノイの終了 */ s_hanoi_stop(); return 0; }
$ ./20170602-01-QQQQ.exe これから解答を開始します。[Enter] キーを押してください > プログラムを終了するには [Enter] キーを押してください > $
Download : 20170602-02.c
/* * DATE-02-QQQQ.c * コマンドライン引数で指定した長さのハノイの塔を解く */ #include <stdio.h> #include <stdlib.h> /* exit を利用するために必要 */ /* * ハノイプログラムには、s_hanoi.h が必要 */ #include "s_hanoi.h" /* * hanoi ( char *f, char *t, char *w, char *size ) * 高さ size のハノイの塔を、 * f で表されている棒から * t で表されている棒へ * w で表されている棒を * 作業領域として利用して移動する * w は空っぽか、size より大きな円盤しかない */ void hanoi ( char *f, char *t, char *w, char *size ) { if ( !strcmp ( size, "" ) ) { /* 空っぽだったら*/ /* する事はない */ } else { /* まだ仕事があるなら */ /* やりたい事は、 「size の大きさの塔を f から t に動かしたい」事 そのためには、最終的に、size の大きさの円盤を動かす必要がある。 そのためには、 size の大きさの上の塔を t を利用して、一旦、f から w に移し size の大きさ円盤を f から t に移し size の大きさの上の塔を f を利用して、w から、t に動かせば良い */ /* f の所にある size の円盤の上の塔を w に移動して退かす (再帰呼出し) */ hanoi ( f, w, t, size + 1 ); /* f の所にある size の円盤を t に移動 */ /* ** この部分を完成させなさい */ /* size の円盤の上に w に退かした塔を載せる (再帰呼出し) */ /* ** この部分を完成させなさい */ } } /* * ハノイの塔 プログラム */ int main ( int argc, char *argv[] ) { /* コマンドライン引数を用いるので、 int main ( int argc, char *argv[] ) と、main 関数の引数を宣言する。 */ if ( argc < 1 ) { /* 引数が指定されていない */ printf ( "ハノイの塔の高さを指定する文字列を指定してください\n" ); /* エラーメッセージの出力 */ exit ( -1 ); /* エラーコード : -1 でプログラム終了 */ /* main 関数内であれば return -1; でも可 */ } /* else {} */ /* 「else {}」は省略可 */ /* * 最初は "1" に全ての円盤が置いてある * これを "2" に全ての円盤を移動する */ /* * ハノイで、できること * s_hanoi_init() : ハノイプログラムの開始 : 最初に一度だけ呼び出す * s_hanoi_size ( char *discs ) : ハノイの塔の高さを設定する * s_hanoi_move ( char *from, char *to ) : from にある円盤を to に移す * s_hanoi_clear () : 最初の状態に戻す * s_hanoi_stop() : ハノイ塔プログラムの終了 : return 0 の前に呼び出す */ s_hanoi_init(); /* ハノイの塔のプログラムの初期変化 */ /* コマンドライン引数の一つ目 (argv[1]) で、問題の高さを初期化 */ /* s_hanoi_size を呼び出す */ /* ** この部分を完成させなさい */ printf ( "これから解答を開始します。[Enter] キーを押してください\n" ); putchar ( '>' ); putchar ( getchar() ); /* 開始前に、一旦停止 */ /* 解答開始 */ hanoi ( "1", "2", "3", argv[1] ); /* 解答終了 */ printf ( "プログラムを終了するには [Enter] キーを押してください\n" ); putchar ( '>' ); /* 終了前に確認 */ putchar ( getchar() ); s_hanoi_stop(); return 0; }
$ ./20170602-02-QQQQ.exe 1234 これから解答を開始します。[Enter] キーを押してください > プログラムを終了するには [Enter] キーを押してください > $