Powered by SmartDoc

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

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

目次

講義資料

当日の OHP 資料

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

Download : sample-006.c

sample-006.c
/*
 * 2018/12/21 sample-006.c
 */

/*
 * メモリモデルの理解 (6)
 *
 * 利用方法
 *		コンパイル 
 *			cc -I ~/c/include -c sample-006.c
 *		リンク 
 *			cc -o sample-006.exe sample-006.c 
 *		実行
 *			./sample-006.exe
 */

#include <stdio.h>
#include "s_variable.h"	/* memory モデルを理解するための関数定義 */

/*
 * main
 */

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

  /*
   * C 言語の文字列のメモリモデルによる理解
   */

	/*
	 * 文字列はアドレスをもっている
	 */

	printf ( "文字列 \"abc\" のアドレスは 16 進数表現で %x です。\n",
		get_string_address( "abc" )
	);

	/*
	 * 文字列の要素をアドレスを利用して参照
	 */

	printf ( "文字列 \"abc\" の先頭の文字は %c  です。\n",
		get_variable_value_at ( get_string_address( "abc" ) )
	);

	/*
	 * 文字列の要素の二つ目以後を取り出す
	 */

	printf ( "文字列 \"abc\" の先頭の次の文字は %c です。\n",
		get_variable_value_at ( get_string_address( "abc" ) + 1 )
	);

	printf ( "文字列 \"abc\" の先頭の次の次の文字は %c です。\n",
		get_variable_value_at ( get_string_address( "abc" ) + 2 )
	);

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-006.c の実行結果
$ ./sample-006.exe
文字列 "abc" のアドレスは 16 進数表現で 401480 です。
文字列 "abc" の先頭の文字は a  です。
文字列 "abc" の先頭の次の文字は b です。
文字列 "abc" の先頭の次の次の文字は c です。
$ 

Download : sample-007.c

sample-007.c
/*
 * 2018/12/21 sample-007.c
 */

/*
 * メモリモデルの理解 (7)
 *
 * 利用方法
 *		コンパイル 
 *			cc -I ~/c/include -c sample-007.c
 *		リンク 
 *			cc -o sample-007.exe sample-007.c 
 *		実行
 *			./sample-007.exe
 */

#include <stdio.h>
#include "s_variable.h"	/* memory モデルを理解するための関数定義 */

/*
 * main
 */

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

  /*
   * C 言語の変数のメモリモデルによる理解
   */

	char cvar;		/* char 型の変数 cvar の宣言 */
	char dvar;		/* char 型の変数 dvar の宣言 */
	char evar;		/* char 型の変数 evar の宣言 */

	/*
	 * 変数を並べてて宣言すると (偶然..) アドレスが連続していた..
	 */

	printf ( "変数 cvar のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( cvar )
	);

	printf ( "変数 dvar のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( dvar )
	);

	printf ( "変数 evar のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( evar )
	);

	/*
	 * 変数をアドレスを利用して参照
	 */

	cvar = 'c';			/* 変数 cvar に、値 'c' を代入 */
	dvar = 'D';			/* 変数 dvar に、値 'D' を代入 */
	evar = '\0';		/* 変数 evar に、値 '\0' を代入 */

	printf ( "cvar の所から記録されている文字列は (%s) です。\n",
		get_variable_address( cvar )
	);

  /*
   *	アドレス経由で、変数の内容を変更
   */

   set_variable_value_at ( get_variable_address( cvar ) + 1, 'x' );
		/* 変数 cvar のアドレスの次のアドレスは dvar のアドレスなので.. */

	printf ( "cvar に記録されている文字は %c です。\n",
		cvar
	);

		/* 結果的に、dvar の内容が書き変わる */

	printf ( "dvar に記録されている文字は %c です。\n",
		dvar
	);

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-007.c の実行結果
$ ./sample-007.exe
変数 cvar のアドレスは 16 進数表現で b766a30d です。
変数 dvar のアドレスは 16 進数表現で b766a30e です。
変数 evar のアドレスは 16 進数表現で b766a30f です。
cvar の所から記録されている文字列は (cD) です。
cvar に記録されている文字は c です。
dvar に記録されている文字は x です。
$ 

Download : sample-008.c

