Powered by SmartDoc

ソフトウェア概論A/B (2019/12/13)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

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

Download : sample-001.c

sample-001.c
/*
 * 2019/12/06 sample-001.c
 *
 *	ポインター型変数の利用
 *
 */

#include <stdio.h>
#include <malloc.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-001.exe sample-001.c
 *		実行
 *			./sample-001.exe
 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int v;			/* 整数型の変数を確保 */
	int *p = &v;	/* ポインター型変数 p に v のポインター値を代入する */

	/* *p は、変数 v と全く同じに振る舞う */

	*p = 1;
	printf ( "*p = %d\n", *p );
	printf ( "v = %d\n", v );

	*p = *p + 10;
	printf ( "*p = %d\n", *p );
	printf ( "v = %d\n", v );

	return 0;
}
sample-001.c の実行結果
$ ./sample-001.exe
*p = 1
v = 1
*p = 11
v = 11
$ 

Download : sample-002.c

sample-002.c
/*
 * 2019/12/06 sample-002.c
 *
 *	動的領域の確保 (単純変数)
 *
 */

#include <stdio.h>
#include <malloc.h>		/* calloc/free を利用する場合に必要 */

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-002.exe sample-002.c
 *		実行
 *			./sample-002.exe
 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int *p;

	/* 整数型変数の領域を 1 つ分確保 */
	p = (int *)calloc ( 1, sizeof(int) );

	if ( p == NULL ) {	/* メモリの確保に失敗した場合は NULL が返る */
		printf ( "整数領域のメモリ確保に失敗しました。\n" );
	} else {

		/* 以下は、*p を普通の整数型変数と同じ様に利用できる */

		*p = 1;
		printf ( "*p = %d\n", *p );

		*p = *p + 10;
		printf ( "*p = %d\n", *p );


		/* 動的に確保したメモリは最後に必ず、free で解放する */

		free ( p );
	}

	return 0;
}
sample-002.c の実行結果
$ ./sample-002.exe
*p = 1
*p = 11
$ 

Download : sample-003.c

sample-003.c
/*
 * 2019/12/06 sample-003.c
 *
 *	ポインター型変数の利用(2)
 *
 */

#include <stdio.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-003.exe sample-003.c
 *		実行
 *			./sample-003.exe
 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int a[10];		/* 整数型の配列を確保 */
	int *p = a;		/* ポインター型変数 p に a の先頭の要素のポインター値を代入する */

	/* p は、配列名 a と全く同じに振る舞う */

	p[2] = 1;
	printf ( "p[2] = %d\n", p[2] );
	printf ( "a[2] = %d\n", a[2] );

	p[4] = p[2] + 10;
	printf ( "p[4] = %d\n", p[4] );
	printf ( "a[4] = %d\n", a[4] );

	return 0;
}
sample-003.c の実行結果
$ ./sample-003.exe
p[2] = 1
a[2] = 1
p[4] = 11
a[4] = 11
$ 

Download : sample-004.c

sample-004.c
/*
 * 2019/12/06 sample-004.c
 *
 *	動的領域の確保 (配列)
 *
 */

#include <stdio.h>
#include <malloc.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-004.exe sample-004.c
 *		実行
 *			./sample-004.exe
 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int *p;

	/* 整数型変数の領域を 10 つ分確保 */
	p = (int *)calloc ( 10, sizeof(int) );

	if ( p == NULL ) {	/* メモリの確保に失敗した場合は NULL が返る */
		printf ( "整数領域のメモリ確保に失敗しました。\n" );
	} else {

		/* 以下は、p を普通の整数型配列名と同じ様に利用できる */

		p[2] = 1;
		printf ( "p[2] = %d\n", p[2] );

		p[4] = p[2] + 10;
		printf ( "p[4] = %d\n", p[4] );

		/* 動的に確保したメモリは最後に必ず、free で解放する */

		free ( p );
	}

	return 0;
}
sample-004.c の実行結果
$ ./sample-004.exe
p[2] = 1
p[4] = 11
$ 

Download : sample-005.c

