Download : sample-001.c
/*
* 2017/06/30 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
/*
* 2017/06/30 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
/*
* 2017/06/30 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
/*
* 2017/06/30 sample-004.c
*
* [コンパイル]
* cc -I ~/include -c sample-004.c
* [リンク]
* cc -o sample-004.exe sample-004.o
* [実行]
* ./sample-004.exe
*/
/*
* インプットループ
* 入力を繰り返す関数
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* '$' が入力されるまで、文字を入力し、それを二度ずつ出力する
*/
void print_twice_char ( char ch ) {
s_print_char ( ch ); /* とりあえず二度出力 */
s_print_char ( ch );
if ( ch == '$' ) { /* '$' だった / もうこれ以上処理しない */
/* 何もしない */
} else { /* まだ処理する必要がある */
print_twice_char ( s_input_char() ); /* 入力をして、再帰 */
}
}
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
* 最初の呼出しは main で..
*/
print_twice_char ( s_input_char() );
/*
*
*/
return 0;
}
abc$
$ ./sample-004.exe < sample-004.in a aa b bb c cc $ $$$
Download : sample-005.c
/*
* 2017/06/30 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 <stdlib.h> /* rand を利用する場合 */
#include "s_print.h"
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
*
*/
s_print_string ( "乱数を出力します : " );
s_print_int ( rand() );
s_print_newline();
/*
*
*/
return 0;
}
$ ./sample-005.exe 乱数を出力します : 1804289383 $
/*
* 20170623-03-QQQQ.c
*
* 二つの整数の最大公約数を返す
*
* コンパイル :
* cc -I../include -c 20170623-03-QQQQ.c
* cc -o 20170623-03-QQQQ.exe 20170623-03-QQQQ.o
* 実行 :
* ./20170623-03-QQQQ.exe
*
*/
#include <stdio.h>
#include "s_print.h" /* s_print_int を利用するので.. */
/*
* int euclid ( int a, int b )
* int a : 非負の整数
* int b : 非負の整数
* 返り値 : a と b の最大公約数を返す
*/
int euclid ( int a, int b ) {
if ( b == 0 ) { /* 任意の数 a と 0 の最大公約数 (a,0) は a となる */
return a;
} else { /* b が 0 でない時 (a,b) = (b,a%b) となる */
return euclid ( b, a%b );
/* a % b は a を b で割った余りを計算する */
}
}
/*
* main
*/
int main( void )
{
s_print_int ( 12 );
s_print_string ( " と、 " );
s_print_int ( 18 );
s_print_string ( " の最大公約数は " );
s_print_int ( euclid( 12, 18 ) );
s_print_string ( " です。\n" );
s_print_int ( 1111 );
s_print_string ( " と、 " );
s_print_int ( 111111 );
s_print_string ( " の最大公約数は " );
s_print_int ( euclid( 1111, 111111 ) );
s_print_string ( " です。\n" );
return 0;
}
/*
* CDATE FILENAME
*
* 数当てを行う
*/
#include <stdio.h>
#include "s_print.h" /* s_print_int を利用するので.. */
#include "s_input.h" /* s_input_int を利用するので.. */
/*
* 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 ) { /* 入力が、答えより大きい */
s_print_string ( "その数は大きすぎます。\n" );
} else { /* 入力が、答えより小さい */
s_print_string ( "その数は小さすぎます。\n" );
}
/* 未だ、答えが、当っていないので、ゲームを続ける.. */
/* 再帰呼び出しをする */
/* インプット・ループなので、入力からして再帰 */
game(prompt(),answer);
/* prompt() で、入力をしてから、ゲームを続ける */
}
}
/*
* main
*/
int main( void )
{
/* 乱数系列の変更 */
srand((unsigned) time(NULL));
/*
これによって、毎回異なる問題が作られる
[参考文献]
http://www9.plala.or.jp/sgwr-t/lib/srand.html
*/
s_print_string ( "私が考えた 1 〜 100 数を予想して当ててみてください。\n" );
game ( prompt(), (rand()%100) + 1 );
/*
ゲームを始めるまえに、最初の入力を済ませる必要がある
ゲームの問題は、rand()を使って行う
rand() -- 整数値の乱数を返す
%100 する事によって、この数は 0 ? 99 になるので、
これに 1 を加えることにより、 1 ? 100 になる
*/
return 0;
}
#include <stdio.h>
/*
"Hello, World" を無限に繰り返す
引数を指定いない
「終わり」が判断できない
再帰呼び出しをすると、無限ループ
実行を開始すると、止まらない
止めるには、Ctrl-C ( [Ctrl] + [c] ) で、強制終了
最悪は、terminal を閉じれば、自動的に強制終了になる
*/
void infinity_loop_print_hello(void) {
printf ( "Hello, World\n" );
infinity_loop_print_hello(); /* 無条件に自分を再帰呼び出し */
}
int main(int argc, char *argv[]) {
infinity_loop_print_hello();
return 0;
}
#include <stdio.h>
/*
"Hello, World" を n 回繰り返す
繰り返し回数を引数で指定
*/
void ntimes_loop_print_hello( int n ) {
if ( n <= 0 ) { /* 繰り返し回数は 0 以下.. */
/* なにもしなくてよい */
} else { /* 繰り返す必要がある */
printf ( "Hello, World\n" ); /* とりあえず 1 回 */
ntimes_loop_print_hello( n - 1 ); /* 残りは再帰呼び出し */
/* 引数である n の値がどんどん減ってゆく */
/* n の値が 0 以下になったら「終了」する */
/* 引数 n によって、実行が「制御」されている */
}
}
int main(int argc, char *argv[]) {
ntimes_loop_print_hello( 10 ); /* 丁度 10 回、出力する */
return 0;
}
#include <stdio.h>
#include "s_print.h"
int f(int x) {
return x * x; /* 引数 x の二乗を返す関数 */
}
int main(int argc, char *argv[]) {
s_print_string ( "3 の二乗は " );
s_print_int ( f(3) );
s_print_string ( " になります。\n" );
return 0;
}
#include <stdio.h>
#include "s_print.h"
int f(int x) {
return x * x; /* 引数 x の二乗を返す関数 */
}
int main(int argc, char *argv[]) {
s_print_string ( "3 の二乗の 2 倍は " );
s_print_int ( 2 * f(3) );
s_print_string ( " になります。\n" );
s_print_string ( "3 の二乗の 2 倍は " );
s_print_int ( f(3) + f(3) );
s_print_string ( " になります。\n" );
return 0;
}
#include <stdio.h>
#include "s_print.h"
int f(int x) {
s_print_string ( "[[f が呼び出されました]]" );
/* 純粋な計算をしているだけでなく、
「出力」という「副作用」をもつ */
return x * x; /* 引数 x の二乗を返す関数 */
}
int main(int argc, char *argv[]) {
s_print_string ( "3 の二乗の 2 倍は " );
s_print_int ( 2 * f(3) );
s_print_string ( " になります。\n" );
s_print_string ( "3 の二乗の 2 倍は " );
s_print_int ( f(3) + f(3) );
s_print_string ( " になります。\n" );
return 0;
}
/*
* 2017/06/30 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;
}
/*
* 2017/06/30 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;
}
/*
* 2017/06/30 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;
}
/*
* 2017/06/30 sample-004.c
*
* [コンパイル]
* cc -I ~/include -c sample-004.c
* [リンク]
* cc -o sample-004.exe sample-004.o
* [実行]
* ./sample-004.exe
*/
/*
* インプットループ
* 入力を繰り返す関数
*/
#include <stdio.h>
#include "s_input.h"
#include "s_print.h"
/*
* '$' が入力されるまで、文字を入力し、それを二度ずつ出力する
*/
void print_twice_char ( char ch ) {
s_print_char ( ch ); /* とりあえず二度出力 */
s_print_char ( ch );
if ( ch == '$' ) { /* '$' だった / もうこれ以上処理しない */
/* 何もしない */
} else { /* まだ処理する必要がある */
print_twice_char ( s_input_char() ); /* 入力をして、再帰 */
}
}
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
* 最初の呼出しは main で..
*/
print_twice_char ( s_input_char() );
/*
*
*/
return 0;
}
/*
* 2017/06/30 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 <stdlib.h> /* rand を利用する場合 */
#include "s_print.h"
/*
* main 関数
*/
int main ( int argc, char *argv[] ) {
/*
*
*/
s_print_string ( "1:乱数を出力します : " );
s_print_int ( rand() );
s_print_newline();
s_print_string ( "2:乱数を出力します : " );
s_print_int ( rand() );
s_print_newline();
s_print_string ( "3:乱数を出力します : " );
s_print_int ( rand() );
s_print_newline();
/*
*
*/
return 0;
}
前回
「関数」の復習をした
その中で再帰も復習
当初は、「関数」=「命令列に名前を付ける」
再帰を考えると、「再帰関数」は、「複数(原理的には無限)」の長さの命令に相当する
「『可変長』の命令列」に名前をつける
自由な形ではなくて、「『同じ命令』の繰り返し」の形
再帰プログラムの基本構造
関数名(制御変数) {
if ( 制御変数が最低値かどうか ) {
なにもしない
} else {
「何か」一つして(繰り返す命令)
関数名 (制御変数の値を小さくする) 再帰呼び出し
}
}
この再帰的関数は、「何か」を繰り返す関数になっている
値を返す事ができる
return 命令
引数に型が指定できる
! 最初は「文字列」だけだったので「char *」がおまじない
仮引数変数の前には「その変数が保持するデータの型」を書く
整数値の引数の場合は int
文字の引数の場合は char
「文字列」の引数の場合は char *
とそれぞれ型名を記述する
関数の型も同じ
三つの基本的な制御構造
順接
二つの命令 P, Q から関数 f() を作る
f() {
P;Q; ( P をやってから、 Q を行う )
}
# P;Q; と Q;P; は異なる
条件分岐
二つの命令 P, Q と条件 C(x) からから関数 f(x) を作る
f(x) {
if ( C(x) ) { 条件が成立したとき
P;
} else { 不成立の場合は
Q;
}
}
もし C(x) が成立したら P, そうでなければ Q を実行
条件 C によって P と Q どちらか一方を実行
再帰
制御変数 x と、最低値を判定する C(x),と、
値を小さくする φ(x) ( φ(x)は x をより小さくし、
これを繰り返し適用すると、いつかは C(x) が成立する)
繰り返す命令 P があったとき
f(x) {
if ( C(x) ) { 最低値
なにもしない
} else {
P;
f(φ(x)); 再帰呼び出し
引数に関数φを適用する事によい
引数の値が「小さく」なる
}
}
前回の課題の 2
階乗の計算をする
factrial(int n) : n が自然数の時に n! を計算
# n = 0, 1, 2,... とし「0! = 1」と決める
1 (n=0 の時)
fcatrial(n) = {
n * fcatrial(n-1) (n>0 の時)
# 計算機(C 言語)では、「再帰的定義」
# 数学では、「帰納的定義」
int factrial(int n) {
if ( n <= 0 ) { /* なぜ == でなく <= かというと安全性を取った */
return 1; /* n <= 0 の時は n! = 1 とする */
} else {
return n * factrial ( n - 1 );
}
/* ここにくることはない */
}
この問題のポイント
作成したい「階乗の関数」が、最初から「帰納的」に定義されている
そのまま、「再帰」で実現できる
/* 数学証明表現は機械的にその問題を解くプログラムにできる */
/* 二次方程式の解の存在証明を読むと、実は、解の公式が導出できる
解の公式=解を求めるプログラム(アルゴリズム)
と考えてよい */
もし、作りたい関数が、帰納的に定義されていなかったら ?
-> 帰納的に定義しなおす必要がある
<= これは、関数の値の存在証明とほぼ同じ
-> 数学の人間は、問題を「証明」で解く事により、プログラムが作れる
再帰の考え方 : 帰納法の考え方
全体を、一つと残り(残りも全体と同じ構造を持つ)に分ける
ユークリッドの互除法
a,b : 自然数 ( 0 以上の整数 )
の最大公約数を (a,b) で表現する事にする
[R.1] (a,0) = a
[R.2] (a,b) = (b,r) # r は a を b で割ったときの余り
上記の性質を利用すると、最大公約数を求める手続き
0.(a,b) を求めたい ( a, b >= 0 )
1.もし、b が 0 なら答えは a である (R.1) ので
a を答えとして終了
2. そうでなければ、a を b で割ったあまり(r とする)を求め、
(b,r) を求めればよい (R.2:帰納的)
a (b=0 の時)
gcm(a,b) = {
gcm(b,a%b) (b>0 の時)
# a%b : a を b で割った余り
C 言語の関数としては、帰納法で実現可能
int gcm(int a, int b) {
if ( b == 0 ) {
return a;
} else {
return gcm(b,a%b);
/*
a>b の時に、 b と a%b
a<b の時は、 a と b%a
とあるが、プログラムでは ??
常に、b と a%b だけど大丈夫 ??
a>b の時は、もちろん、 a と a%b で OK
a<b の時は、どうなるか ?
b と a%b
b と a
再度 gcm を呼び出すと
a と b%a ( a>b が保証されている )
gcm(12,16)
-> gcm(16,12%16)
-> gcm(16,12)
-> gcm(12,16%12)
-> gcm(12,4)
-> gcm(4,12%4)
-> gcm(4,0)
-> 4
*/
}
}
gcm(a,b) -> gcm(b,a%b)
a>b の時 a%b は、b より小さくなる
a,b の小さい方を取ると、
a,b の場合 b
b,a%b の場合は a%b
「小さく」なる
a<b の時
a, b%a (gcm が二度呼ばれた後に)
a,b の小さいほうは a
a, b%a の小さいは b%a
「小さく」なる
[副作用]
入出力を伴う関数は、「副作用」をもっている
純粋な関数とはいえない
特に入力に関しては、入力関数を呼び出すたびに、プログラムは
入力待ちになり、そのたびに「データの入力を促す」事になる
もし、入力結果を再度利用したい場合はどうするか ?
入力関数を二度呼び出すと、二度入力作業が必要になり、
(同じ値をしていないと..) 異なった値になる
「入力値を二度利用する場合」は、「入力関数を二度呼んではいけない」
同じ値を、何度も利用する場合 : 変数を利用する
変数に値が設定されていれば、同じ変数を利用する事により、同じ値を何度も参照可能
ところが、「変数を利用するには関数を作る必要がある」
なので、入力値は、関数の引数に与える事になる
[乱数]
rand() ライブラリ関数
乱数値を返す関数
呼び出すたびに、(一般には..)異なる値を返す
その値は(一応..)予想できない(事になっている)
数当てゲーム
一方が、一定の範囲(例 : 1 から 100)の数を決める
他方が、それを予想する
予想値を相手に伝える
あっていれば、「あたり」いう
あってなければ、「おきいかちいさいか」を答える
さらに、予想を続ける
Download : 20170630-01.c
/*
* CDATE FILENAME
*
* 数当てを行う
*/
#include <stdio.h>
#include "s_print.h" /* s_print_int を利用するので.. */
#include "s_input.h" /* s_input_int を利用するので.. */
/*
* 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_print_string ( "私が考えた 1 〜 100 数を予想して当ててみてください。\n" );
game ( prompt(), (rand()%100) + 1 );
return 0;
}
50 75 83 90 85 84
$ ./20170630-01-QQQQ.exe 私が考えた 1 〜 100 数を予想して当ててみてください。 私が選んだ数を予想して入力してください : 50 その数は小さすぎます。 私が選んだ数を予想して入力してください : 75 その数は小さすぎます。 私が選んだ数を予想して入力してください : 83 その数は小さすぎます。 私が選んだ数を予想して入力してください : 90 その数は大きすぎます。 私が選んだ数を予想して入力してください : 85 その数は大きすぎます。 私が選んだ数を予想して入力してください : 84 お見事です。あたりました。 $
Download : 20170630-02.c
/*
* CDATE FILENAME
*
* 与えられた自然数の素因数を出力する
*
* 12 は..
*
*
*
*
*
*
*/
#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;
}
$ ./20170630-02-QQQQ.exe 12の素因数分解は 2 2 3 となります。 $