Powered by SmartDoc

ソフトウェア概論A/B (2014/05/30)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

Download

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

サンプルファイル

Download : sample-001.c ( SJIS 版 )

sample-001.c
/*
 * 2014/05/30 sample-001.c
 */

/*
 *	最初は取り敢えず「Hello, World」
 */

#include <stdio.h>

int main ( void ) {

  printf ( "Hello, World\n" );	/* "Hello, World" を出力 */

  return 0;
}
sample-001.c の実行結果
C:\usr\c>sample-001
Hello, World
C:\usr\c> 

Download : sample-002.c ( SJIS 版 )

sample-002.c
/*
 * 2014/05/30 sample-002.c
 */

/*
 *	順接 : 「Hello, World」を二度出す
 */

#include <stdio.h>

int main ( void ) {

  printf ( "Hello, World\n" );	/* "Hello, World" を出力 */
  printf ( "Hello, World\n" );	/* 命令を並べれば、並べた通りに実行 */

  return 0;
}
sample-002.c の実行結果
C:\usr\c>sample-002
Hello, World
Hello, World
C:\usr\c> 

Download : sample-003.c ( SJIS 版 )

sample-003.c
/*
 * 2014/05/30 sample-003.c
 */

/*
 *	異る命令の実行
 */

#include <stdio.h>

int main ( void ) {

  printf ( "1 : Hello, World\n" );	/* 一度目の "Hello, World" を出力 */
  printf ( "2 : Hello, World\n" );	/* ニ度目、「並べた順」に実行される */

  return 0;
}
sample-003.c の実行結果
C:\usr\c>sample-003
1 : Hello, World
2 : Hello, World
C:\usr\c> 

Download : sample-004.c ( SJIS 版 )

sample-004.c
/*
 * 2014/05/30 sample-004.c
 */

/*
 *	「順接」の繰返し
 *		A,B,C,D,E,F = (((((A,B),C),D),E),F)
 *			6 行の命令は、順接を 5 回行ったと考える
 */

#include <stdio.h>

int main ( void ) {

  printf ( "1 : Hello, World\n" );
  printf ( "2 : Hello, World\n" );
  printf ( "3 : Hello, World\n" );
  printf ( "4 : Hello, World\n" );
  printf ( "5 : Hello, World\n" );
  printf ( "6 : Hello, World\n" );

  return 0;
}
sample-004.c の実行結果
C:\usr\c> cc -c sample-004.c
sample-004.c:17:3: 警告: 組み込み関数 ‘printf’ の互換性がない暗黙的な宣言です [デフォルトで有効]

Download : sample-005.c ( SJIS 版 )

sample-005.c
/*
 * 2014/05/30 sample-005.c
 */

/*
 *	「順接」の繰返し
 *		ブロック( {, } ) を利用して明示的に記述
 */

#include <stdio.h>

int main ( void ) {

	{
		{
  			{
  				{
					printf ( "1 : Hello, World\n" );
			  		printf ( "2 : Hello, World\n" );
				}
				printf ( "3 : Hello, World\n" );
			}
			printf ( "4 : Hello, World\n" );
		}
		printf ( "5 : Hello, World\n" );
	}
	printf ( "6 : Hello, World\n" );

	return 0;
}
sample-005.c の実行結果
C:\usr\c>sample-005
1 : Hello, World
2 : Hello, World
3 : Hello, World
4 : Hello, World
5 : Hello, World
6 : Hello, World
C:\usr\c> 

Download : sample-006.c ( SJIS 版 )

sample-006.c
/*
 * 2014/05/30 sample-006.c
 */

/*
 *	「順接」の繰返し
 *		同じ命令の繰返し
 */

#include <stdio.h>

int main ( void ) {

	printf ( "Hello, World\n" );	/* 「Hello, World」を 6 度 */
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );

	return 0;
}
sample-006.c の実行結果
C:\usr\c>sample-006
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
C:\usr\c> 

Download : sample-007.c ( SJIS 版 )

