Powered by SmartDoc

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

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

目次

講義資料

当日の OHP 資料

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

サンプルファイル

Download : sample-001.c ( SJIS 版 )

sample-001.c
/*
 * 2014/12/12 sample-001.c
 */

/*
 *
 */

#include <stdio.h>

/*
 *
 */

int main ( int ac, char *av[] ) {
	int stack[1000];	/* 配列サイズは適当(充分に大きく取ってあると *仮定*) */
	int stack_pointer;	/* sp */
	int data;			/* データ */

		/*
				「スタック」の設計方針
					「スタック」は、「下から上に積む」物として考える
					「スタックポインター(sp)」は、「次にデータを積む場所」と考える

						...
					+-----------+
				2	|			|
					+-----------+
				1	|			|
					+-----------+
				0	|			|		<- sp (stack_pointer) == 0
			--------+-----------+-----
		*/

		/*
		 * スタックを利用する前に、スタックの初期化を行う
		 */

	stack_pointer = 0;	/* 初期状態では、空 (sp == 0) */

		/*
		 * 最初にスタックに 100 を積む : push ( 100 )
		 */

	data = 100;							/* データは 100 */
	printf ( "スタックに %d を積みます。\n", data );

	stack [ stack_pointer ] = data;		/* 現在の場所にデータを保存 */
	stack_pointer = stack_pointer + 1;	/* スタックポインターは「次」を指す */

		/*
				データは「現在の場所」に保存され、
				sp が「次の場所」を指すようになる

						...
					+-----------+
				2	|			|
					+-----------+
				1	|			|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|		スタックトップには 100 が入る
			--------+-----------+-----
		*/

		/*
		 * スタックに 123 を積む : push ( 123 )
		 */

	data = 123;
	printf ( "スタックに %d を積みます。\n", data );

	stack [ stack_pointer ] = data;
	stack_pointer = stack_pointer + 1;

		/*

						...
					+-----------+
				2	|			|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	123		|		スタックトップには 123 が入る
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックに 999 を積む  : push ( 999 )
		 */

	data = 999;
	printf ( "スタックに %d を積みます。\n", data );

	stack [ stack_pointer ] = data;
	stack_pointer = stack_pointer + 1;

		/*

						...
					+-----------+
				3	|			|		<- sp (stack_pointer) == 3
					+-----------+
				2	|	999		|		スタックトップには 999 が入る
					+-----------+
				1	|	123		|
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 999 が取り出される
		 */

	stack_pointer = stack_pointer - 1;	/* まず、sp を戻す */
	data = stack [ stack_pointer ];		/* sp が指す先がスタックトップ */

	printf ( "スタックから取出したデータは %d です。\n", data );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	123		|
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * もう一度スタックからデータを取り出す : pop() => 123 が取り出される
		 */

	stack_pointer = stack_pointer - 1;
	data = stack [ stack_pointer ];

	printf ( "スタックから取出したデータは %d です。\n", data );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- データは消えない(が、利用禁止 !!)
					+-----------+
				1	|	123		|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックに 876 を積む  : push ( 876 )
		 */

	data = 876;
	printf ( "スタックに %d を積みます。\n", data );

	stack [ stack_pointer ] = data;
	stack_pointer = stack_pointer + 1;

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	876		|		<- データは上書き(領域は再利用)
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 876 が取り出される
		 */

	stack_pointer = stack_pointer - 1;
	data = stack [ stack_pointer ];

	printf ( "スタックから取出したデータは %d です。\n", data );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|
					+-----------+
				1	|	876		|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 100 が取り出される
		 */

	stack_pointer = stack_pointer - 1;
	data = stack [ stack_pointer ];

	printf ( "スタックから取出したデータは %d です。\n", data );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|
					+-----------+
				1	|	876		|
					+-----------+
				0	|	100		|		<- sp (stack_pointer) == 0 : 空っぽ
			--------+-----------+-----
		*/

	return 0;
}

/*
 *
 */