sample-005.c
/*
 * 2019/12/06 sample-005.c
 *
 *	不定長の入力 (最大値が存在)
 *
 */

#include <stdio.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-005.exe sample-005.c
 *		実行
 *			./sample-005.exe
 */

#define	MAX_OF_INPUT_SIZE	10		/* 入力できるデータ数 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int array[MAX_OF_INPUT_SIZE];		/* 整数型の配列を確保 */
	int n;								/* 入力される整数値の個数 */
	int i;

	printf ( "データ数を入力してください : " );
	scanf ( "%d", &n );

	if ( ( 0 <= n ) && ( n < MAX_OF_INPUT_SIZE ) ) {
		for ( i = 0; i < n; i++ ) {
			printf ( "%d 番目の数値を入力してください : ", i + 1 );
			scanf ( "%d", &array[i] );
		}

		printf ( "入力された内容は以下の通りです。\n" );
		for ( i = 0; i < n; i++ ) {
			printf ( "%d 番目の数値は %d です。\n", i + 1, array[i] );
		}
	} else {
		printf ( "データ数(%d)が異常です。\n", n );
	}

	return 0;
}
入力例
5
453
32
-239
0
294
sample-005.c の実行結果
$ ./sample-005.exe < sample-005.in
データ数を入力してください : 5
1 番目の数値を入力してください : 453
2 番目の数値を入力してください : 32
3 番目の数値を入力してください : -239
4 番目の数値を入力してください : 0
5 番目の数値を入力してください : 294
入力された内容は以下の通りです。
1 番目の数値は 453 です。
2 番目の数値は 32 です。
3 番目の数値は -239 です。
4 番目の数値は 0 です。
5 番目の数値は 294 です。
$ 

Download : sample-006.c

sample-006.c
/*
 * 2019/12/06 sample-006.c
 *
 *	不定長の入力 (動的に領域を確保)
 *
 */

#include <stdio.h>
#include <malloc.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -o sample-006.exe sample-006.c
 *		実行
 *			./sample-006.exe
 */

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	int *parray;		/* 整数型の配列の先頭 */
	int n;				/* 入力される整数値の個数 */
	int i;

	printf ( "データ数を入力してください : " );
	scanf ( "%d", &n );

	if ( 0 <= n ) {
		if ( ( parray = (int *)calloc( n, sizeof(int) ) ) != NULL ) {
			for ( i = 0; i < n; i++ ) {
				printf ( "%d 番目の数値を入力してください : ", i + 1 );
				scanf ( "%d", &parray[i] );
			}

			printf ( "入力された内容は以下の通りです。\n" );
			for ( i = 0; i < n; i++ ) {
				printf ( "%d 番目の数値は %d です。\n", i + 1, parray[i] );
			}

			free ( parray );
		} else {
			printf ( "整数領域のメモリ確保に失敗しました。\n" );
		}
	} else {
		printf ( "データ数(%d)が異常です。\n", n );
	}

	return 0;
}
入力例
15
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
sample-006.c の実行結果
$ ./sample-006.exe < sample-006.in
データ数を入力してください : 15
1 番目の数値を入力してください : 1
2 番目の数値を入力してください : 2
3 番目の数値を入力してください : 3
4 番目の数値を入力してください : 4
5 番目の数値を入力してください : 5
6 番目の数値を入力してください : 6
7 番目の数値を入力してください : 7
8 番目の数値を入力してください : 8
9 番目の数値を入力してください : 9
10 番目の数値を入力してください : 0
11 番目の数値を入力してください : 1
12 番目の数値を入力してください : 2
13 番目の数値を入力してください : 3
14 番目の数値を入力してください : 4
15 番目の数値を入力してください : 5
入力された内容は以下の通りです。
1 番目の数値は 1 です。
2 番目の数値は 2 です。
3 番目の数値は 3 です。
4 番目の数値は 4 です。
5 番目の数値は 5 です。
6 番目の数値は 6 です。
7 番目の数値は 7 です。
8 番目の数値は 8 です。
9 番目の数値は 9 です。
10 番目の数値は 0 です。
11 番目の数値は 1 です。
12 番目の数値は 2 です。
13 番目の数値は 3 です。
14 番目の数値は 4 です。
15 番目の数値は 5 です。
$ 

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