sample-008.c
/*
 * 2018/12/21 sample-008.c
 */

/*
 * メモリモデルの理解 (8)
 *
 * 利用方法
 *		コンパイル 
 *			cc -I ~/c/include -c sample-008.c
 *		リンク 
 *			cc -o sample-008.exe sample-008.c 
 *		実行
 *			./sample-008.exe
 */

#include <stdio.h>
#include "s_variable.h"	/* memory モデルを理解するための関数定義 */

/*
 * main
 */

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

  /*
   * C 言語の変数のメモリモデルによる理解
   */

	char carray[3];	/* char 型の一次元配列 carray の宣言 (サイズは 3)  */

		/*
			意味的には
				char carry[0];		-- cvar
				char carry[1];		-- dvar
				char carry[2];		-- evar
			のように考えて良い (cf. sample-007.c)
		*/

	/*
	 * 配列の要素のアドレスは連続している事が保証される
	 */

	printf ( "変数 carray[0] のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( carray[0] )
	);

	printf ( "変数 carray[1] のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( carray[1] )
	);

	printf ( "変数 carray[2] のアドレスは 16 進数表現で %x です。\n",
		get_variable_address( carray[2] )
	);

	/*
	 * 変数をアドレスを利用して参照
	 */

	carray[0] = 'c';		/* 変数 carray[0] に、値 'c' を代入 */
	carray[1] = 'D';		/* 変数 carray[1] に、値 'D' を代入 */
	carray[2] = '\0';		/* 変数 carray[2] に、値 '\0' を代入 */

	printf ( "carray[0] の所から記録されている文字列は (%s) です。\n",
		get_variable_address( carray[0] )
	);

  /*
   *	アドレス経由で、変数の内容を変更
   */

   set_variable_value_at ( get_variable_address( carray[0] ) + 1, 'x' );
		/* 変数 carray[0] のアドレスの次のアドレスは carray[1] のアドレスなので.. */

	printf ( "carray[0] に記録されている文字は %c です。\n",
		carray[0]
	);

		/* 結果的に、carray[1] の内容が書き変わる */

	printf ( "carray[1] に記録されている文字は %c です。\n",
		carray[1]
	);

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-008.c の実行結果
$ ./sample-008.exe
変数 carray[0] のアドレスは 16 進数表現で 9ec9bb0 です。
変数 carray[1] のアドレスは 16 進数表現で 9ec9bb1 です。
変数 carray[2] のアドレスは 16 進数表現で 9ec9bb2 です。
carray[0] の所から記録されている文字列は (cD) です。
carray[0] に記録されている文字は c です。
carray[1] に記録されている文字は x です。
$ 

Download : sample-009.c

sample-009.c
/*
 * 2018/12/21 sample-009.c
 */

/*
 * メモリモデルの理解 (9)
 *
 * 利用方法
 *		コンパイル 
 *			cc -I ~/c/include -c sample-009.c
 *		リンク 
 *			cc -o sample-009.exe sample-009.c 
 *		実行
 *			./sample-009.exe
 */

#include <stdio.h>
#include "s_variable.h"	/* memory モデルを理解するための関数定義 */

/*
 * main
 */

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

  /*
   * 
   */

	char carray[3];	/* char 型の一次元配列 carray の宣言 (サイズは 3)  */

	/*
	 * 配列の要素のアドレスは連続している事が保証される
	 */

	carray[0] = 'c';		/* 変数 carray[0] に、値 'c' を代入 */
	carray[1] = 'D';		/* 変数 carray[1] に、値 'D' を代入 */
	carray[2] = '\0';		/* 変数 carray[2] に、値 '\0' を代入 */

	printf ( "carray[0] の所から記録されている文字列は (%s) です。\n",
		get_variable_address( carray[0] )
	);

  /*
   *	配列名は、文字列と同じように扱える
   */

	printf ( "carray が表現している文字列は (%s) です。\n",
		carray
	);

  /*
   *	文字列の一部を変更する事ができる
   */

	carray[1] = 'U';		/* ニ文字目を 'U' に変更 */

	printf ( "carray が表現している文字列は (%s) です。\n",
		carray
	);

	carray[0] = 'p';		/* 一字目を 'p' に変更 */

	printf ( "carray が表現している文字列は (%s) です。\n",
		carray
	);

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-009.c の実行結果
$ ./sample-009.exe
carray[0] の所から記録されている文字列は (cD) です。
carray が表現している文字列は (cD) です。
carray が表現している文字列は (cU) です。
carray が表現している文字列は (pU) です。
$ 

