Download : sample-001.c
/*
* 2020/07/17 sample-001.c
*
* [コンパイル]
* cc -I ~/include -c sample-001.c
* [リンク]
* cc -o sample-001.exe sample-001.o
* [実行]
* ./sample-001.exe
*/
/*
* 入力を一度だけ処理
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
s_print_string ( "整数値を一つ入力してください、一つ増やした値を出力します:" );
s_print_int ( s_input_int() + 1 ); /* 整数値を入力し、1 を増やし、出力 */
s_print_newline();
return 0;
}
123
$ ./sample-001.exe < sample-001.in 整数値を一つ入力してください、一つ増やした値を出力します:123 124 $
Download : sample-002.c
/*
* 2020/07/17 sample-002.c
*
* [コンパイル]
* cc -I ~/include -c sample-002.c
* [リンク]
* cc -o sample-002.exe sample-002.o
* [実行]
* ./sample-002.exe
*/
/*
* 入力を複数回処理
* 入力関数(s_input_int())が呼び出される度に、入力が行われる
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
* 一回目
*/
s_print_string ( "一回目:整数値を一つ入力してください、一つ増やした値を出力します:" );
s_print_int ( s_input_int() + 1 );
s_print_newline();
/*
* ニ回目
*/
s_print_string ( "ニ回目:整数値を一つ入力してください、一つ増やした値を出力します:" );
s_print_int ( s_input_int() + 1 );
s_print_newline();
/*
*
*/
return 0;
}
123 456
$ ./sample-002.exe < sample-002.in 一回目:整数値を一つ入力してください、一つ増やした値を出力します:123 124 ニ回目:整数値を一つ入力してください、一つ増やした値を出力します:456 457 $
Download : sample-003.c
/*
* 2020/07/17 sample-003.c
*
* [コンパイル]
* cc -I ~/include -c sample-003.c
* [リンク]
* cc -o sample-003.exe sample-003.o
* [実行]
* ./sample-003.exe
*/
/*
* 一つの入力を複数回処理
* 入力関数の呼出し(入力)は一回だが、値(入力値)は複数利用したい
* 関数(変数)を利用するしかない
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* 引数で与えらえた値を複数回利用する(関数/引数変数の特権 !!)
*/
void print_add_one_result ( int value ) {
s_print_string ( "整数値 " );
s_print_int ( value ); /* 一度目の利用 */
s_print_string ( " に 1 を加えた値は " );
s_print_int ( value + 1 ); /* 二度目の利用 */
s_print_string ( "これを 2 倍した値は " );
s_print_int ( value * 2 ); /* 三度目の利用 */
s_print_string ( " になります。\n" );
}
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
* 一回目
*/
print_add_one_result ( s_input_int() ); /* 「入力(機能)」は「ここ」で一回 */
/* 「入力値」は、関数内で、何度も利用可能 */
/*
* ニ回目
*/
print_add_one_result ( s_input_int() ); /* 二度目の入力 */
/*
*
*/
return 0;
}
123 456
$ ./sample-003.exe < sample-003.in 123 整数値 123 に 1 を加えた値は 124これを 2 倍した値は 246 になります。 456 整数値 456 に 1 を加えた値は 457これを 2 倍した値は 912 になります。 $
Download : sample-004.c
/*
* 2020/07/17 sample-004.c
*
* [コンパイル]
* cc -I ~/include -c sample-004.c
* [リンク]
* cc -o sample-004.exe sample-004.o
* [実行]
* ./sample-004.exe
*/
/*
* インプットループ
* 入力を繰り返す関数
*/
#include <stdio.h>
/*
* 改行 ('\n') が入力されるまで、文字を入力し、それを二度ずつ出力する
*/
void print_twice_char ( char ch ) {
putchar ( ch ); /* とりあえず二度出力 */
putchar ( ch );
if ( ch == '\n' ) { /* 改行だった / もうこれ以上処理しない */
/* 何もしない */
} else { /* まだ処理する必要がある */
print_twice_char ( getchar() ); /* 入力をして、再帰 */
}
}
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
* 最初の呼出しは main で..
*/
print_twice_char ( getchar() );
/*
*
*/
return 0;
}
abc$
$ ./sample-004.exe < sample-004.in abc$ aabbcc$$ $
Download : sample-005.c
/*
* 2020/07/17 sample-005.c
*
* [コンパイル]
* cc -I ~/include -c sample-005.c
* [リンク]
* cc -o sample-005.exe sample-005.o
* [実行]
* ./sample-005.exe
*/
/*
* 乱数
*/
#include <stdio.h>
#include "s_print.h"
#include "s_random.h" /* s_random を利用するので.. */
/*
s_init_random() --- 乱数系列を現在の時刻を利用して決定
s_random() --- 整数値を持つ(疑似)一様乱数を返す
*/
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
*
*/
s_init_random(); /* 乱数系列の初期化 */
/*
*
*/
s_print_string ( "乱数を出力します : " );
s_print_int ( s_random() );
s_print_newline();
/*
*
*/
return 0;
}
$ ./sample-005.exe 乱数を出力します : 1973597680 $
/*
* 課題 CNAME-01
*
* CDATE FILENAME
*
* キーボードから一文字入力し、その文字によって異る国の挨拶をする
*/
#include <stdio.h>
/*
* hello ( char contry )
* char contry : 国を表す一文字
* j : 日本
* e : 英語
* c : 中国
* f : フランス語
* g : ドイツ語
*/
void hello ( char cmd ) {
/* if 構文版
if ( cmd == 'j' ) {
} else if ( cmd == 'e' ) {
} ..
switch ( cmd ) {
case 'j':
case 'e':
..
}
*/
switch ( cmd ) {
case 'j': /* 'j' の時は、日本語にする */
printf ( "こんにちは\n" );
break;
case 'e': /* 'e' の時は、英語にする */
printf ( "Hello\n" );
break;
case 'c': /* 'c' の時は、中国語にする */
printf ( "ニイハオ\n" );
break;
case 'f': /* 'f' の時は、フランス語にする */
printf ( "Bonjour\n" );
break;
/*
** この部分を完成させなさい
*/
printf ( "Guten tag\n" );
break;
default: /* どれでもなければ.. */
printf ( "???\n" );
break;
}
}
/*
* 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;
}
#include <stdio.h>
/*
void is_digit_char ( char ch )
引数で指定された『文字(コード)』が、「数字」を表す
なら、「数字です」と出力、
そうでないならば、「数字ではありません」と出力
*/
void is_digit_char ( char ch ) {
/*
仮引数変数 ch (に入っている文字コード) が
「数字」を表すコードである事を確認する
ASCII コード表
'0' <= ch <= '9' ( ch は '0' ? '9' )
=> 二つの条件
'0' <= ch
ch <= '9'
が同時に成立している必要がある
!! もし、C 言語で「 '0' <= ch <= '9'」という記述が
!! 許されるなら
!! if ( '0' <= ch <= '9' ) {
!! printf ( "数字です\n" );
!! } else {
!! printf ( "数字ではありません\n" );
!! }
二つの条件をチェックする例
(今の所)二つの条件は同時には判定できない
=> 一つずつ判定するしかない
*/
if ( '0' <= ch ) {
/* '0' <= ch が成り立っている */
if ( ch <= '9' ) {
/* 「'0' <= ch が成り立って」という状況で、更に
「ch <= '9'」が成立 */
/* => 二つの条件が共に成立している */
printf ( "数字です\n" );
} else {
/* 「'0' <= ch」は成立するが「ch <= '9'」は不成立 */
printf ( "数字ではありません\n" );
}
} else {
/* 「'0' <= ch」が不成立 */
if ( ch <= '9' ) {
/* 「'0' <= ch」は不成立、「ch <= '9'」が成立 */
printf ( "数字ではありません\n" );
} else {
/* 「'0' <= ch」が不成立、「ch <= '9'」も不成立 */
printf ( "数字ではありません\n" );
}
}
}
int main(void) {
printf ( "文字を一文字入力して、[Enter]キーを押してください : " );
is_digit_char ( getchar() );
return 0;
}
#include <stdio.h>
/*
void is_digit_char ( char ch )
引数で指定された『文字(コード)』が、「数字」を表す
なら、「数字です」と出力、
そうでないならば、「数字ではありません」と出力
*/
void is_digit_char ( char ch ) {
/*
仮引数変数 ch (に入っている文字コード) が
「数字」を表すコードである事を確認する
ASCII コード表
'0' <= ch <= '9' ( ch は '0' ? '9' )
=> 二つの条件
'0' <= ch
ch <= '9'
が同時に成立している必要がある
!! もし、C 言語で「 '0' <= ch <= '9'」という記述が
!! 許されるなら
!! if ( '0' <= ch <= '9' ) {
!! printf ( "数字です\n" );
!! } else {
!! printf ( "数字ではありません\n" );
!! }
二つの条件をチェックする例
(今の所)二つの条件は同時には判定できない
=> 一つずつ判定するしかない
*/
if ( '0' <= ch ) {
/* '0' <= ch が成り立っている */
if ( ch <= '9' ) {
/* 「'0' <= ch が成り立って」という状況で、更に
「ch <= '9'」が成立 */
/* => 二つの条件が共に成立している */
printf ( "数字です\n" );
} else {
/* 「'0' <= ch」は成立するが「ch <= '9'」は不成立 */
printf ( "数字ではありません\n" );
}
} else {
/* 「'0' <= ch」が不成立 */
/* 「ch <= '9'」の条件を確認するまでもなく、数字でない */
printf ( "数字ではありません\n" );
}
}
int main(void) {
printf ( "文字を一文字入力して、[Enter]キーを押してください : " );
is_digit_char ( getchar() );
return 0;
}
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
void check_make_program ( int times )
switch 構文で実現
*/
void check_make_program ( int times ) {
switch ( times ) {
case 1: /* times == 1 の意味 */
/* times == 1 の時の命令を記述する */
s_print_string ( "手でやる\n" );
break; /* ここで命令を終わり case - break <=> {} */
case 2: /* times == 2 の意味 */
/* times == 2 の時の命令を記述する */
s_print_string ( "自分で作るかどうか判断しろ\n" );
break;
default: /* 上記以外の意味 */
/* 上で挙げた候補以外(その他) */
s_print_string ( "プログラムを作れ\n" );
break;
}
}
int main(void) {
s_print_string ( "その仕事は何度行いますか ? : " );
check_make_program ( s_input_int() );
return 0;
}
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
void check_make_program ( int times )
引数で与えれた、仕事の繰り返し回数によって、
プログラムを作成するかどうかを判定して、
その指示を出力するプログラム
判定の基準と動作
times が 1 の時は、「手でやる」
times が 2 の時は、「自分で作るかどうか判断しろ」
times が 3(以上) の時は、「プログラムを作れ」
*/
void check_make_program ( int times ) {
if ( times == 1 ) {
s_print_string ( "手でやる\n" );
} else if ( times == 2 ) {
s_print_string ( "自分で作るかどうか判断しろ\n" );
} else {
/* times != 1, times != 2, (仮定 times > 0 ) */
/* => times >= 3 */
s_print_string ( "プログラムを作れ\n" );
}
}
int main(void) {
s_print_string ( "その仕事は何度行いますか ? : " );
check_make_program ( s_input_int() );
return 0;
}
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
void check_make_program ( int times )
引数で与えれた、仕事の繰り返し回数によって、
プログラムを作成するかどうかを判定して、
その指示を出力するプログラム
判定の基準と動作
times が 1 の時は、「手でやる」
times が 2 の時は、「自分で作るかどうか判断しろ」
times が 3(以上) の時は、「プログラムを作れ」
*/
void check_make_program ( int times ) {
if ( times == 1 )
else if ( times == 2 )
s_print_string ( "自分で作るかどうか判断しろ\n" );
else
s_print_string ( "プログラムを作れ\n" );
}
int main(void) {
s_print_string ( "その仕事は何度行いますか ? : " );
check_make_program ( s_input_int() );
return 0;
}
前回(2020/07/10)の内容
条件分岐 (if 構文)
条件分岐
「複数の命令」の内、
「条件」によって、
その複数の命令の内の、「いずれか一つ」
を実行する仕組み
=> 命令を実行するかどうかの条件が記述できる
<= 順接は、「問答無用」で実行される
cf.
順接 : 命令を並べる事により、
複数の命令を、並べた順に、それぞれ実行する仕組み
=> 「記述量」がふえると、「実行量」が増える
与えれた状況に併せて、適切な対応を選択する仕組み
プログラムの「柔軟性」を高める仕組み
「柔軟性」=>「汎用性」=>「再利用」
if 構文 : 条件分岐を実現する C 言語での表現方法
構文 :
if ( 条件式 ) { then 節
条件が不成立時の文
} else { else 節
条件が成立時の文
}
条件式 : 真偽値(成立/不成立)を求める式
真 => 条件が成立
偽 => 条件が不成立 ( 成立しなかった )
例: !strcmp ( A, B ) => A,B が同じ文字列なら真
例: 整数型の値や文字型の値は「比較」ができる
==, != (等しい、等しくない)
<, >, <=, >= で、大小比較が可能
条件の成立時の文
条件が不成立時の文
: 複数の文(命令)が指定できる ( 空にする事も可能 )
意味
「条件」が
『成立』した時に「条件の成立時の文」
を、
そうでない時には、「条件が不成立時の文」
を
実行する
どちらか
一方だけ
が実行される
「両方実行」も「両方不実行」も「無し」
「if 『文』」ではなく、
「if 『構文』」である理由
「『文』を対象として、『何かをする表現』」
なので「メタ表現」
文は、データを対象とする表現
構文は、文を対象とする表現
cf. 「順接」も「順接構文」
if 構文 アラカルト
if 構文の基本 :
if ( C ) {
A
} else {
B
}
「基本」は「基本の組み合せだけで何でもできる」ので秀逸
色々な組み合せ方を学ぶ必要がある
=> いかなる条件の判定も、(条件のサイズが有限なら)
基本の if 構文だけで、表現できる
二つの条件 C1, C2 の両方が成立した時に A、そうでない時に B という場合
# 基本の構文は、一つの条件しか確認できない
# => 二つの条件 C1, C2 を、どのように利用するか ?
場合分け ( 真 : T / 偽 : F )
C1 C2 C1 と C2 の両方
T T T
T F F
F T F
F F F
# if 構文を利用すると、2 つの場合に分けられる
# => if 構文数を N とすると、N+1 の状況が作れる
例: 引数の『文字(コード)』が数字かどうかを確認する
(三つ目の if 構文を省略する場合の真偽表)
場合分け ( 真 : T / 偽 : F )
C1 C2 C1 と C2 の両方
T T T
T F F
F * F
else 節の省略
else 節 : if 構文の 「else { B }」の部分
B が空の時は、
「else {}」としても良い
が、
それを省略しても良い
基本:
if ( C ) {
A
} else {
}
else 節の省略の場合:
if ( C ) {
A
} /* else {} */ /* else 節を省略 */
then 節 ( { A } の所 ) は省略できない
基本:
if ( C ) {
} else {
B
}
できない:
if ( C )
else {
B
}
if 構文の「入れ子」
if 構文の文の中に if 構文をいれる
複数の条件の「条件の組み合せ」を
if 構文の組み合せで実現できる
例(複雑な条件) : ch が英大文字かどうか
'A' <= ch <= 'Z' [数学]
=> C 言語では、こう表現できません
# 別の表現があるが、後期に話す
例 :
if ( 'A' <= ch ) {
/* ここでは、 「'A' <= ch」が成立している */
if ( ch <= 'Z' ) {
/* ここでは「'A' <= ch」と「ch <= 'Z'」の両方が成立 */
/* ch が「英大文字」の時 */
} else {}
} else {}
[前回(2020/07/10) : 条件分岐 again ]
条件分岐
条件の可否によって、複数の命令の実行を選択できる
命令を組み合わせて新しい命令を作る仕組み ( cf. 順接 )
if 構文
C 言語で条件分岐を表現する仕組み
基本 : if ( C ) { A } else { B }
=> 基本の組み合わせ ( 入れ子 ) で任意の条件が判定可能
応用
else 節が省略可能
[2020/07/17]
複数条件の判定の内
ある値が複数の値をとりうる場合
例 : 入力される数値が、 1, 2, 3 の三通りある
それぞれの場合に対して、別々の処理をしたい
!! もし、取りうる範囲が 2 種類しかなければ、
!! if 構文一つで十分
例:
それを 1 度しかやらないなら、すぐに手でやれ
もし、2 度やるなら、どちらか悩んでください
もし、3 度(以上)やるなら、プログラムを作って、PCにやらせろ
一般に N 通りの区別をするには、
else が N - 1 回深く
もし、else の中身が、if 構文一つ場合
=> else 節の {} を省略する
else if 構文 (イデオム)
else 節の文全体が一つの if 構文(入れ子)になっている場合
else 節のブレースを省略する
例:
if ( C1 ) {
A
} else {
if ( C2 ) {
B
} else {
C
}
}
=>
if ( C1 ) {
A
} else if ( C2 ) {
B
} else {
C
}
入れ子による、段の深化が防げる
複数の条件の関係が「視覚化」できます
入れ子 : 複数条件が適用されている
else if : 一つのものに対する異なった条件が適用
一つのデータに対して、複数の条件の検査になっている
「表現」と「意味」の対応 (イデオム)
推奨しない if 構文の表現
その他の表現
いつでも、「基本」を守る事が肝要
自分で作成する時には、まずは、基本を守る
他人は、基本を守るとは限らないので、
いろいろな記法を学ぶ事も必要
ブレースの省略
then 節/else 節の文が一文の時にはブレースを省略できる
!! 「本」には、
!! then/else 節には、「(一つの)文」が書ける
!! 複数の文を書きたい場合は {} を使え
!! 文が一つの場合は、{} を付けてもよい
else if 構文は、その規則を特別な場合に適用している
ブレース省略の是非
「省略」できるから、「手間」は減る (僅かな利点)
条件の適用範囲が不明瞭になる (大きな損失)
後から、変更を加える時に不便 (ミスの増大)
ミスをしないためのちょっとした習慣(小さなコスト)が、
結果的に、大きなミス(多大な損害)を防ぐ事になります。
例 : {} を省略しない
ぶら下がり構文の悲劇
ブレースの省略と else の省略が重なると悲惨
if ( C1 ) if ( C2 ) A else B
は、次のどちらか ?
(1) else が内側(後の/近い方の) if に対応 [正解]
if ( C1 )
if ( C2 )
A
else
B
if ( C1 ) {
if ( C2 ) {
A
} else {
B
}
}
(2) else が外側(前の/遠い方の) if に対応
if ( C1 )
if ( C2 )
A
else
B
if ( C1 ) {
if ( C2 ) {
A
}
} else {
B
}
1+2*3 => 1+(2*3)
[switch 構文]
switch 構文
条件分岐の表現方法の一つ
!! if 構文は万能なので、なくてもよい
機能
多分岐構文
if 構文は 2 分岐だが switch 構文は n 分岐
構文
<switch 文> ::= switch ( <式> ) { <case 並び> }
<case 並び> ::= <case> の繰返し
<case> ::= <label> : 文並び ( 最後に break がある事を想定 )
<label> := case <定数> | default
※1 一つの <switch 文>内には、同じ <label> を含める事はできない
※2 文並び中に break 文があり、それが実行されると、switch 文は終了する
意味
もし、「式」の値が「定数」の何れか
であれば、
そのラベル以下の文を実行する
そうでなくて、
もし、
defualt があれば、そのラベル以下の文を実行する
そのいずれでもなければ、何もしない
[再帰呼出し again]
再帰呼出し
ある関数定義の本体に、その関数自身の呼出しが含まれる事
=> その関数は再帰呼び出しされる
関数が、再帰で定義されている (プログラミング言語)
# [数学]
# 帰納的に定義されている関数
# 例:
# 1 ( n が 0 の時 )
# 階乗 n! = {
# n * ( (n-1)! ) ( その他 )
#
# n! を定義するのに、(n-1)! を利用している
# 「循環定義(論法)」のように感じる
# 「表は裏の裏」、「裏は表の裏」
# すべてのものは神が作った
# 神を作ったのは ? 神様の神様
# 神様の神様を作ったのは神様の神様の神様
# 数学的帰納法の原理に基づく
# 帰納的定義になっている
# 3! => 3 * (3-1)!
# => 3 * 2!
# => 3 * ( 2 * (2-1)! )
# => 3 * 2 * 1!
# => 3 * 2 * (1 * (1-1)!)
# => 3 * 2 * 1 * 0!
# => 3 * 2 * 1
# => 6
#
# 自然数の定義(ペアノの公理)
# [i] 0 は自然数
# [ii] n が自然数ならn+1も自然数
# [iii] [i],[ii] から作られるものだけが自然数
#
# 3 は自然数か ?
# => [ii] から 3 = 2 + 1, 2 が自然数なら自然数
# => 2 が自然数か ?
# => [ii] から 2 = 1 + 1, 1 が自然数なら自然数
# => 1 が自然数か ?
# => [ii] から 1 = 0 + 1, 0 が自然数なら自然数
# => 0 が自然数か ?
# => [i] 0 は自然数なので OK
#
# => 数学的帰納法の原理
#
「再帰的に定義さらた関数の『一度』の呼出し」
で「その関数の定義の呼出しが」
が『何度』も呼び出される
「可能性」が生じる
注意 :
安易に「再帰呼出し」を記述すると、「無限ループ」になる
安易 :
「対象を『小さく』」していない
や
最小の場合の対応をしていない
「再帰呼出しを『終了』させる」仕組
を「意図的に導入」する
「対象を『小さく』」する
し、
最小の場合の対応をする
を記述する必要がある
「条件分岐」が必須
再帰句
P は、停止条件
A は繰り返す命令、
X' は X から計算され、『何時か』 P(X)が成立する
X' は X より「小さく」なり、
P(c) となる c (最小値)に X が何時かは成る
記述形式
f(X) {
if ( P(X) ) {
/* なにもしない *.
} else {
A(X);
f(X');
}
}
意味 :
f(X) を呼ぶと、
P(X''..')が成立するまで A(X) を繰り返す
' の個数だけ A(X)を繰り返す
ポイント :
「A(X) を繰り返す」ために「f() を再帰で定義」する
再帰関数
再帰呼出しを行う形で定義された関数
繰返し : 同じ命令(記述)を何度も呼び出す仕組
再帰呼出しを利用する事により、「繰返し」が実現できる
再帰関数は、「何らかの繰返し」を実現している
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20200717-01.c
/*
* 20200717-01-QQQQ.c
*
* 数当てを行う
*
* コンパイル :
* cc -I ~/c/include -c 20200717-01-QQQQ.c
* cc -o 20200717-01-QQQQ.exe 20200717-01-QQQQ.o
* 実行 :
* ./20200717-01-QQQQ.exe
*
*/
#include <stdio.h>
#include "s_print.h" /* s_print_int を利用するので.. */
#include "s_input.h" /* s_input_int を利用するので.. */
#include "s_random.h" /* s_random を利用するので.. */
/*
* prompt
* メッセージを出力し、キーボードから整数値を読み込んで、
* その値を返す関数
*/
int prompt(void) {
s_print_string ( "私が選んだ数を予想して入力してください : " );
return s_input_int();
}
/*
*/
void game ( int input, int answer ) {
if ( input == answer ) { /* 入力と答えが一致した */
s_print_string ( "お見事です。あたりました。\n" );
} else {
if ( input > answer ) { /* 入力が、答えより大きい */
/*
** この部分を完成させなさい
*/
} else { /* 入力が、答えより小さい */
s_print_string ( "その数は小さすぎます。\n" );
}
/* 未だ、答えが、当っていないので、ゲームを続ける.. */
/*
** この部分を完成させなさい
*/
}
}
/*
* main
*/
int main( void )
{
s_init_random(); /* 乱数系列の初期化 */
s_print_string ( "私が考えた 1 〜 100 数を予想して当ててみてください。\n" );
game ( prompt(), (s_random()%100) + 1 );
return 0;
}
50 75 83 90 85 84
$ ./20180928-01-QQQQ.exe 私が考えた 1 〜 100 の数を予想して当ててみてください。 私が選んだ数を予想して入力してください : 5 5 その数は小さすぎます。 私が選んだ数を予想して入力してください : 60 60 その数は大きすぎます。 私が選んだ数を予想して入力してください : 30 30 お見事です。あたりました。 $
Download : 20200717-02.c
/*
* CDATE FILENAME
*
* 与えられた自然数の素因数を出力する
*
* 12 は..
*
* [コンパイル]
* cc -I ~/include -c FILENAME
* [リンク]
* cc -o BASENAME.exe BASENAME.o
* [実行]
* ./BASENAME.exe
*
*/
#include <stdio.h>
#include "s_print.h" /* s_print_int を利用するので.. */
/*
* void print_prime_factor_sequence ( int n, int p )
* 機能 : p 以上の n の素因数を小さい順に並べで表示する
* 条件 : n には p 未満の素因数を含まれていないものとする
* int n : p 未満の素因数を含まれていない自然数
* 返り値 : なし
*/
void print_prime_factor_sequence ( int n, int p ) {
if ( p > n ) { /* もう n には p 以上の素因数を含まない */
/* 何もしなくてよい */
/* 本来、ここにくるのは n = 1 の時だが、念の為 */
} else if ( n % p == 0 ) { /* n が p を素因数として含む */
s_print_char ( ' ' ); /* 隙間を空け */
s_print_int ( p ); /* 素因数を表示し */
/* もう一度 p の要素があるかもしれないので、そこから試す [再帰] */
/*
** この部分を完成させなさい
*/
} else { /* n が p を素因数として含まない */
/* 本来は p の次の素数を試すべきだが.. */
/* その代りに p + 1 を試す (のは無駄だが、正く動く) [再帰] */
/*
** この部分を完成させなさい
*/
}
}
/*
* void print_prime_factor_of ( int n )
* 機能 : n の素因数を出力する
* int n : 素因数を表示したい自然数
* 返り値 : なし
*/
void print_prime_factor_of ( int n ) {
if ( n < 1 ) { /* 与えらた数が自然数ではない */
s_print_int ( n );
s_print_string ( "は、自然数ではありません\n" );
} else if ( n == 1 ) { /* 与えられた数が 1 の場合 */
s_print_int ( n );
s_print_string ( "の素因数はありません\n" );
} else {
s_print_int ( n );
s_print_string ( "の素因数分解は" );
/*
** この部分を完成させなさい
*/
s_print_string ( " となります。\n" );
}
}
/*
* main
*/
int main( void )
{
print_prime_factor_of ( 12 );
return 0;
}
$ ./20200717-02-QQQQ.exe 12の素因数分解は 2 2 3 となります。 $
Download : 20200717-03.c
/*
* 20200717-03-QQQQ.c
* フィボナッチ数列の第 n 項を返す関数
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* int fibonacci ( int n )
* 引数で指定された n 番目 ( n = 0 〜 ) のフィボナッチ数を値として返す関数
* ただし、n 番目のフィボナッチ数 fib(n) は次のように再帰的に定義
* 0 (n = 0 の時)
* fib(n) = { 1 (n = 1 の時)
* fib(n-1) + fib(n-2) (n > 1 の時)
*
* 注意 : 引数に負の数を指定された場合の値は「未定義」
*/
int fibonacci ( int n ) {
if ( n < 2 ) {
/* 本来は n = 0, n = 1 の時の処理 */
/* fib(0) = 0, fib(1) = 1 なので 0 <= n <= 1 の時 fib(n) = n */
return n;
/* n < 0 (負の数) の時は、『未定義』なので、勝手に n を返している */
/* 本来は『未定義』の場合を含めるべきでない */
} else {
/* 再帰を利用して計算 */
/*
** この部分を完成させなさい
*/
}
}
/*
*
*/
void print_fibonacci ( int n ) {
s_print_int ( n );
s_print_string ( " 番目のフィボナッチ数は " );
s_print_int ( fibonacci ( n ) );
s_print_string ( " です。\n" );
}
/*
* main
*/
int main ( void ) {
s_print_string ( "整数値 n を入力してください : " );
print_fibonacci ( s_input_int() );
s_print_string ( "整数値 n を入力してください : " );
print_fibonacci ( s_input_int() );
return 0;
}
4 10
$ ./20200717-03-QQQQ.exe 整数値 n を入力してください : 4 4 番目のフィボナッチ数は 3 です。 整数値 n を入力してください : 10 10 番目のフィボナッチ数は 55 です。 $