本日の課題

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

課題 20191213-01 : 「三角形の形」をした配列

Download : 20191213-01.c

20191213-01.c
/*
 * 20190111-01-QQQQ.c
 *
 *	三角形の形をした配列
 *
 */

/*
 * 利用方法
 *		コンパイル
 *			cc -o BASENAME.exe FILENAME
 *		実行
 *			./BASENAME.exe
 */

#include <stdio.h>

#define ARRAY_SIZE_N	10	

/*
 *
 *	0	a[0][0]
 *	1	a[1][0], a[1][1]
 *	3	a[2][0], a[2][1], a[2][2]
 *	6		..
 *		a[9][0], a[9][1], a[9][2], .., a[9][9]
 *
 */

int get_tri ( int *ary, int n, int m ) {


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

}

void set_tri ( int *ary, int n, int m, int value ) {


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


}


/*
 * main
 */

int main ( int argc, char *argv[] ) {
	int triary[ARRAY_SIZE_N*(ARRAY_SIZE_N+1)/2];
	int n;
	int m;
	int i;

	for ( n = 0; n < ARRAY_SIZE_N; n++ ) {
		for ( m = 0; m <= n; m++ ) {
			set_tri ( triary, n, m, n * 100 + m );
		}
	}

	for ( i = 0; i < ARRAY_SIZE_N*(ARRAY_SIZE_N+1)/2; i++ ) {
		printf ( "triary[%d] = %d\n", i, triary[i] );
	}

	for ( n = 0; n < ARRAY_SIZE_N; n++ ) {
		for ( m = 0; m <= n; m++ ) {
			printf ( "triary[%d][%d] = %d\n", n, m, get_tri( triary, n, m ) );
		}
	}

	return 0;
}
20191213-01.c の実行結果
$ ./20191213-01-QQQQ.exe
triary[0] = 0
triary[1] = 100
triary[2] = 101
triary[3] = 200
triary[4] = 201
triary[5] = 202
triary[6] = 300
triary[7] = 301
triary[8] = 302
triary[9] = 303
triary[10] = 400
triary[11] = 401
triary[12] = 402
triary[13] = 403
triary[14] = 404
triary[15] = 500
triary[16] = 501
triary[17] = 502
triary[18] = 503
triary[19] = 504
triary[20] = 505
triary[21] = 600
triary[22] = 601
triary[23] = 602
triary[24] = 603
triary[25] = 604
triary[26] = 605
triary[27] = 606
triary[28] = 700
triary[29] = 701
triary[30] = 702
triary[31] = 703
triary[32] = 704
triary[33] = 705
triary[34] = 706
triary[35] = 707
triary[36] = 800
triary[37] = 801
triary[38] = 802
triary[39] = 803
triary[40] = 804
triary[41] = 805
triary[42] = 806
triary[43] = 807
triary[44] = 808
triary[45] = 900
triary[46] = 901
triary[47] = 902
triary[48] = 903
triary[49] = 904
triary[50] = 905
triary[51] = 906
triary[52] = 907
triary[53] = 908
triary[54] = 909
triary[0][0] = 0
triary[1][0] = 100
triary[1][1] = 101
triary[2][0] = 200
triary[2][1] = 201
triary[2][2] = 202
triary[3][0] = 300
triary[3][1] = 301
triary[3][2] = 302
triary[3][3] = 303
triary[4][0] = 400
triary[4][1] = 401
triary[4][2] = 402
triary[4][3] = 403
triary[4][4] = 404
triary[5][0] = 500
triary[5][1] = 501
triary[5][2] = 502
triary[5][3] = 503
triary[5][4] = 504
triary[5][5] = 505
triary[6][0] = 600
triary[6][1] = 601
triary[6][2] = 602
triary[6][3] = 603
triary[6][4] = 604
triary[6][5] = 605
triary[6][6] = 606
triary[7][0] = 700
triary[7][1] = 701
triary[7][2] = 702
triary[7][3] = 703
triary[7][4] = 704
triary[7][5] = 705
triary[7][6] = 706
triary[7][7] = 707
triary[8][0] = 800
triary[8][1] = 801
triary[8][2] = 802
triary[8][3] = 803
triary[8][4] = 804
triary[8][5] = 805
triary[8][6] = 806
triary[8][7] = 807
triary[8][8] = 808
triary[9][0] = 900
triary[9][1] = 901
triary[9][2] = 902
triary[9][3] = 903
triary[9][4] = 904
triary[9][5] = 905
triary[9][6] = 906
triary[9][7] = 907
triary[9][8] = 908
triary[9][9] = 909
$ 