Download : sample-010.c

sample-010.c
/*
 * 2018/12/21 sample-010.c
 */

/*
 * 文字配列と文字列
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-010.c
 *		リンク 
 *			cc -o sample-010.exe sample-010.c 
 *		実行
 *			./sample-010.exe
 */

#include <stdio.h>

/*
 * main
 */

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

  /*
   * 	文字配列の初期化
   */

	char carray[3] = "AB";

		/*
			carray[0] = 'A';
			carray[1] = 'B';
			carray[2] = '\0';
		*/

	printf ( "carray[0] は %c です。\n",
		carray[0]
	);

	printf ( "carray[1] は %c です。\n",
		carray[1]
	);

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-010.c の実行結果
$ ./sample-010.exe
carray[0] は A です。
carray[1] は B です。
$ 

Download : sample-011.c

sample-011.c
/*
 * 2018/12/21 sample-011.c
 */

/*
 * アドレス演算子「&」と間接演算子「*」
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-011.c
 *		リンク 
 *			cc -o sample-011.exe sample-011.c 
 *		実行
 *			./sample-011.exe
 */

#include <stdio.h>

/*
 * main
 */

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

  /*
   * 	アドレス演算子「&」と間接演算子「*」
   */

	char carray[3] = "AB";

  /*
   *	添字による参照
   */

	printf ( "carry[0] = %c\n", carry[0] );
	printf ( "carry[1] = %c\n", carry[1] );

  /*
   *	間接演算子による参照
   */

	printf ( "*carry = %c\n", *carry );
	printf ( "*(carry+1) = %c\n", *(carry+1) );

  /*
   *	address の比較
   */

	s_print_string ( "&carry[0] = %x\n", &carry[0] );
	s_print_string ( "carry = %x\n", carry );

  /*
   *	「&」と「*」は逆演算子
   */

	s_print_string ( "carry = %x\n", carry );
	s_print_string ( "&*carry = %x\n", &*carry );

	s_print_string ( "carry[0] = %c\n", carry[0] );
	s_print_string ( "*&carry[0] = %c\n", *&carry[0] );

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-011.c の実行結果
$ ./sample-011.exe
carray[0] は A です。
carray[1] は B です。
$ 

Download : sample-012.c

sample-012.c
/*
 * 2018/12/21 sample-012.c
 */

/*
 * 二次元配列とメモリモデル (1)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-012.c
 *		リンク 
 *			cc -o sample-012.exe sample-012.c 
 *		実行
 *			./sample-012.exe
 */

#include <stdio.h>

/*
 *	◯×ゲームのボード (一次元版)
 *
 *               y
 *         0     1     2			    (y,t)
 *		+-----+-----+-----+            +-----+
 *	  0	|(0,0)|(0,1)|(0,2)|            |(0,0)| 0 = 0*3+0 = t*3+y
 *		+-----+-----+-----+            +-----+
 * t  1	|(1,0)|(1,1)|(1,2)|            |(0,1)| 1 = 0*3+1 = t*3+y
 *		+-----+-----+-----+            +-----+
 *	  2	|(2,0)|(2,1)|(2,2)|            |(0,2)| 2 = 0*3+2 = t*3+y
 *		+-----+-----+-----+            +-----+
 *									   |(1,0)| 3 = 1*3+0 = t*3+y
 *									   +-----+
 *									   |(1,1)| 4 = 1*3+1 = t*3+y
 *									   +-----+
 *									   |(1,2)| 5 = 1*3+2 = t*3+y
 *									   +-----+
 *									   |(2,0)| 6 = 2*3+0 = t*3+y
 *									   +-----+
 *									   |(2,1)| 7 = 2*3+1 = t*3+y
 *									   +-----+
 *									   |(2,2)| 8 = 2*3+2 = x*3+y
 *									   +-----+
 *
 */

#define	BOARD_SIZE	3	/* ボードのサイズ */