sample-007.c
/*
 * 2014/05/30 sample-007.c
 */

/*
 *	命令列に名前を付ける (関数の作成)
 */

#include <stdio.h>

/*
	命令の断片「printf ( "Hello, World\n" );」に printHello という名前を付ける
*/

void printHello(void) {				/* 関数の定義 */
	printf ( "Hello, World\n" );	/* 「Hello, World」を出力する関数 */
}

int main ( void ) {

	printHello();					/* 元々あったものと同じ */
									/* 命令は、「関数名」で「呼出し」可能 */
									/* 表現が「短く」なった */		
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );
	printf ( "Hello, World\n" );

	return 0;
}
sample-007.c の実行結果
C:\usr\c>sample-007
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
C:\usr\c> 

Download : sample-008.c ( SJIS 版 )

sample-008.c
/*
 * 2014/05/30 sample-008.c
 */

/*
 *	「関数の呼出し」の繰返し
 */

#include <stdio.h>

void printHello(void) {
	printf ( "Hello, World\n" );
}

int main ( void ) {

	printHello();		/* 一度定義した関数は何度でも呼出し可能 */
	printHello();
	printHello();
	printHello();
	printHello();
	printHello();

	return 0;
}
sample-008.c の実行結果
C:\usr\c>sample-008
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
C:\usr\c> 

Download : sample-009.c ( SJIS 版 )

sample-009.c
/*
 * 2014/05/30 sample-009.c
 */

/*
 *	関数の本体には「命令列」が記述できる
 */

#include <stdio.h>

void printHello(void) {
	printf ( "Hello, World\n" );	/* 「Hello, World」を出力する関数 */
}

void printTwoHello(void) {			/* printHello を二度呼ぶ */
	 printHello();					/* 本体には、「命令列」でもよい */
	 printHello();
}

int main ( void ) {

	printTwoHello();	/* printTwoHello() を三度呼ぶ */
	printTwoHello();	/* 結果的に printHello() が六度呼ばれる */
	printTwoHello();	/* 最終的に 「Hello, World」が六行出力される */

	return 0;
}
入力例
A
sample-009.c の実行結果
C:\usr\c>sample-009<  sample-009.in
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
Hello, World
C:\usr\c> 

Download : sample-010.c ( SJIS 版 )

sample-010.c
/*
 * 2014/05/30 sample-010.c
 */

/*
 *	似た命令の関数化 [1]
 */

#include <stdio.h>

int main ( void ) {

	printf ( "1 : Hello, World\n" );	/* 命令が異っている場合は.. */
	printf ( "2 : Hello, World\n" );
	printf ( "3 : Hello, World\n" );
	printf ( "4 : Hello, World\n" );
	printf ( "5 : Hello, World\n" );
	printf ( "6 : Hello, World\n" );

	return 0;
}
sample-010.c の実行結果
C:\usr\c>sample-010
1 : Hello, World
2 : Hello, World
3 : Hello, World
4 : Hello, World
5 : Hello, World
6 : Hello, World
C:\usr\c> 

Download : sample-011.c ( SJIS 版 )

sample-011.c
/*
 * 2014/05/30 sample-011.c
 */

/*
 *	似た命令の関数化 [2] : 異る部分と同じ部分にわける
 */

#include <stdio.h>

int main ( void ) {

	printf ( "1" );					/* 異る部分 */
	printf ( " : Hello, World\n" );	/* 同じ部分 */

	printf ( "2" );
	printf ( " : Hello, World\n" );	

	printf ( "3" );
	printf ( " : Hello, World\n" );

	printf ( "4" );
	printf ( " : Hello, World\n" );

	printf ( "5" );
	printf ( " : Hello, World\n" );

	printf ( "6" );
	printf ( " : Hello, World\n" );

	return 0;
}
sample-011.c の実行結果
C:\usr\c>sample-011
1 : Hello, World
2 : Hello, World
3 : Hello, World
4 : Hello, World
5 : Hello, World
6 : Hello, World
C:\usr\c> 