課題 20191213-02 : 動的なメモリの利用

Download : 20191213-02.c

20191213-02.c
/*
 * DATE-02-QQQQ.c
 *
 *	動的なメモリの確保
 *		キーボードより正の整数を幾つか入力して、その要素が入った配列を返す
 *		0 以下の整数が入力されたら、終了とする
 *		配列のサイズは、正の整数の個数 + 1 とし、最後の要素には 0 を入れる
 */

/*
 * 利用方法
 *		コンパイル
 *			cc -o BASENAME.exe FILENAME
 *		実行
 *			./BASENAME.exe
 */

#include <stdio.h>
#include <malloc.h>		/* calloc/free を利用するので必要 */

/*
 *	read_n_integers
 */

int	*read_n_integers( int size ) {
	int num;			/* キーボードから入力された数値を保存する */
	int *value;			/* 確保された配列の先頭要素へのポインター */

	printf ( "正の整数値を入力してください(0 以下だと入力を終了します):" );
	scanf ( "%d", &num );

	if ( num <= 0 ) {	/* 入力が全部終ったので、配列を作成する */

		/* 配列のサイズは、引数で指定された個数 + 1 となる */
		if ( ( value = (int *)calloc ( size + 1, sizeof ( int ) ) ) != NULL ) {

			/* 動的メモリは取り出せるとは限らないので、結果をチェック */
			value[ size ] = 0;	/* 最後の要素として 0 を代入 */

		} /* else {} */ /* NULL が帰った場合は、そのまま、値として返す */
	} else {	/* 入力が終っていないので、更に、値を読むために再帰呼び出し */

		if ( ( value = read_n_integers( size + 1 ) ) != NULL ) {
			/* 結果が NULL でなければ、配列が作られている */

			/* size 番目の要素を配列に記録 */

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

		} /* else {} */ /* NULL が帰った場合は、そのまま、値として返す */
	}

	/* いずれの場合でも value を返す */

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

}

/*
 * main
 */

int main ( int argc, char *argv[] ) {
	int *array;		/* n 個数の要素をもつ配列の先頭をもつ */
	int i;

	/* read_n_integers を呼び出して、n 個の整数値を入力する */
	/* 引数には、入力済のデータ数を指定するので、最初は 0 を指定する */

	if ( ( array = read_n_integers( 0 ) ) != NULL ) {
		/* read_n_integers は、NULL を返す可能性がある */

		/* 入力された要素を画面に出力 */
		for ( i = 0; array[i] > 0; i++ ) {
			printf ( "%d th data = %d\n", i, array[i] );
		}

		/* malloc/calloc で確保したメモリは、必ず free で解放する */


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


	} /* else {} */	/* NULL の場合はエラーなので、何もしない */

	return 0;
}
入力例
12
34
5
6
90
-1
20191213-02.c の実行結果
$ ./20191213-02-QQQQ.exe
正の整数値を入力してください(0 以下だと入力を終了します):12
正の整数値を入力してください(0 以下だと入力を終了します):34
正の整数値を入力してください(0 以下だと入力を終了します):5
正の整数値を入力してください(0 以下だと入力を終了します):6
正の整数値を入力してください(0 以下だと入力を終了します):90
正の整数値を入力してください(0 以下だと入力を終了します):-1
0 th data = 12
1 th data = 34
2 th data = 5
3 th data = 6
4 th data = 90
$