#define	SENTE_MARK	'o'	/* 先手は 'o' (マル) */
#define	GOTE_MARK	'x'	/* 後手は 'x' (バツ) */

/*
 * main
 */

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

  /*
   *
   */

   char board[BOARD_SIZE*BOARD_SIZE];	/* サイズは 3 × 3 */
   int t;								/* 縱 */
   int y;								/* 横 */

  /*
   * ある局面
   *
   *     oxx
   *     xoo
   *     oox                             
   */

   board[0*BOARD_SIZE+0] = 'o';	/* (0,0) */
   board[0*BOARD_SIZE+1] = 'x';	/* (0,1) */
   board[0*BOARD_SIZE+2] = 'x';	/* (0,2) */

   board[1*BOARD_SIZE+0] = 'x';	/* (1,0) */
   board[1*BOARD_SIZE+1] = 'o';	/* (1,1) */
   board[1*BOARD_SIZE+2] = 'o';	/* (1,2) */

   board[2*BOARD_SIZE+0] = 'o';	/* (2,0) */
   board[2*BOARD_SIZE+1] = 'x';	/* (2,1) */
   board[2*BOARD_SIZE+2] = 'x';	/* (2,2) */

  /*
   *
   */

   t = 0;
   while ( t < BOARD_SIZE ) {
   	 y = 0;
     while ( y < BOARD_SIZE ) {
	   printf ( "%c", board[t*BOARD_SIZE+y] );
	   y = y + 1;
	 }
	 printf ( "\n" );
	 t = t + 1;
  }

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-012.c の実行結果
$ ./sample-012.exe
oxx
xoo
oxx
$ 

Download : sample-013.c

sample-013.c
/*
 * 2018/12/21 sample-013.c
 */

/*
 * 二次元配列とメモリモデル (2)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-013.c
 *		リンク 
 *			cc -o sample-013.exe sample-013.c 
 *		実行
 *			./sample-013.exe
 */

#include <stdio.h>

/*
 *	◯×ゲームのボード (一次元版)
 *
 *               y
 *         0     1     2			    (y,t)
 *		+-----+-----+-----+            +-----+
 *	  0	|(0,0)|(0,1)|(0,2)|            |(0,0)| 0 = 0*3+0 = t*3+y
 *		+-----+-----+-----+            +-----+
 * t  1	|(1,0)|(1,1)|(1,2)|            |(0,1)| 1 = 0*3+1 = t*3+y
 *		+-----+-----+-----+            +-----+
 *	  2	|(2,0)|(2,1)|(2,2)|            |(0,2)| 2 = 0*3+2 = t*3+y
 *		+-----+-----+-----+            +-----+
 *									   |(1,0)| 3 = 1*3+0 = t*3+y
 *									   +-----+
 *									   |(1,1)| 4 = 1*3+1 = t*3+y
 *									   +-----+
 *									   |(1,2)| 5 = 1*3+2 = t*3+y
 *									   +-----+
 *									   |(2,0)| 6 = 2*3+0 = t*3+y
 *									   +-----+
 *									   |(2,1)| 7 = 2*3+1 = t*3+y
 *									   +-----+
 *									   |(2,2)| 8 = 2*3+2 = x*3+y
 *									   +-----+
 *
 */

#define	BOARD_SIZE	3	/* ボードのサイズ */

#define	SENTE_MARK	'o'	/* 先手は 'o' (マル) */
#define	GOTE_MARK	'x'	/* 後手は 'x' (バツ) */

/*
 * 二次元の座標を一次元に変換する関数
 */

int index2d ( int t, int y ) {

	return t * BOARD_SIZE + y;
}

