Powered by SmartDoc

ソフトウェア概論A/B (2021/07/02)
Ver. 1.0

2021年7月2日
栗野 俊一
kurino@math.cst.nihon-u.ac.jp
http://edu-gw2.math.cst.nihon-u.ac.jp/~kurino/2021/soft/soft.html
ソフトウェア概論 A/B2021年7月2日 の資料

目次

講義資料

当日の OHP 資料

Download

講義で利用するサンプルプログラム

Download : sample-001.c

sample-001.c
/*
 * 2021/07/02 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.c の実行結果
$ ./sample-001.exe < sample-001.in
整数値を一つ入力してください、一つ増やした値を出力します:123
124
$ 

Download : sample-002.c

sample-002.c
/*
 * 2021/07/02 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.c の実行結果
$ ./sample-002.exe < sample-002.in
一回目:整数値を一つ入力してください、一つ増やした値を出力します:123
124
ニ回目:整数値を一つ入力してください、一つ増やした値を出力します:456
457
$ 

Download : sample-003.c

sample-003.c
/*
 * 2021/07/02 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.c の実行結果
$ ./sample-003.exe < sample-003.in
123
整数値 123 に 1 を加えた値は 124これを 2 倍した値は 246 になります。
456
整数値 456 に 1 を加えた値は 457これを 2 倍した値は 912 になります。
$ 

Download : sample-004.c

sample-004.c
/*
 * 2021/07/02 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.c の実行結果
$ ./sample-004.exe < sample-004.in
abc$
aabbcc$$

$ 

Download : sample-005.c

sample-005.c
/*
 * 2021/07/02 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.c の実行結果
$ ./sample-005.exe
乱数を出力します : 725633840
$ 

講議中に作成したプログラム

本日の課題

課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。

課題 20210702-01 : 数当てをするプログラム

Download : 20210702-01.c

20210702-01.c
/*
 * 20210702-01-QQQQ.c
 *
 *	数当てを行う
 *
 *	コンパイル :
 *		cc -I ~/c/include -c 20210702-01-QQQQ.c
 *		cc -o 20210702-01-QQQQ.exe 20210702-01-QQQQ.o
 *	実行 :
 *		./20210702-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
20210702-01.c の実行結果
$ ./20180928-01-QQQQ.exe
私が考えた 1 〜 100 の数を予想して当ててみてください。
私が選んだ数を予想して入力してください : 5
5
その数は小さすぎます。
私が選んだ数を予想して入力してください : 60
60
その数は大きすぎます。
私が選んだ数を予想して入力してください : 30
30
お見事です。あたりました。
$

課題 20210702-02 : 与えられた自然数の素因数を表示するプログラム

Download : 20210702-02.c

20210702-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;
}
20210702-02.c の実行結果
$ ./20210702-02-QQQQ.exe
12の素因数分解は 2 2 3 となります。
$ 

課題 20210702-03 : フィボナッチ数列の第 n 項を返す関数

Download : 20210702-03.c

20210702-03.c
/*
 * 20210702-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
20210702-03.c の実行結果
$ ./20210702-03-QQQQ.exe
整数値 n を入力してください : 4
4 番目のフィボナッチ数は 3 です。
整数値 n を入力してください : 10
10 番目のフィボナッチ数は 55 です。
$