sample-001.c の実行結果
C:\usr\c>sample-001
スタックに 100 を積みます。
スタックに 123 を積みます。
スタックに 999 を積みます。
スタックから取出したデータは 999 です。
スタックから取出したデータは 123 です。
スタックに 876 を積みます。
スタックから取出したデータは 876 です。
スタックから取出したデータは 100 です。
C:\usr\c> 

Download : sample-002.c ( SJIS 版 )

sample-002.c
/*
 * 2014/12/12 sample-002.c
 */

/*
 *
 */

#include <stdio.h>

/*
 *
 */

#include "int_stack.h"

/*
 *
 */

void push_and_print ( IntStack *isp, int data ) {

	printf ( "スタックに %d を積みます。\n", data );

	push_int_stack ( isp, data );	/* data を push */

}

/*
 *
 */

int pop_and_print ( IntStack *isp ) {
	int data;

	data = pop_int_stack ( isp );	/* data を pop */

	printf ( "スタックから取出したデータは %d です。\n", data );
	
	return data;
}

/*
 *
 */

int main ( int ac, char *av[] ) {
	IntStack stack;		/* スタックの宣言 */

		/*
		 * スタックを利用する前に、スタックの初期化を行う
		 */

	clear_int_stack ( &stack );	/* ポインターを渡す */

		/*
				「スタック」の設計方針
					「スタック」は、「下から上に積む」物として考える
					「スタックポインター(sp)」は、「次にデータを積む場所」と考える

						...
					+-----------+
				2	|			|
					+-----------+
				1	|			|
					+-----------+
				0	|			|		<- sp (stack_pointer) == 0
			--------+-----------+-----
		*/

		/*
		 * 最初にスタックに 100 を積む : push ( 100 )
		 */

	push_and_print ( &stack, 100 );

		/*
				データは「現在の場所」に保存され、
				sp が「次の場所」を指すようになる

						...
					+-----------+
				2	|			|
					+-----------+
				1	|			|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|		スタックトップには 100 が入る
			--------+-----------+-----
		*/

		/*
		 * スタックに 123 を積む : push ( 123 )
		 */

	push_and_print ( &stack, 123 );

		/*

						...
					+-----------+
				2	|			|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	123		|		スタックトップには 123 が入る
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックに 999 を積む  : push ( 999 )
		 */

	push_and_print ( &stack, 999 );

		/*

						...
					+-----------+
				3	|			|		<- sp (stack_pointer) == 3
					+-----------+
				2	|	999		|		スタックトップには 999 が入る
					+-----------+
				1	|	123		|
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 999 が取り出される
		 */

	pop_and_print ( &stack );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	123		|
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * もう一度スタックからデータを取り出す : pop() => 123 が取り出される
		 */

	pop_and_print ( &stack );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- データは消えない(が、利用禁止 !!)
					+-----------+
				1	|	123		|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックに 876 を積む  : push ( 876 )
		 */

	push_and_print ( &stack, 876 );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|		<- sp (stack_pointer) == 2
					+-----------+
				1	|	876		|		<- データは上書き(領域は再利用)
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 876 が取り出される
		 */

	pop_and_print ( &stack );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|
					+-----------+
				1	|	876		|		<- sp (stack_pointer) == 1
					+-----------+
				0	|	100		|
			--------+-----------+-----
		*/

		/*
		 * スタックからデータを取り出す : pop() => 100 が取り出される
		 */

	pop_and_print ( &stack );

		/*

						...
					+-----------+
				3	|			|
					+-----------+
				2	|	999		|
					+-----------+
				1	|	876		|
					+-----------+
				0	|	100		|		<- sp (stack_pointer) == 0 : 空っぽ
			--------+-----------+-----
		*/

	return 0;
}

/*
 *
 */
sample-002.c の実行結果
C:\usr\c>sample-002
スタックに 100 を積みます。
スタックに 123 を積みます。
スタックに 999 を積みます。
スタックから取出したデータは 999 です。
スタックから取出したデータは 123 です。
スタックに 876 を積みます。
スタックから取出したデータは 876 です。
スタックから取出したデータは 100 です。
C:\usr\c> 

Download : int_stack.h ( SJIS 版 )