/*
 * main
 */

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

  /*
   *
   */

   char board[BOARD_SIZE*BOARD_SIZE];	/* サイズは 3 × 3 */
   int t;								/* 縱 */
   int y;								/* 横 */

  /*
   * ある局面
   *
   *     oxx
   *     xoo
   *     oox                             
   */

   board[index2d(0,0)] = 'o';	/* (0,0) */
   board[index2d(0,1)] = 'x';	/* (0,1) */
   board[index2d(0,2)] = 'x';	/* (0,2) */

   board[index2d(1,0)] = 'x';	/* (1,0) */
   board[index2d(1,1)] = 'o';	/* (1,1) */
   board[index2d(1,2)] = 'o';	/* (1,2) */

   board[index2d(2,0)] = 'o';	/* (2,0) */
   board[index2d(2,1)] = 'x';	/* (2,1) */
   board[index2d(2,2)] = 'x';	/* (2,2) */

  /*
   *
   */

   t = 0;
   while ( t < BOARD_SIZE ) {
   	 y = 0;
     while ( y < BOARD_SIZE ) {
	   printf ( "%c", board[index2d(t,y)] );
	   y = y + 1;
	 }
	 printf ( "\n" );
	 t = t + 1;
  }

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-013.c の実行結果
$ ./sample-013.exe
oxx
xoo
oxx
$ 

Download : sample-014.c

sample-014.c
/*
 * 2018/12/21 sample-014.c
 */

/*
 * 二次元配列とメモリモデル (3)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-014.c
 *		リンク 
 *			cc -o sample-014.exe sample-014.c 
 *		実行
 *			./sample-014.exe
 */

#include <stdio.h>

/*
 *	◯×ゲームのボード (二次元版)
 *
 *               y
 *         0     1     2
 *		+-----+-----+-----+
 *	  0	|(0,0)|(0,1)|(0,2)|
 *		+-----+-----+-----+
 * t  1	|(1,0)|(1,1)|(1,2)|
 *		+-----+-----+-----+
 *	  2	|(2,0)|(2,1)|(2,2)|
 *		+-----+-----+-----+
 *
 */

#define	BOARD_SIZE	3	/* ボードのサイズ */

#define	SENTE_MARK	'o'	/* 先手は 'o' (マル) */
#define	GOTE_MARK	'x'	/* 後手は 'x' (バツ) */

/*
 * main
 */

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

  /*
   *
   */

   char board[BOARD_SIZE][BOARD_SIZE];	/* サイズは 3 × 3 */
   int t;								/* 縱 */
   int y;								/* 横 */

  /*
   * ある局面
   *
   *     oxx
   *     xoo
   *     oox                             
   */

   board[0][0] = 'o';	/* (0,0) */
   board[0][1] = 'x';	/* (0,1) */
   board[0][2] = 'x';	/* (0,2) */

   board[1][0] = 'x';	/* (1,0) */
   board[1][1] = 'o';	/* (1,1) */
   board[1][2] = 'o';	/* (1,2) */

   board[2][0] = 'o';	/* (2,0) */
   board[2][1] = 'x';	/* (2,1) */
   board[2][2] = 'x';	/* (2,2) */

  /*
   *
   */

   t = 0;
   while ( t < BOARD_SIZE ) {
   	 y = 0;
     while ( y < BOARD_SIZE ) {
	   printf ( "%c", board[t][y] );
	   y = y + 1;
	 }
	 printf ( "\n" );
	 t = t + 1;
  }

  /*
   *
   */

    return 0;

}

/*
 *
 */
sample-014.c の実行結果
$ ./sample-014.exe
oxx
xoo
oxx
$ 

Download : sample-015.c

sample-015.c
/*
 * 2018/12/21 sample-015.c
 */

/*
 * 二次元配列とメモリモデル (3)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-015.c
 *		リンク 
 *			cc -o sample-015.exe sample-015.c 
 *		実行
 *			./sample-015.exe
 */

#include <stdio.h>

/*
 *	◯×ゲームのボード (一次元版)
 *
 *               y
 *         0     1     2			    (y,t)
 *		+-----+-----+-----+            +-----+
 *	  0	|(0,0)|(0,1)|(0,2)|            |(0,0)| 0 = 0*3+0 = t*3+y
 *		+-----+-----+-----+            +-----+
 * t  1	|(1,0)|(1,1)|(1,2)|            |(0,1)| 1 = 0*3+1 = t*3+y
 *		+-----+-----+-----+            +-----+
 *	  2	|(2,0)|(2,1)|(2,2)|            |(0,2)| 2 = 0*3+2 = t*3+y
 *		+-----+-----+-----+            +-----+
 *									   |(1,0)| 3 = 1*3+0 = t*3+y
 *									   +-----+
 *									   |(1,1)| 4 = 1*3+1 = t*3+y
 *									   +-----+
 *									   |(1,2)| 5 = 1*3+2 = t*3+y
 *									   +-----+
 *									   |(2,0)| 6 = 2*3+0 = t*3+y
 *									   +-----+
 *									   |(2,1)| 7 = 2*3+1 = t*3+y
 *									   +-----+
 *									   |(2,2)| 8 = 2*3+2 = x*3+y
 *									   +-----+
 *
 */

