Powered by SmartDoc

ソフトウェア概論A/B (2016/11/25)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

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

Download : sample-001.c ( utf8 版 )

sample-001.c
/*
 * 2016/11/18 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 ( utf8 版 )

sample-002.c
/*
 * 2016/11/18 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 ( utf8 版 )

sample-003.c
/*
 * 2016/11/18 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 ( utf8 版 )

sample-004.c
/*
 * 2016/11/18 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 ( utf8 版 )

sample-005.c
/*
 * 2016/11/18 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 ( utf8 版 )

sample-006.c
/*
 * 2016/11/18 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 です。
$ 

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

本日の課題

課題 20161125-01 : 動的なメモリの確保

Download : 20161125-01.c ( utf8 版 )

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

/*
 * 利用方法
 *		コンパイル
 *			cc -I ~/c/include -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
20161125-01.c の実行結果
$ ./20161125-01-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
$