Download : sample-012.c ( SJIS 版 )

sample-012.c
/*
 * 2014/05/30 sample-012.c
 */

/*
 *	似た命令の関数化 [3] : 異る部分を「変数化」する事により、関数に出来る
 */

#include <stdio.h>

void printStringHello ( char *X ) {

	printf ( X );					/* 異る部分が変数(X:仮引数)で共通化 */
	printf ( " : Hello, World\n" );	/* 同じ部分 */

}

int main ( void ) {

	printStringHello ( "1" );		/* 異る部分を「実引数」として指定 */

	printStringHello ( "2" );
	printStringHello ( "3" );
	printStringHello ( "4" );
	printStringHello ( "5" );
	printStringHello ( "6" );

	return 0;
}
sample-012.c の実行結果
C:\usr\c>sample-012
1 : Hello, World
2 : Hello, World
3 : Hello, World
4 : Hello, World
5 : Hello, World
6 : Hello, World
C:\usr\c> 

Download : sample-013.c ( SJIS 版 )

sample-013.c
/*
 * 2014/05/30 sample-013.c
 */

/*
 *	似た命令の関数化 [4] : 引数の型
 */

#include <stdio.h>

void printCharHello ( char X ) {	/* 変数の型を char 型に変更 */

	putchar ( X );					/* X を「文字」出力 */
	printf ( " : Hello, World\n" );	/* 同じ部分 */

}

void printCharHello ( char X ) {	/* 変数の型を char 型に変更 */


int main ( void ) {

	printCharHello ( '1' );		/* 引数も「文字」にする必要がある */
	printCharHello ( '2' );
	printCharHello ( '3' );
	printCharHello ( '4' );
	printCharHello ( '5' );
	printCharHello ( '6' );

	return 0;
}
sample-013.c の実行結果
C:\usr\c>sample-013
1 : Hello, World
2 : Hello, World
3 : Hello, World
4 : Hello, World
5 : Hello, World
6 : Hello, World
C:\usr\c> 

Download : sample-014.c ( SJIS 版 )

sample-014.c
/*
 * 2014/05/30 sample-014.c
 */

/*
 *	似た命令の関数化 [5] : 引数の計算
 */

#include <stdio.h>

void printCharHello ( char X ) {	/* 変数の型を char 型に変更 */

	putchar ( X );					/* X を「文字」出力 */
	printf ( " : Hello, World\n" );	/* 同じ部分 */

}

void printTwoCharHello ( char X ) {

	 printCharHello ( X );			/* 一度目は、引数をそのまま */
	 printCharHello ( X + 1 );		/* ニ度目は、引数の値の次の値を利用 */
									/* '1' + 1 -> '2' */
									/* '3' + 1 -> '4' */
									/* '5' + 1 -> '6' */

}

int main ( void ) {

	printCharTwoHello ( '1' );		/* 三度呼ぶと.. */
	printCharTwoHello ( '3' );
	printCharTwoHello ( '5' );		/* 六行.. */

	return 0;
}
sample-014.c の実行結果
C:\usr\c>sample-014
C:\usr\c> 

Download : sample-016.c ( SJIS 版 )

sample-016.c
/*
 * 2014/05/30 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(void) {

	check_star_char ( getchar() );	/* getchar() で文字を読込み、それを出力 */

	return 0;
}
入力例
A
sample-016.c の実行結果
C:\usr\c>sample-016<  sample-016.in
これは「*」ではありません
C:\usr\c> 

Download : sample-113.c ( SJIS 版 )

sample-113.c
/*
 * 2014/05/30 sample-113.c
 */

/*
 *	s_print.h の利用法
 */

#include <stdio.h>
#include "s_print.h"	/* s_print.h を利用する */

/*
 */