#define	BOARD_SIZE	3	/* ボードのサイズ */

#define	SENTE_MARK	'o'	/* 先手は 'o' (マル) */
#define	GOTE_MARK	'x'	/* 後手は 'x' (バツ) */

/*
 * main
 */

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

  /*
   *
   */

   char board[BOARD_SIZE][BOARD_SIZE];	/* サイズは 3 × 3 */
   int t;								/* 縱 */
   int y;								/* 横 */

  /*
   *
   */

	printf ( "sizeof ( board[0][0] ) = %d\n",
 		sizeof ( board[0][0] )
	);

	printf ( "sizeof ( board[0] ) = %d\n",
 		sizeof ( board[0] )
	);

	printf ( "\n" );

	for ( t = 0; t < BOARD_SIZE; t++ ) {
		printf ( "board[%d]=%x\n", t, &board[t] );

		for ( y = 0; y < BOARD_SIZE; y++ ) {
			/* アドレスの表示 */

			printf ( "\t(%d,%d)=%x\n", t, y, &board[t][y] );
		}
		printf ( "\n" );
	}

	/*
	 *
   	 */

	return 0;

}

/*
 *
 */
sample-015.c の実行結果
$ ./sample-015.exe
sizeof ( board[0][0] ) = 1
sizeof ( board[0] ) = 3

board[0]=ad04ed70
	(0,0)=ad04ed70
	(0,1)=ad04ed71
	(0,2)=ad04ed72

board[1]=ad04ed73
	(1,0)=ad04ed73
	(1,1)=ad04ed74
	(1,2)=ad04ed75

board[2]=ad04ed76
	(2,0)=ad04ed76
	(2,1)=ad04ed77
	(2,2)=ad04ed78

$ 

Download : sample-016.c

sample-016.c
/*
 * 2018/12/21 sample-016.c
 */

/*
 * ニ次元配列とメモリモデル (4)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-016.c
 *		リンク 
 *			cc -o sample-016.exe sample-016.c 
 *		実行
 *			./sample-016.exe
 */

#include <stdio.h>

/*
 *	三次の行列
 *
 *   A           列
 *         0     1     2
 *		+-----+-----+-----+
 *	  0	| a00 | a01 | a02 |
 *		+-----+-----+-----+
 * 行 1	| a10 | a11 | a12 |
 *		+-----+-----+-----+
 *	  2	| a20 | a21 | a22 |
 *		+-----+-----+-----+
 *
 */

#define	DIM	3	/* 行列の次元 */

/*
 * void print_array ( int array[DIM][DIM] )
 *		array を出力する
 */

void print_array ( int array[DIM][DIM] ) {
	 int row;	/* 行 */
	 int col;	/* 列 */

	 for ( row = 0; row < DIM; row++ ) {
		printf ( "%c%c ", " | "[row], "/ \\"[row] );
		for ( col = 0; col < DIM; col++ ) {
			printf ( "%d ", array[row][col] );
		}
		printf ( "%c%c\n", "\\ /"[row], " | "[row] );
	}
}

/*
 * void add_array ( int c[DIM][DIM], int a[DIM][DIM], int b[DIM][DIM] )
 *		c = a + b 
 */

void add_array ( int c[DIM][DIM], int a[DIM][DIM], int b[DIM][DIM] ) {
	 int row;	/* 行 */
	 int col;	/* 列 */

	 for ( row = 0; row < DIM; row++ ) {
		for ( col = 0; col < DIM; col++ ) {
			c[row][col] = a[row][col] + b[row][col];
		}
	}

}

