Powered by SmartDoc

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

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

目次

講義資料

当日の OHP 資料

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

サンプルファイル

Download : sample-001.c ( SJIS 版 )

sample-001.c
/*
 * 2014/11/07 sample-001.c
 */

/*
 *  関数への引数渡し(単純型変数版)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * func
 *		整数(int)型単純変数の仮引数
 */

void func ( int var ) {

	printf ( "Func[1] : var = %d\n", var );	/* 引数の値を出力 */

	var = - var;							/* 引数の値の符号を変更 */

	printf ( "Func[2] : var = %d\n", var );	/* 引数の値を再度出力 */
											/* 仮引数変数の値は変化している */
											/* その変更は、main には影響しない */
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int v = 123;	/* 整数(int)型単純変数の引数 */

	printf ( "Main[1] : v = %d\n", v );	/* v を出力 */
	func ( v );	   						/* func を呼び出す時に v の値を渡す */
	printf ( "Main[2] : v = %d\n", v );	/* v を出力 */
										/* 変数 v の値は変更されない */
										/* 渡されているのは「値」のみ */

	func ( 456 );	/* 引数には定数も OK */
					/* そもそも変更の対象となる変数がない */
					/* 誤解(変数そのものを渡す)の可能性はない */
	return 0;
}
sample-001.c の実行結果
C:\usr\c>sample-001
Main[1] : v = 123
Func[1] : var = 123
Func[2] : var = -123
Main[2] : v = 123
Func[1] : var = 456
Func[2] : var = -456
C:\usr\c> 

Download : sample-002.c ( SJIS 版 )

sample-002.c
/*
 * 2014/11/07 sample-002.c
 */

/*
 *  関数への引数渡し(構造体型変数版)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * 構造体型の定義
 */

typedef struct {	/* 新しい構造体型の宣言 */
	int x;
	int y;
} Point2D;			/* 二次元の点型 */

/*
 * func
 *		構造体型変数の仮引数
 */

void func ( Point2D pt ) {

	printf ( "Func[1] : pt.x = %d, pt.y = %d\n", pt.x, pt.y );

	pt.x = pt.x + 1;	/* x は一つふやす */
	pt.y = pt.y - 1;	/* y は一つ減らす */

	printf ( "Func[2] : pt.x = %d, pt.y = %d\n", pt.x, pt.y );
			/* 引数の値を再度出力 */
			/* 仮引数変数の値は変化している */
			/* その変更は、main には影響しない */
}

/*
 *	main
 *
 */

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

	pa.x = 12;
	pa.y = 34;

	printf ( "Main[1] : pa.x = %d, pa.y = %d\n", pa.x, pa.y );
	func ( pa );		/* 関数を呼び出す時に構造体型の変数 pa を指定 */
	printf ( "Main[2] : pa.x = %d, pa.y = %d\n", pa.x, pa.y );
						/* 関数の中の変更は、呼出し側の変数に影響しない */
						/* 渡されているのは「値」のみ */

	return 0;
}
sample-002.c の実行結果
C:\usr\c>sample-002
Main[1] : pa.x = 12, pa.y = 34
Func[1] : pt.x = 12, pt.y = 34
Func[2] : pt.x = 13, pt.y = 33
Main[2] : pa.x = 12, pa.y = 34
C:\usr\c> 

Download : sample-003.c ( SJIS 版 )

sample-003.c
/*
 * 2014/11/07 sample-003.c
 */

/*
 *  関数への引数渡し(配列型変数版)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-003.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * func
 *		配列型変数の引数
 */

void func ( int array[2] ) {

	printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] );

	array[0] = array[0] + 1;
	array[1] = array[1] - 1;

	printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] );
			/* 引数の値を再度出力 */
			/* 仮引数変数の値は変化している */
			/* その変更は、main には影響しない ... ????? */
}

/*
 *	main
 *
 */

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

	ia[0] = 12;
	ia[1] = 34;

	printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] );
	func ( ia );		/* 関数を呼び出す時に「配列名」を指定する */
						/* 「ia[2]」ではない事に注意 */
	printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] );
						/* 関数の中の変更が、呼出し側の変数に影響 !!!! */
						/* 「値」が渡されるのでは ??? */
						/* この内容説明については後日 */
						/* 今回は、「そうゆうもの」と考える */

	return 0;
}
sample-003.c の実行結果
C:\usr\c>sample-003
Main[1] : ia[0] = 12, ia[1] = 34
Func[1] : array[0] = 12, array[1] = 34
Func[1] : array[0] = 13, array[1] = 33
Main[1] : ia[0] = 13, ia[1] = 33
C:\usr\c> 