int_stack.h
/*
 * int_stack.h
 *
 */

#ifndef	_INT_STACK_H_
#define	_INT_STACK_H_

/*
 * Stack Size
 */

#define	INT_STACK_SIZE	100		/* 	充分に大きな数と *期待* する */

/*
 *	IntStack 型の定義
 */

typedef	struct	{
  int stack [ INT_STACK_SIZE ];		/* スタックの本体 */
  int sp;							/* sp : スタックポインター */
} IntStack;							/* IntStack 型の定義 */

/*
 *	IntStack 操作 (プロトタイプ宣言)
 */

extern void clear_int_stack ( IntStack *isp );
extern void pushd_int_stack ( IntStack *isp, int data );
extern int pop_int_stack ( IntStack *isp );

/*
 *
 */

#endif

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

本日の課題

課題 20141212-03 : Point2D 型に対応した myprintf を拡張して作る(先週の課題)

Download : 20141212-03.c ( SJIS 版 )

20141212-03.c
/*
 * 20141212-03-QQQQ.c
 * Point2D 型に対応した myprintf を拡張して作る
 */

#include <stdio.h>
#include "s_print.h"
#include "s_input.h"

/*
 *
 */

typedef struct {
		int x;
		int y;
} Point2D;

/*
 * 複数の引数を書式指定して文字列の中に埋め込む 
 */

void myprintf ( char *msg, ... ) {
  int i;
  char *pvalue = (char *)&msg + sizeof( char * );
  Point2D pv;

  for ( i = 0; msg[i] != EOS; i++ ) {
	if ( msg[i] == '%' ) {		/* 文字列の中に '%' があったら特別処理する */
	  i++; 						/* 次の文字をみる */
	  switch ( msg[i] ) {
	  case 'd':					/* 10 進数 */
		s_print_int ( *((int *)pvalue) );
		pvalue += sizeof ( int );
		break;
	  case 'o':					/* 8 進数 */
		s_print_int ( *((int *)pvalue) );
		pvalue += sizeof ( int );
		break;
	  case 'x':					/* 16 進数 */
		s_print_int ( *((int *)pvalue) );
		pvalue += sizeof ( int );
		break;
	  case 'c':					/* 文字 */
		s_print_char ( *((char *)pvalue) );
		pvalue += sizeof ( int );	/* char は自動的に int にされる */
		break;
	  case 's':					/* 文字列 */
		s_print_string ( *((char **)pvalue) );
		pvalue += sizeof ( char * );
		break;
	  case 'f':					/* 浮動小数点数 */
		s_print_double ( *((double *)pvalue) );
		pvalue += sizeof ( double );
		break;
	  case 'D':					/* Point2D 型 */
		pv = *((Point2D *)pvalue);
			/* pv の値を (%d,%d) の形式で出力する */

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

			/* 次のデータを処理するために pvalue 変更 */

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

		break;
	  case '%':					/* '%' が重なったら.. */
		s_print_char ( '%' );	/* '%' を出力 */
		break;
	  default:					/* その他 : よくわからないので読み飛ばす.. */
		  break;
	  }
	} else {	/* そうでなけれ .. */
	  s_print_char ( msg[i] );	/* そのままその文字を出力 */
	}
  }
}

/*
 * 色々な数値の出力
 */

int main ( void ) {
	Point2D pv;

	pv.x = 2;
	pv.y = -3;

  /*
   * データの出力 (Output)
   */

  myprintf ( 
					 "整数値(%%d) : %d, 文字(%%c) : '%c', 文字列(%%s) : \"%s\", 浮動小数点数(%%f) : %f, \
    点の座標 (%%D) : %D\n",
					 123, (int)'a', "xyz" , 1.23, pv );

  /*
   * 
   */

  return 0;
}

/*
 *
 */
20141212-03.c の実行結果
C:\usr\c\> 20141212-03-QQQQ
整数値(%d) : 123, 文字(%c) : 'a', 文字列(%s) : "xyz", 浮動小数点数(%f) : \
    1.230000, 点の座標 (%D) : (2,-3)
C:\usr\c\>