/*
 * main
 */

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

  /*
   *
   */

	int a[DIM][DIM] = {
		{1, 2, 3},
		{2, 3, 4},
		{3, 4, 5}
	};	/* 配列の初期化 */

	int b[DIM][DIM] = {
		{1, 1, 1},
		{3, 2, 1},
		{4, 2, 0}
	}; 
	int c[DIM][DIM];	/* a + b の結果を入れる行列 */

	/*
	 *
	 */

	printf ( "行列 a\n" );
	print_array ( a );
	printf ( "と、\n" );
	printf ( "行列 b\n" );
	print_array ( b );
	printf ( "の和は\n" );

	add_array ( c, a, b );		/* c = a + b */

	print_array ( c );
	printf ( "になります。\n" );

  /*
   *
   */

	return 0;

}

/*
 *
 */
sample-016.c の実行結果
$ ./sample-016.exe
行列 a
 / 1 2 3 \ 
|  2 3 4  |
 \ 3 4 5 / 
と、
行列 b
 / 1 1 1 \ 
|  3 2 1  |
 \ 4 2 0 / 
の和は
 / 2 3 4 \ 
|  5 5 5  |
 \ 7 6 5 / 
になります。
$ 

Download : sample-017-01.c

sample-017-01.c
/*
 * 2018/12/14 sample-017-01.c
 */

#include <stdio.h>

/*
 * 利用方法
 *		コンパイル
 *			cc -c sample-017-01.c
 */

typedef struct {
		unsigned char intAry[ sizeof ( int ) ];
} Int;

void print_int_as_char_list ( Int ia ) {
	 int i;

	 for ( i = 0; i < sizeof ( int ); i++ ) {
		printf ( "%d ", ia.intAry[i] );
	 }
 	 printf ( "\n" );

}

Download : sample-017.c

sample-017.c
/*
 * 2018/12/21 sample-017.c
 */

/*
 * 二次元配列とメモリモデル (5)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-017.c
 *		リンク 
 *			cc -o sample-017.exe sample-017.c 
 *		実行
 *			./sample-017.exe
 */

#include <stdio.h>

#if 0
/*
 * 利用方法
 *		コンパイル
 *			cc -I ~/c/include -c sample-017.c
 *			cc -I ~/c/include -c sample-017-01.c
 *			cc -o sample-017.exe sample-017.o sample-017-01.o
 *		実行
 *			./sample-017.exe
 */
#endif

/*
 *	整数とメモリモデル
 *
 *		+---+---+---+---+           +---+
 *  int |				|  == char	|	|
 *		+---+---+---+---+           +---+
 *									|	|
 *									+---+
 *									|	|
 *									+---+
 *									|	|
 *									+---+
 *
 *
 */

int make_int ( int b1, int b2, int b3, int b4 ) {

	return b1 + 256 * ( b2 + 256 * ( b3 + 256 * b4 ) );

}

/*
 * main
 */

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

  /*
   *
   */

	int i;

	printf ( "sizeof( int ) = %d\n", sizeof ( int ) );

	i = make_int ( 1, 0, 0, 0 );
	printf ( "i = make_int ( 1, 0, 0, 0 ) = %d\n", i );
	print_int_as_char_list ( i );

	i = make_int ( 2, 3, 0, 0 );
	printf ( "i = make_int ( 2, 3, 0, 0 ) = %d\n", i );
	print_int_as_char_list ( i );

	i = make_int ( 3, 4, 5, 0 );
	printf ( "i = make_int ( 3, 4, 5, 0 ) = %d\n", i );
	print_int_as_char_list ( i );

	i = make_int ( 4, 5, 6, 7 );
	printf ( "i = make_int ( 4, 5, 6, 7 ) = %d\n", i );
	print_int_as_char_list ( i );

  /*
   *
   */

   printf ( "----\n" );

  /*
   *
   */

	i = 255;
   	printf ( "i = %d\n", i );
	print_int_as_char_list ( i );

	i = 256;
   	printf ( "i = %d\n", i );
	print_int_as_char_list ( i );

  /*
   *
   */

	return 0;

}

/*
 *
 */
sample-017.c の実行結果
$ ./sample-017.exe
sizeof( int ) = 4
i = make_int ( 1, 0, 0, 0 ) = 1
1 0 0 0 
i = make_int ( 2, 3, 0, 0 ) = 770
2 3 0 0 
i = make_int ( 3, 4, 5, 0 ) = 328707
3 4 5 0 
i = make_int ( 4, 5, 6, 7 ) = 117835012
4 5 6 7 
----
i = 255
255 0 0 0 
i = 256
0 1 0 0 
$ 

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

