Download : sample-001.c
/*
* 2018/06/22 sample-001.c
*/
/*
* "Hello, World" again
*/
#include <stdio.h>
int main ( int argc, char *argv[] ) {
printf ( "Hello, World\n" ); /* "Hello, World" という文字列と改行 ( "\n" ) を表示する */
return 0;
}
$ ./sample-001.exe Hello, World $
Download : sample-002.c
/*
* 2018/06/22 sample-002.c
*/
/*
* プログラム・ノックアウト (1)
*/
#include <stdio.h>
int main ( int argc, char *argv[] ) {
/* まず、printf をノックアウト */
return 0;
}
$ ./sample-002.exe $
Download : sample-003.c
/* * 2018/06/22 sample-003.c */ /* * プログラム・ノックアウト (2) */ /* * main 関数もなくしたら ? */ /* ここには何もない */
$ cc -c sample-003.c $ cc -o sample-003.exe sample-003.o /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 0 が無効なシンボル索引 11 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 1 が無効なシンボル索引 12 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 2 が無効なシンボル索引 2 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 3 が無効なシンボル索引 2 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 4 が無効なシンボル索引 11 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 5 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 6 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 7 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 8 が無効なシンボル索引 12 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 9 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 10 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 11 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 12 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 13 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 14 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 15 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 16 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 17 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 18 が無効なシンボル索引 13 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): 再配置 19 が無効なシンボル索引 21 を持っています /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): 再配置 0 が無効なシンボル索引 2 を持っています /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: 関数 `_start' 内: (.text+0x20): `main' に対する定義されていない参照です collect2: error: ld returned 1 exit status $
Download : sample-004.c
/*
* 2018/06/22 sample-004.c
*/
/*
* プログラム・ノックアウト (3)
*/
/*
* #include <stdio.h> // #include を無くした
*/
int main ( int argc, char *argv[] ) {
printf ( "Hello, World\n" ); /* この行で「警告」が出る */
return 0;
}
$ cc -c sample-004.c sample-004.c: In function ‘main’: sample-004.c:15:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default] printf ( "Hello, World\n" ); /* この行で「警告」が出る */ ^ $
Download : sample-005.c
/*
* 2018/06/22 sample-005.c
*/
/*
* プログラム・ノックアウト (4)
*/
/*
* #include <stdio.h> // #include を無くした
*/
int main ( int argc, char *argv[] ) {
/* printf も使わないと、「警告」はなくなった */
return 0;
}
$ ./sample-005.exe $
Download : sample-006.c
/*
* 2018/06/22 sample-006.c
*/
/*
* プログラム・ノックアウト (5)
*/
void main ( void ) { /* int を void に変更, 引数宣言もなくして良い */
/* return 0; を削って、空っぽにする */
}
/*
最も短い C 言語プログラムの実現
*/
$ ./sample-006.exe $
Download : sample-007.c
/*
* 2018/06/22 sample-007.c
*/
/*
* プログラム・ノックアウト (6)
*/
/*
* #include の代りに printf の extern 宣言
*/
extern int printf ( const char *message, ... );
/* 「extern void printf ( char *message );」 ではない ?? */
/*
* main
*/
int main ( int argc, char *argv[] ) {
printf ( "Hello, World\n" ); /* 「警告」が消えた */
return 0;
}
$ ./sample-007.exe Hello, World $
Download : sample-008.c
/*
* 2018/06/22 sample-008.c
*/
#include <stdio.h>
/*
* 文字列を三度表示する : 関数定義の例
*/
void threeTimesPrint ( char *message ) {
printf ( message ); /* 一度目 */
printf ( message ); /* ニ度目 */
printf ( message ); /* 三度目 */
}
/*
* main
*/
int main ( int argc, char *argv[] ) {
threeTimesPrint ( "Hello\n" ); /* 関数呼出しの例 */
threeTimesPrint ( "こんにちは\n" );
return 0;
}
$ ./sample-008.exe Hello Hello Hello こんにちは こんにちは こんにちは $
Download : sample-009.c
/*
* 2018/06/22 sample-009.c
*/
#include <stdio.h>
/*
* echo_char ( char ch )
* char ch -- 引数で指定された文字
* 引数で指定された文字を『』付で出力
*/
void echo_char ( char ch ) {
printf ( "『" );
putchar ( ch ); /* 引数で指定された文字を出力する */
printf ( "』" );
}
/*
* main
*/
int main ( int argc, char *argv[] ) {
printf ( "何か文字を入れてから[Enter]キーを押す : " );
echo_char ( getchar() ); /* getchar() で文字を読込み、それを出力 */
putchar ( '\n' );
return 0;
}
A
$ ./sample-009.exe < sample-009.in 何か文字を入れてから[Enter]キーを押す : A 『A』 $
Download : sample-010-01.c
/*
* 2018/06/22 sample-010-01.c
*/
#include <stdio.h> /* putchar が必要なので.. */
/*
* nprinttail
* n 回数 message を出力するが、行末を変更する。
*/
void nprinttail ( char *tail, char *message ) {
if ( *tail == '\0' ) {
} else {
printf ( message );
if ( *tail == '\n' ) { /* 改行の時のみ */
putchar ( '\n' ); /* 改行する */
} else { /* それ以外は */
/* 何もしない */
}
nprinttail ( tail + 1, message );
}
}
Download : sample-010.c
/*
* 2018/06/22 sample-010.c
*/
/*
* extern 宣言
*/
extern void println ( char *message );
extern void nprinttail ( char *tail, char *message );
/*
* n 回数の繰返し
*/
int main ( int argc, char *argv[] ) {
println ( "毎回改行「Hello」: " );
nprinttail ( "\n\n\n", "Hello" );
println ( "3 回目, 7 回目だけ改行「Hello」: " );
nprinttail ( "12\n456\n", "Hello" );
return 0;
}
$ ./sample-010.exe $
Download : sample-011.c
/*
* 2018/06/22 sample-011.c
*/
#include <stdio.h>
/*
* 文字の扱い
*/
int main ( int argc, char *argv[] ) {
printf ( "abc\n" ); /* 「abc(改行)」とでる */
printf ( "abc\n" + 1 ); /* 「bc(改行)」とでる ( 1 を加えると短くなる ) */
putchar ( 'A' ); /* 「A」とでる */
putchar ( '\n' ); /* 「(改行)」とでる */
putchar ( 'A' + 1 ); /* 文字に 1 を加えると ? */
putchar ( '\n' ); /* 「(改行)」とでる */
return 0;
}
$ ./sample-011.exe abc bc A B $
Download : sample-012.c
/*
* 2018/06/22 sample-012.c
*/
/*
* extern 宣言
*/
extern void printcharln ( char ch );
/*
* 文字の扱い(2)
*/
int main ( int argc, char *argv[] ) {
printcharln ( 'A' + 1 ); /* 'B' になった */
printcharln ( 'B' + 1 ); /* 'C' になる */
printcharln ( 'A' + 1 + 1 ); /* これも 'C' になる */
printcharln ( 'A' + 0 ); /* これはもちろん 'A' */
printcharln ( 'A' + 10 ); /* 'A', 'B', .., 'J', 'K' になるはず */
printcharln ( 'A' + 25 ); /* 'Z' !! */
printcharln ( 'Z' + 1 ); /* ??? */
return 0;
}
$ ./sample-012.exe $
Download : sample-013.c
/*
* 2018/06/22 sample-013.c
*/
/*
* extern 宣言
*/
extern void nprintcharln ( char *n, char ch );
extern void printcharln ( char ch );
extern void println ( char *string );
/*
* 文字の扱い(3)
*/
int main ( int argc, char *argv[] ) {
println ( "'A' から 10 個 :" );
nprintcharln ( "1234567890", 'A' );
println ( "'U' から 10 個 :" );
nprintcharln ( "1234567890", 'U' );
println ( "'k' から 10 個 :" );
nprintcharln ( "1234567890", 'k' );
println ( "'0' から 10 個 :" );
nprintcharln ( "1234567890", '0' );
println ( "'9' + 1 は.. :" );
printcharln ( '9' + 1 ); /* 残念ながら "10" ではない */
return 0;
}
$ ./sample-013.exe $
Download : sample-014.c
/*
* 2018/06/22 sample-014.c
*/
/*
* extern 宣言
*/
extern void println ( char *string );
extern void printonedigit ( int n );
extern void printonedigitln ( int n );
/*
* 整数
*/
int main ( int argc, char *argv[] ) {
println ( "整数値 0 の出力" );
printonedigitln ( 0 ); /* 「'0'」 でも 「"0"」 でもなく 「0」 */
println ( "整数値 9 の出力" );
printonedigitln ( 9 ); /* 一桁は OK */
println ( "整数値 11 の出力" );
printonedigitln ( 11 ); /* 上手く行かない */
println ( "整数値 1 + 1 の出力" );
printonedigitln ( 1 + 1 ); /* やっと計算がでてきた */
println ( "整数値 5 - 2 の出力" );
printonedigitln ( 5 - 2 ); /* 引算 */
println ( "整数値 3 * 2 の出力" );
printonedigitln ( 3 * 2 ); /* かけ算 */
println ( "整数値 8 / 3 の出力" );
printonedigitln ( 8 / 3 ); /* 小数点以下は余りは切り捨て */
println ( "整数値 8 % 3 の出力" );
printonedigitln ( 8 % 3 ); /* 余りは「%」をで計算 */
println ( "整数値 8 - ( 8 / 3 ) * 3 の出力" );
printonedigitln ( 8 - ( 8 / 3 ) * 3 ); /* 余りを求めるもう一つの方法 */
return 0;
}
$ ./sample-014.exe $
Download : sample-015.c
/*
* 2018/06/22 sample-015.c
*/
/*
* extern 宣言
*/
extern void println ( char *string );
extern void printpositiveint ( int n );
extern void printpositiveintln ( int n );
/*
* 整数
*/
int main ( int argc, char *argv[] ) {
println ( "整数値 0 の出力" );
printpositiveintln ( 0 );
println ( "整数値 11 の出力" );
printpositiveintln ( 11 );
println ( "整数値 12345 の出力" );
printpositiveintln ( 12345 );
println ( "整数値 12 * 34 の出力" );
printpositiveintln ( 12 * 34 );
return 0;
}
$ ./sample-015.exe $
Download : sample-016.c
/*
* 2018/06/22 sample-016.c
*/
#include <stdio.h>
/*
* check_star_char
*/
void check_star_char ( char ch ) {
if ( ch == '*' ) { /* ch の中身が '*' かどうかをチェック */
printf ( "これは「*」です\n" );
} else {
printf ( "これは「*」ではありません\n" );
}
}
/*
* main
*/
int main ( int argc, char *argv[] ) {
check_star_char ( getchar() ); /* getchar() で文字を読込み、それを出力 */
return 0;
}
A
$ ./sample-016.exe < sample-016.in A これは「*」ではありません $
/*
* 20180615-01-QQQQ.c
* コマンドライン引数で指定した長さのハノイの塔を解く
* [ポイント]
* コマンドラインで、長さを指定する[知識:argc,argv]
* 任意の高さのハノイの問題をどう解くか[思考:再帰を使う]
* cf. 3 の時は、人間が解いて、その手順をプログラム内に指定
*
[復習] 高さが 3
1 1
2 => 2
3 3
===== =====
A B C A B C
[思考法]
最終的に A の上の 123 を C のところに移動必要がある
中間目標(複雑な問題は、簡単な問題に分割)
3 の円盤を A か C に移動する必要
=> 3 の上の 12 が邪魔 => どかすか
=> どかす先は B である
12 を A => B にする = Hanoi の高さが 2 の問題を解く
=> 再帰が使える
123 を A => C
12 A => B ハノイ
3 A => C move : ライブラリ関数を呼ぶだけ
12 B => C ハノイ
高さ n のハノイの塔を移動するには、
2^{n}-1
回の移動が必要(数学的に証明可能:数学的帰納法を使う)
[解答]
1
2
3
=====
A B C
=>
2
3 1
=====
A B C
=>
3 2 1
=====
A B C
=>
1
3 2
=====
A B C
=>
1
2 3
=====
A B C
=>
1 2 3
=====
A B C
=>
2
1 3
=====
A B C
=>
1
2
3
=====
A B 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 より大きな円盤しかない
*/
/*
hanoi ( "A", "C", "B", "123" )
1 1
2 => 2
3 3
----- -----
A B C A B C
hanoi( "A", "B", "C", "12" );
move ( "A", "C", "3" );
hanoi( "B", "C", "A", "12" );
*/
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 );
/* s_hanoi_move は、f にある一番上の円盤を t に移動する */
/* 特に、円盤のサイズは指定しなくてもよい */
/* size の円盤の上に w に退かした塔を載せる (再帰呼出し) */
hanoi ( w, t, f, size + 1 ); /* 考える (ヒント 122 行目. 101,103) */
}
}
/*
* ハノイの塔 プログラム
*/
int main ( int argc, char *argv[] ) {
/*
コマンドライン引数を用いるので、
int main ( int argc, char *argv[] )
と、main 関数の引数を宣言する。
*/
/*
コマンドライン引数で、入力を行う
=> プログラムの実行開始時で、人間が判断して、引数を与える
=> プログラム開始前 : プログラムからは、強制できない
=> 人間は、間違える生き物 => 誤った指定がされる可能性がある
入力に対するチェックが必須
*/
if ( argc <= 1 ) { /* 引数が指定されていない */
printf ( "ハノイの塔の高さを指定する文字列を指定してください\n" );
/* エラーメッセージの出力 */
exit ( -1 ); /* エラーコード : -1 でプログラム終了 */
/* main 関数内であれば return -1; でも可 */
/* プログラムの強制終了 : exit */
/* => エラーコードが返せる */
/* => main 関数の return 0: エラーコード 0 (正常終了) */
} /* 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>
/*
今までは、main 関数の引数は void (「引数は無い」という意味 )
main は C Program の最初に呼び出される関数
=> 基本は、Program 中、他の関数から呼び出される事はない
=> 「引数には意味がない」と考える事ができる
実は
main 関数にも、引数を渡す事ができる
=> Program (内からも可能だが、普通は) の外から
「コマンドライン引数」として渡す
[コマンドライン引数の利用の手順]
1. main 関数の引数を「void」から「int argc, char *argv[]」と変更
# argc, argv は、引数の名前なので、自分の好きにしてよい
# (cf. int ac, char *av[] などとする人もいる..)
# が、習慣的に, argc, argv の名前を使う事多い
2. 引数の意味
argc (整数型) : コマンドライン引数の個数 + 1
argv (説明しない) : argv[k] で、k 番目の引数(文字列)を表す
k = 1 ? argc - 1
0 ? argc
0 : コマンド名になる
argc : 常に NULL が入っている
# NULL の説明はしない
*/
int main(int argc, char *argv[]) {
/* コマンドライン引数で、指定された一つ目の引数を表示する */
printf ( "コマンド名は : " );
printf ( argv[0] ); /* 0 番目はコマンド名 */
printf ( "です。\n" );
printf ( "コマンドライン引数の個数は " );
print_number ( argc - 1 ); /* argc は引数の個数 + 1 */
printf ( "です。\n" );
printf ( "一つめの引数は : " );
printf ( argv[1] ); /* 1 つめの引数 */
printf ( "です。\n" );
return 0;
}
#include <stdio.h>
/*
引数で指定された文字列を画面に出力する echo を作る
echo 「abc efg hij」
3, [ "abc", "efg", "hij" ]
# argc, argv
=>
abc efg hij
=>
abc => [ "abc", "efg", "hij" ] の一番目 => argv[1]
efg hij => 残り => argv の 2 番目以降
=> 「n 番目以降」を表現するために、n を追加
*/
void echo ( int n, int argc, char *argv[] ) {
if ( n < argc ) {
printf ( argv[n] ); /* n 番目を出力し */
putchar ( ' ' ); /* 出力した後、空白を追加 */
echo ( n + 1, argc, argv ); /* 残りの n + 1 番目からの出力を再帰で */
} else {
putchar ( '\n' ); /* 一番最後に、改行 */
}
}
int main(int argc, char *argv[]) {
echo ( 1, argc, argv ); /* argc, argv の 1 番目から出力 */
return 0;
}
#include <stdio.h>
/*
一桁の数を二つ指定して、足し算をするプログラム
./p-003.exe 2 3
=> 2+3=5
*/
int main(int argc, char *argv[]) {
printf ( argv[1] ); /* putchar ( *(argv[1]) ); */
/* argv[1] == "2" */
/* *(argv[1]) == *"2" == '2' */
/* '2' : ASCII Code 表での文字「2」に対応する数値 */
/* '2' == '0' + 2 */
/* '2' - '0' == 2 */
printf ( "+" );
printf ( argv[2] );
printf ( "=" );
print_number ( ((*(argv[1]))-'0') + ((*(argv[2]))-'0') );
/* ^^^^^^^^^^^^^^^^ => 2 ^^^^^^^^^^^^^^^^^ => 3 */
printf ( "\n" );
return 0;
}
#include <stdio.h>
/*
整数値(を表現する文字列)を二つ指定して、足し算をするプログラム
./p-003.exe 123+456
=> 123+456=579
[Point]
atoi 関数 (標準ライブラリにある関数)
引数に、整数値を表現する文字列を指定すると、
その文字列が意味する整数値を返す
*/
int main(int argc, char *argv[]) {
printf ( argv[1] );
printf ( "+" );
printf ( argv[2] );
printf ( "=" );
print_number ( atoi ( argv[1] ) + atoi( argv[2] ) );
printf ( "\n" );
return 0;
}
[前回]
整数型の話
整数値 ( .... -2, -1, 0, 1, 2, ... )
集合としては有限集合 ( -2^{31} ? 2^{31}-1 )
=> コンピュータでは、表現の対象を内部の数値でコーディング
内部の数値:bit の並び(32 個) で表現
bit : 0/1 ( 2 通りの区別 )
32 bit => 2^{32} 通りの区別(集合の要素)
=> 有限でしかない !!
=> ふつうに整数の四則演算などの整数の性質をもったモノ(int 型の値)が
C 言語内の利用できる
それまで、C 言語で「扱えるモノ[データ/値]」には、
最初に「文字列」、次に、「文字列の一部」としての「文字」
前回 : 「整数」が追加された
# 実は他にもある「例 : 浮動小数点型 : 実数に対応」
処理の対象は「文字列」しか扱わない => 色々なところが決め打ち
# 例 : 関数の引数は、「char *」とかけばよい
# 整数型がはいってきた => 「int」とかく場面がでてきた
これまでの講義方針
C 言語を学ぶ(講義の本来の目的)ではなく、C 言語に慣れる
これまで(一周目) : C 言語の世界を一通りめぐる事やってきた
-> 二週目は、「C 言語を理解するための『系統的な』説明」したい
整数型
定数表現(リテラル) : 数字並び (例 : 123 => 「百二十三」を表す )
# cf. "123" は、1,2,3 の文字が並ぶ、文字列
# '3' が、「3」という文字
# 123 は、整数値の123 になる
演算 : 四則演算(+,-,*,/)と、余り(%)ができる
比較演算 ( ==, !=, >, <, >=, <= )
宣言(関数の引数): int
# cf. 文字列の時は、「char *」だった...
出力 : (標準的な方法はあるが、それは説明せず..) : print_number
=> すでに、知っている文字の出力関数 putchar で、自分で作った
[今日の内容]
コマンドライン引数
プログラムを実行するとき、(実行ファイル名を指定する、そのあとに、追加で)
コマンドライン引数(引数となる文字列を空白で区切ったもの)が指定できる
例 : ./p-003.exe abc 123
=> 実行ファイル p-003.exe に、二つの引数 abc, 123 を指定
C 言語では、コマンドライン引数は、
main 関数に渡される、argc (引数の個数+1) と argv ( argv[n] とすると、n 番目に
に指定した引数(文字列)を表す ) によって、参照できる
=> プログラムへの入力(文字列)として引数が利用できる
# cf. 入力は、文字(getchar())しかやっていない
Hanoi の問題
コマンドライン引数 => argc, argv の使い方
構造的帰納法の考え方
Hanoi(N) =>
Hanoi(N-1)
move(N)
Hanoi(N-1)
# 再帰呼び出しが、二か所でおきている
# cf. これまでの「繰り返し」のためには、
# 再帰呼び出しが一か所で済んだ
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20180622-01.c
/*
* CDATE FILENAME
*
* キーボードから一文字入力し、その文字によって異る国の挨拶をする
*/
#include <stdio.h>
/*
* hello ( char contry )
* char contry : 国を表す一文字
* j : 日本
* e : 英語
* c : 中国
* f : フランス語
* g : ドイツ語
*/
void hello ( char cmd ) {
if ( cmd == 'j' ) { /* 'j' の時は、日本語にする */
printf ( "こんにちは\n" );
} else if ( cmd == 'e' ) { /* 'e' の時は、英語にする */
/*
** この部分を完成させなさい
*/
} else if ( cmd == 'c' ) { /* 'c' の時は、中国語にする */
printf ( "ニイハオ\n" );
} else if ( cmd == 'f' ) { /* 'f' の時は、フランス語にする */
printf ( "Bonjour\n" );
/*
** この部分を完成させなさい
*/
printf ( "Guten tag\n" );
} else { /* どれでもなければ.. */
printf ( "???\n" );
}
}
/*
* main
*/
int main( void )
{
printf ( "国を表す文字を入力してください\n" );
printf ( "\tj\t日本\n" );
printf ( "\te\t英語\n" );
printf ( "\tc\t中国\n" );
printf ( "\tf\tフランス\n" );
printf ( "\tg\tドイツ\n" );
hello ( getchar() ); /* getchar() で文字を入力し、それに対応する結果を出す */
return 0;
}
f
C:\usr\c\> 20140523-01-QQQQ 国を表す文字を入力してください j 日本 e 英語 c 中国 f フランス g ドイツ f Bonjour C:\usr\c\>
Download : 20180622-02.c
/*
* CDATE FILENAME
*
* キーボードから一行(改行まで..)文字列を読込み、それを逆順に出す
*/
#include <stdio.h>
/*
* reverse ( char contry )
* char cmd : どのメッセージにするかを表す文字
*
*/
void reverse_line ( char ch ) {
if ( ch == '\n' ) { /* 改行ならば.. */
/* なにもしなくてよい */
} else { /* そうでなければ.. */
/*
** この部分を完成させなさい
*/
}
}
/*
* main
*/
int main( void )
{
reverse_line ( getchar() ); /* 最初の文字を読み込んで .. */
putchar ( '\n' ); /* 改行を出力 */
return 0;
}
abc123
C:\usr\c\> 20140523-02-QQQQ abc123 321cba C:\usr\c\>