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] キーを押してください > $