本日の課題

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

課題 20181221-01 : union

Download : 20181221-01.c

20181221-01.c
/*
 * 20181221-01-QQQQ.c
 *	union の応用 (整数型変数のメモリ構造の出力)
 */

#include <stdio.h>

/*
 * IntCharArray
 */

	/* 共用体を利用した IntCharArray 型の宣言 */
typedef union {
	int iv;					/* 整数部 */
	char cv[sizeof(int)];	/* 文字(byte)配列部 */
} IntCharArray;

/*
 * printIntCharArray
 */

void printIntCharArray ( IntCharArray x ) {
	 int i;

		/* 整数値として出力 */

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


		/* 文字(byte)配列として出力 */
	 printf ( "配列として出力 : " );
	 for ( i = 0; i < sizeof ( int ); i++ ) {
	 	 printf ( " %2d", x.cv[i] );
	 }
	 printf ( "\n" );

}

/*
 * main
 *	2^b ( b = 0 〜 sizeof(int)*8 - 1 ) を整数値と文字(byte)配列として出力
 */

int main ( void ) {
	int b;				/* 2 の指数 */
	int v = 1;			/* 2 の k 乗の整数値 */
	IntCharArray ica;	/* 整数と文字配列の共用体 */

	for ( b = 0; b < sizeof(int) * 8; b++ ) {
		/* ica に v の値を整数値として代入 */

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

		/* printIntCharArray を呼出して、内容を出力する */
		printIntCharArray ( ica );
		v = v * 2;
	}

  return 0;
}
20181221-01.c の実行結果
$ ./20181221-01-QQQQ.exe
整数値として出力 :          1,	配列として出力 :   1  0  0  0
整数値として出力 :          2,	配列として出力 :   2  0  0  0
整数値として出力 :          4,	配列として出力 :   4  0  0  0
整数値として出力 :          8,	配列として出力 :   8  0  0  0
整数値として出力 :         16,	配列として出力 :  16  0  0  0
整数値として出力 :         32,	配列として出力 :  32  0  0  0
整数値として出力 :         64,	配列として出力 :  64  0  0  0
整数値として出力 :        128,	配列として出力 :  -128  0  0  0
整数値として出力 :        256,	配列として出力 :   0  1  0  0
整数値として出力 :        512,	配列として出力 :   0  2  0  0
整数値として出力 :       1024,	配列として出力 :   0  4  0  0
整数値として出力 :       2048,	配列として出力 :   0  8  0  0
整数値として出力 :       4096,	配列として出力 :   0 16  0  0
整数値として出力 :       8192,	配列として出力 :   0 32  0  0
整数値として出力 :      16384,	配列として出力 :   0 64  0  0
整数値として出力 :      32768,	配列として出力 :   0 -128  0  0
整数値として出力 :      65536,	配列として出力 :   0  0  1  0
整数値として出力 :     131072,	配列として出力 :   0  0  2  0
整数値として出力 :     262144,	配列として出力 :   0  0  4  0
整数値として出力 :     524288,	配列として出力 :   0  0  8  0
整数値として出力 :    1048576,	配列として出力 :   0  0 16  0
整数値として出力 :    2097152,	配列として出力 :   0  0 32  0
整数値として出力 :    4194304,	配列として出力 :   0  0 64  0
整数値として出力 :    8388608,	配列として出力 :   0  0 -128  0
整数値として出力 :   16777216,	配列として出力 :   0  0  0  1
整数値として出力 :   33554432,	配列として出力 :   0  0  0  2
整数値として出力 :   67108864,	配列として出力 :   0  0  0  4
整数値として出力 :  134217728,	配列として出力 :   0  0  0  8
整数値として出力 :  268435456,	配列として出力 :   0  0  0 16
整数値として出力 :  536870912,	配列として出力 :   0  0  0 32
整数値として出力 : 1073741824,	配列として出力 :   0  0  0 64
整数値として出力 : -2147483648,	配列として出力 :   0  0  0 -128
$