Download : sample-004.c ( SJIS 版 )

sample-004.c
/*
 * 2014/11/07 sample-004.c
 */

/*
 *  関数への引数渡し(副作用の問題)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * funcArray
 *		配列型変数の引数
 */

void funcArray ( int array[1] ) {

	printf ( "Func[1] : array[0] = %d\n", array[0] );
	array[0] = - array[0];
	printf ( "Func[2] : array[0] = %d\n", array[0] );

		/* 結果的に呼出し元の変数の値を変更していまう(副作用がある) */
}

/*
 * funcSimple
 *		単純型変数の引数
 */

void funcSimple ( int simple ) {

	printf ( "Func[1] : simple = %d\n", simple );
	simple = -simple;
	printf ( "Func[1] : simple = %d\n", simple );
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int ia[1];	/* サイズ 1 !! の配列 */
	int is;		/* 単純変数 */

	ia[0] = 12;
	is = 34;

	/* Test 1 : 単純変数 */
	printf ( "<Test 1>\n" );
	printf ( "Main[1-1] : is = %d\n", is );
	funcSimple ( is );
	printf ( "Main[1-2] : is = %d\n", is );
		/* 影響はない */
		/* 関数を呼んでも、main の変数の値は変更されない
			→ 気を付かう必要がない
		*/

	/* Test 2 : 配列変数 */
	printf ( "<Test 2>\n" );
	printf ( "Main[2-1] : ia[0] = %d\n", ia[0] );
	funcArray ( ia );						   		/* 配列名を指定 */
	printf ( "Main[2-2] : ia[0] = %d\n", ia[0] );
		/* 影響がある */
		/* 関数を呼ぶと、main の変数の値は変更されてしまう(副作用)
			→ 気を付かう必要がでてしまう ( ia の値は変更されるのされないの ? )
		*/

	/*
		関数を呼ぶと(代入文でないのに..) 変数の値値が変る事が前にも..
			→ scanf
	*/

	return 0;
}
sample-004.c の実行結果
C:\usr\c>sample-004
<Test 1>
Main[1-1] : is = 34
Func[1] : simple = 34
Func[1] : simple = -34
Main[1-2] : is = 34
<Test 2>
Main[2-1] : ia[0] = 12
Func[1] : array[0] = 12
Func[2] : array[0] = -12
Main[2-2] : ia[0] = -12
C:\usr\c> 

Download : sample-005.c ( SJIS 版 )

sample-005.c
/*
 * 2014/11/07 sample-005.c
 */

/*
 *  関数への引数渡し(配列型と単純変数の比較)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-005.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * funcArray
 *		配列型変数の引数
 */

void funcArray ( int array[1] ) {

	printf ( "Func[1] : array[0] = %d\n", array[0] );
	array[0] = - array[0];
	printf ( "Func[2] : array[0] = %d\n", array[0] );
}

/*
 * funcSimple
 *		単純型変数の引数
 */