int main ( void ) {

	printf ( "s_print_string で「文字列」を出力「" );
	s_print_string ( "1" );		/* 文字列「1」を出力 */
	printf ( "」\n" );

	printf ( "s_print_char で「文字」を出力「" );
	s_print_char ( '1' );		/* 文字「1」を出力 */
	printf ( "」\n" );

	printf ( "s_print_int で「整数値」を出力「" );
	s_print_int ( 1 );			/* 整数値「1」を出力 */
	printf ( "」\n" );

	return 0;
}
sample-113.c の実行結果
C:\usr\c>sample-113
s_print_string で「文字列」を出力「1」
s_print_char で「文字」を出力「1」
s_print_int で「整数値」を出力「1」
C:\usr\c> 

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

本日の課題

課題 20140530-01 : 二つの整数の積を返す関数

Download : 20140530-01.c ( SJIS 版 )

20140530-01.c
/*
 * CDATE FILENAME
 *
 *	二つの整数の積を返す関数
 */

#include <stdio.h>
#include "s_print.h"	/* s_print_int を利用するので.. */

/*
 * int imul ( int a, int b )
 *	int a : かけられる数
 *	int b : かける数
 *  返り値 : a と b の積
 */

int imul ( int a, int b ) {


	/*
	**	 この部分を完成させなさい
	*/


}

/*
 *	main
 */

int main( void )
{

    s_print_int ( 2 );
	s_print_string ( " と、 " );
    s_print_int ( 3 );
	s_print_string ( " の積は " );
    s_print_int ( imul( 2, 3 ) );
	s_print_string ( " です。\n" );

    s_print_int ( 12 );
	s_print_string ( " と、 " );
    s_print_int ( 78 );
	s_print_string ( " の積は " );
    s_print_int ( imul( 12, 78 ) );
	s_print_string ( " です。\n" );

	return 0;
}
20140530-01.c の実行結果
C:\usr\c\> 20140530-01-QQQQ
2 と、 3 の積は 6 です。
12 と、 78 の積は 936 です。
C:\usr\c\> 

課題 20140530-02 : 自然数の階乗を返す関数

Download : 20140530-02.c ( SJIS 版 )

20140530-02.c
/*
 * CDATE FILENAME
 *
 *	自然数の階乗を返す関数
 */

#include <stdio.h>
#include "s_print.h"	/* s_print_int を利用するので.. */

/*
 *	int factrial ( int n )
 *		int n : 階乗を計算する自然数	
 *		返り値 : n! ( n の階乗 )
 */

int factrial ( int n ) {

	if ( n <= 0 ) {	/* 0!, 負の数の階乗は、取り敢えず 1 にする */
		return 1;	/* 特に 「0! = 1」に注意 */
	} else {		/* n が正の時は、「n! = n * (n-1)!」となるので.. */

	/*
	**	 この部分を完成させなさい
	*/

	}
}


/*
 *	main
 */

int main( void )
{

	s_print_int ( 3 );
	s_print_string ( " の階乗の値は " );
	s_print_int ( factrial ( 3 ) );
	s_print_string ( " になります。\n" );

	s_print_int ( 5 );
	s_print_string ( " の階乗の値は " );
	s_print_int ( factrial ( 5 ) );
	s_print_string ( " になります。\n" );

	return 0;
}
入力例
abc123
20140530-02.c の実行結果
C:\usr\c\> 20140530-02-QQQQ
3 の階乗の値は 6 になります。
5 の階乗の値は 120 になります。
C:\usr\c\> 

課題 20140530-03 : 二つの非負の整数の最大公約数を返す(ユークリッドの互除法)

Download : 20140530-03.c ( SJIS 版 )

20140530-03.c
/*
 * CDATE FILENAME
 *
 *	二つの整数の最大公約数を返す
 */

#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) となる */

	/*
	**	 この部分を完成させなさい
	*/

	}
}

/*
 *	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;
}
20140530-03.c の実行結果
C:\usr\c\> 20140530-03-QQQQ
12 と、 18 の最大公約数は 6 です。
1111 と、 111111 の最大公約数は 11 です。
C:\usr\c\> 

Links

その他