void funcSimple ( int simple ) {

	printf ( "Func[1] : simple = %d\n", simple );
	simple = -simple;
	printf ( "Func[1] : simple = %d\n", simple );
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int ia[1];	/* サイズ 1 !! の配列 */
	int is;		/* 単純変数 */

	ia[0] = 12;
	is = 34;

	/* Test 1 : 単純変数 */
	printf ( "<Test 1>\n" );
	printf ( "Main[1-1] : is = %d\n", is );
	funcSimple ( is );
	printf ( "Main[1-2] : is = %d\n", is );
		/* 影響はない */

	/* Test 2 : 配列変数 */
	printf ( "<Test 2>\n" );
	printf ( "Main[2-1] : ia[0] = %d\n", ia[0] );
	funcArray ( ia );							/* 配列名を指定 */
	printf ( "Main[2-2] : ia[0] = %d\n", ia[0] );
		/* 影響がある */

	/* Test 3 : 配列要素 */
	printf ( "<Test 3>\n" );
	printf ( "Main[3-1] : ia[0] = %d\n", ia[0] );
	funcSimple ( ia[0] );						/* 配列要素を指定 */
	printf ( "Main[3-2] : ia[0] = %d\n", ia[0] );
		/* 影響はない */

	/* Test 4 : 幻のテスト */
	/* printf ( "<Test 4>\n" ); */
	/* printf ( "Main[4-1] : is = %d\n", is ); */
	/* funcArray ( is ); */						/* ココでエラーになる !! */
	/* printf ( "Main[4-2] : is = %d\n", is ); */

	/* Test 5 : & を付けると .. ? */
	printf ( "<Test 5>\n" );
	printf ( "Main[5-1] : is = %d\n", is );
	funcArray ( &is );							/* 何だコリャ ???? */
	printf ( "Main[5-2] : is = %d\n", is );
		/* 影響がある !? */
		/* scanf と同じ効果 ??? */
		/* 謎は深まるばかりだが... */

	return 0;
}
sample-005.c の実行結果
C:\usr\c>sample-005
<Test 1>
Main[1-1] : is = 34
Func[1] : simple = 34
Func[1] : simple = -34
Main[1-2] : is = 34
<Test 2>
Main[2-1] : ia[0] = 12
Func[1] : array[0] = 12
Func[2] : array[0] = -12
Main[2-2] : ia[0] = -12
<Test 3>
Main[3-1] : ia[0] = -12
Func[1] : simple = -12
Func[1] : simple = 12
Main[3-2] : ia[0] = -12
<Test 5>
Main[5-1] : is = 34
Func[1] : array[0] = 34
Func[2] : array[0] = -34
Main[5-2] : is = -34
C:\usr\c> 

Download : sample-006.c ( SJIS 版 )

sample-006.c
/*
 * 2014/11/07 sample-006.c
 */

/*
 *  関数への引数渡し(配列を要素に持つ構造体変数版)
 *
 * 利用方法
 *		コンパイル
 *			cc -Ic:\usr\c\include -o BASENAME.exe sample-006.c
 *		実行
 *			BASENAME
 */

#include <stdio.h>

/*
 * 構造体型の定義
 */

typedef struct {	/* 新しい構造体型の宣言 */
	int x[2];		/* 構造体の要素が配列になっている */
} Point2D;			/* 二次元の点型 */

/*
 * func
 *		配列を要素に持つ構造体型変数の仮引数
 */

void func ( Point2D pt ) {

	printf ( "Func[1] : pt.x[0] = %d, pt.x[1] = %d\n", pt.x[0], pt.x[1] );

	pt.x[0] = pt.x[0] + 1;	/* x[0] は一つふやす */
	pt.x[1] = pt.x[1] - 1;	/* x[1] は一つ減らす */

	printf ( "Func[1] : pt.x[0] = %d, pt.x[1] = %d\n", pt.x[0], pt.x[1] );
			/* 引数の値を再度出力 */
			/* 仮引数変数の値は変化している */
			/* その変更は、main には影響しない */
}

/*
 *	main
 *
 */

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

	pa.x[0] = 12;
	pa.x[1] = 34;

	printf ( "Main[1] : pa.x[0] = %d, pa.x[1] = %d\n", pa.x[0], pa.x[1] );
	func ( pa );		/* 関数を呼び出す時に構造体型の変数 pa を指定 */
	printf ( "Main[2] : pa.x[0] = %d, pa.x[1] = %d\n", pa.x[0], pa.x[1] );
						/* 関数の中の変更は、呼出し側の変数に影響しない */
						/* 渡されているのは「値」のみ */
						/* 構造体型の変数は中に配列があっても OK */

	return 0;
}
sample-006.c の実行結果
C:\usr\c>sample-006
Main[1] : pa.x[0] = 12, pa.x[1] = 34
Func[1] : pt.x[0] = 12, pt.x[1] = 34
Func[1] : pt.x[0] = 13, pt.x[1] = 33
Main[2] : pa.x[0] = 12, pa.x[1] = 34
C:\usr\c> 

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

本日の課題

課題 20141107-01 : Othell.c (2014/11/07 版)

Links

開発手法

Waterfall Model