#include <stdio.h>
int main(int ac, char *av[] ) {
  printf ( "sizeof ( char ) = %d\n", sizeof ( char ) );
  printf ( "sizeof ( int ) = %d\n", sizeof ( int ) );
  printf ( "sizeof ( double ) = %d\n", sizeof ( double ) );
  return 0;
}
#include <stdio.h>
void print_char ( char ch ) {
  printf ( "ch = %d\n", ch );
}
int main(int ac, char *av[] ) {
  print_char ( 'A' );	/* 'A' という文字を表す ASCII Code を指定 */
  						/* 'A' は、65 という(ちいさな)整数値になる */
						/* 「小さい整数」とは「0 から 255 の 1 byte 表現できる整数」 */
						/* あるいは -128 から 127 の範囲 (符号つきの場合) */
  print_char ( 65 );	/* 実際に整数を指定しても、同じ */
  print_char ( 1000 );	/* 小くなければ .. ? */
  print_char ( 1000 % 256 );	/* 小くなければ .. => 余分な部分はきりすてられる  */
  printf ( "%d\n", 256 * 10 + 20 );
  print_char ( 256 * 10 + 20 );
  print_char ( 2580 );		/* 2580 = 256 * 10 + 20 */
  							/* 2580 / 256 = 10 .. 20 */
  							/* 余りの 20 しかでない */
						  /*
							2580 = 256 * 10 + 20
							+-----------+
							|	20		|	0 〜 255
							+-----------+
							|	10		|	0 〜 255
							+-----------+
								-> 256 * 10 + 20 ( 256 進数法での表現 )
							セルが一つ 0 〜 255 = 256 - 1 ( 256 = 2^8 通り )
							セルが二つ 0 〜 655xx ( 2^16 通り )
							セルが四つ 0 〜 2^32-1 ( 2^32 通り )
								-> int の表現できる場合のかず
									- 2^(32-1) 〜 2^(32-1) - 1
						  */
  return 0;
}
#include <stdio.h>
void print_char ( char ch ) {
  printf ( "ch = %d\n", ch );
}
int main(int ac, char *av[] ) {
  int i;
  char ch;
  ch = 0;
  for ( i = 0; i < 1000; i++ ) {	/* i を 0 から 999 まで 1000 回実行 */
	printf ( "%d : ", i );
								/*
									+-----------+
							i +--	|	0		| 0 = 0 + 0 * 256^1
							  |		+-----------+       + 0 * 256^2
							  +--	|	0		|       + 0 * 256^3
							  |		+-----------+
							  +--	|	0		|
							  |		+-----------+
							  +--	|	0		|
									+-----------+
									+-----------+
							ch  --	|	0		| 256 = 0 + 0 * 256^1
									+-----------+         + 1 * 256^2
									|	1		|         + 0 * 256^3
									+-----------+
									|	0		|
									+-----------+
									|	0		|
									+-----------+
								*/
	/*
	  127 : ch = 127
	  128 : ch = -128
	  		セル		char	int
				128		-128	-128
				129		-127	-127
						-2		-2
				255		-1		-1
				0		0		0
				1		1		1
						..		..
				127		127		127
	*/
	print_char ( ch );
	ch = ch + 1;			/* ch を 1 ずつ増やす */
							/* 最初は 0 : 0, 1 : 1, ... */
  }
  return 0;
}
#include <stdio.h>
void print_int ( int ch ) {
  printf ( "ch = %d\n", ch );
}
int main(int ac, char *av[] ) {
  print_int ( 'A' );
  print_int ( 65 );	/* 実際に整数を指定しても、同じ */
  print_int ( 1000 );	/* 小くなければ .. ? */
  print_int ( 2580 );	/* 2580 = 256 * 10 + 20 */
  return 0;
}
/*
 */
#include <stdio.h>
typedef struct {
  char bytes[sizeof(int)];		/* sizeof int = 4 */
} Int;
void print_int ( Int ch ) {
  int i;
  for ( i = 0; i < sizeof ( int ); i++ ) {
	printf ( "%d\n", ch.bytes[i] );
  }
}
#include <stdio.h>
int main(int ac, char *av[] ) {
  print_int ( 'A' );
  print_int ( 65 );	/* 実際に整数を指定しても、同じ */
		  /*
				+-----------+
		65		|	65		|
				+-----------+
				|	0		|
				+-----------+
				|	0		|
				+-----------+
				|	0		|
				+-----------+
		  */
  print_int ( 1000 );	/* 小くなければ .. ? */
  print_int ( 2580 );	/* 2580 = 256 * 10 + 20 */
		  /*
				+-----------+
		2580	|	20		|
				+-----------+
				|	10		|
				+-----------+
				|	0		|
				+-----------+
				|	0		|
				+-----------+
		  */
  /*
	int 型の変数は、sizeof ( int ) のサイズのセルを占有する
  */
  return 0;
}
#include <stdio.h>
int main(int ac, char *av[] ) {
  int ivar;
  char cvar;
  /* & は、変数の前につけて、その変数のアドレス(ポインター)値を取る */
  printf ( "&ivar = %x\n", &ivar );	/* ivar のアドレス値 */
  printf ( "&cvar = %x\n", &cvar );	/* cvar のアドレス値 */
  return 0;
}
#include <stdio.h>
void set_char_var ( char *p ) {
  /* アドレス値(ポインター値)を利用して、変数の値が変更できる */
  *p = 1;		/* 引数でしていされた char 型変数へのポインターを使って */
  				/* その変数の値を書き換える */
}
void set_int_var ( int *p ) {
  *p = 1;		/* 引数でしていされた int 型変数へのポインターを使って */
  				/* その変数の値を書き換える */
}
int main(int ac, char *av[] ) {
  int ivar = 2;
  char cvar = 2;
  /* char 型変数の場合 (先週) */
  printf ( "前 : cvar = %d\n", cvar );
  set_char_var ( &cvar );
  printf ( "後 : cvar = %d\n", cvar );
  /* int 型変数の場合 (今週) */
  printf ( "前 : ivar = %d\n", ivar );
  set_int_var ( &ivar );
  printf ( "後 : ivar = %d\n", ivar );
  return 0;
}
#include <stdio.h>
void print_char_array ( char ch[3] ) {
  int i;
  for ( i = 0; i < 3; i++ ) {
	printf ( "ch[%d] = %d\n", i, ch[i] );
  }
}
int main(int ac, char *av[] ) {
  char cArray[3] = { 1, 2, 3 };
	  /*
			+-----------+
			|	1		| cArray[0]
			+-----------+
			|	2		| cArray[1]
			+-----------+
			|	3		| cArray[2]
			+-----------+
	  */
  print_char_array ( cArray );
  return 0;
}
#include <stdio.h>
void print_char_array_address ( char ch[3] ) {
  int i;
  printf ( "関数 : ch = %x\n", ch );
  for ( i = 0; i < 3; i++ ) {
	printf ( "&ch[%d] = %x\n", i, &ch[i] );	/* アドレスの表示 */
  }
  /*
	配列名は、その配列の先頭の要素のアドレス(ポインター値)をもっている
		=>
			普通、
				関数には、実引数に変数名を指定して、
				関数内で、仮引数変数の値を書き換えても、元には影響しない
			一方、
				関数には、実引数に配列名を指定して、
				関数内で、仮引数変数を利用して、配列の要素の値を書き換えると
				元の配列の要素の値が書き変わる
  */
}
int main(int ac, char *av[] ) {
  char cArray[3] = { 1, 2, 3 };
	  /*
			+-----------+
			|	1		| cArray[0]
			+-----------+
			|	2		| cArray[1]
			+-----------+
			|	3		| cArray[2]
			+-----------+
	  */
  printf ( "main : ch = %x\n", cArray );
  print_char_array_address ( cArray );
  return 0;
}
#include <stdio.h>
void print_int_array_address ( int in[3] ) {
  int i;
  printf ( "関数 : in = %x\n", in );
  for ( i = 0; i < 3; i++ ) {
	printf ( "&in[%d] = %x\n", i, &in[i] );	/* アドレスの表示 */
  }
}
int main(int ac, int *av[] ) {
  int iArray[3] = { 1, 2, 3 };
	  /*
			+-----------+
bfd9e7e4	|	1		| iArray[0]
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
bfd9e7e4+4	|	2		| iArray[1]
=bfd9e7e8	+-----------+ &iArray[1] の値は &iArray[0] より sizeof (int) だけ大
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	3		| iArray[2]
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
	  */
  printf ( "main : in = %x\n", iArray );
  print_int_array_address ( iArray );
  return 0;
}
#include <stdio.h>
void print_int_array_address ( int in[3] ) {
  int i;
  printf ( "関数 : in = %x\n", in );
  printf ( "in + 1 = %x\n", in + 1 );
  printf ( "&in[1] = %x\n", &in[1] );
  /*
	&in[1] = in + 1 = &in[0] + 1
  */
}
int main(int ac, int *av[] ) {
  int iArray[3] = { 1, 2, 3 };
	  /*
			+-----------+
bfd9e7e4	|	1		| iArray[0]
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
bfd9e7e4+4	|	2		| iArray[1]
=bfd9e7e8	+-----------+ &iArray[1] の値は &iArray[0] より sizeof (int) だけ大
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	3		| iArray[2]
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
			|	0		|
			+-----------+
	  */
  printf ( "main : in = %x\n", iArray );
  print_int_array_address ( iArray );
  return 0;
}
/*
 * 20141212-01-QQQQ.c
 * ポインターを利用して、整数変数の値を正値にする
 */
#include <stdio.h>
/*
 *	to_positive_int_variable ( int *iVarPtr )
 *		指定された整数型の変数の値を正値になるようにする
 *		int *iVarPtr : 整数型変数へのポインター値
 */
void to_positive_int_variable ( int *iVarPtr ) {
  /* int *iVarPtr <=> int iVarPtr[1] */
  /* iVarPtr[0] を操作できる iVarPtr は配列と同じだから */
	if ( *iVarPtr < 0 )	{	/* もし、整数型変数の値が負ならば.. */
		/* その値の符号を変更して、元の変数に代入する */
		/* *iVarPtr ( = iVarPtr[0] ) の値を変更する必要がある */
	  *iVarPtr = - *iVarPtr;		/* この結果 (当然) *iVarPtr の値が変化 */
	  								/* するが、これは、関数の呼び元の値も変る */
	} /* そうでなければ、何もしない.. */
}
/*
 *
 */
int main ( int argc, char *argv[] ) {
	int pVar = 5;	/* 正の値を持つ整数型変数 */
	int nVar = -2;	/* 負の値を持つ整数型変数 */
	int zVar = 0;	/* 零の値を持つ整数型変数 */
	/* pVar */
	printf ( "前 : pVar = %d\n", pVar );
	to_positive_int_variable ( &pVar );	/* 引数はポインター値を指定する */
	/* 引数には、値を変更させたい変数の「ポインター値」を指定するする必要が
	   あるので「&pVar」とする必要がある
			引数でわたしているのは pVar の「ポインター値」
			関数は、その「ポインター値」を利用して pVar を間接的に操作する
	 */
	printf ( "後 : pVar = %d\n", pVar );
	/* nVar */
	printf ( "前 : nVar = %d\n", nVar );
	to_positive_int_variable ( &nVar );
	/*                         ^この「&」が重要 */
	printf ( "後 : nVar = %d\n", nVar );
	/* zVar */
	printf ( "前 : zVar = %d\n", zVar );
	/*
	**	 この部分を完成させなさい
	*/
	printf ( "後 : zVar = %d\n", zVar );
  return 0;
}
/*
 *
 */
/*
 構造体とポインターの関係
*/
#include <stdio.h>
typedef struct {
  int x;
  int y;
} Point2D;
/*
 * void to_origin ( Point2D *pPtr );
 *	引数で指定された Point2D 型の変数のポインター値を利用して
 *	その変数の値を、原点 ( 0, 0 ) に移す関数
 */
void to_origin ( Point2D *pPtr ) {
  (*pPtr).x = 0;		/* x 座標を 0 にする */
  (*pPtr).y = 0;		/* y 座標を 0 にする */
	  /*
		注意 : *pPtr.x は *(pPtr.x) と同じで、これは (*pPtr).x と異る
	  */
  /*
	main 側で &pa を渡すので、ここでは
		(*(&pa)).x = 0
		(*(&pa)).y = 0
	とおなじで、これは
		pa.x = 0
		pa.y = 0
	とおなじ、すなわち、元 main の変数の値を (0,0) した
  */
}
void print_point_2d ( Point2D point ) {
  /* Point2D の値がわかればよいので * は不要 */
  /* ※ * と & をつかっても良い (may) */
  printf ( "(%d, %d)", point.x, point.y );
}
int main(int ac, char *av[] ) {
  Point2D pa = { 1, 2 };		/* pa = (1,2) にする */
  printf ( "pa = " );
  print_point_2d ( pa );		/* ここでは値をわたしている */
								/* & はいらない */
  printf ( "です\n" );
  printf ( "これを原点に移動させると\n" );
  to_origin ( &pa );		/* 変数の値を変更するのでポインターを渡す */
							/* & を利用 */
  printf ( "pa = " );
  print_point_2d ( pa );		/* ここでは値をわたしている */
								/* & はいらない */
  printf ( "となります\n" );
  return 0;
}
/*
 構造体とポインターの関係(2)
*/
#include <stdio.h>
typedef struct {
  int x;
  int y;
} Point2D;
/*
 * void to_origin ( Point2D *pPtr );
 *	引数で指定された Point2D 型の変数のポインター値を利用して
 *	その変数の値を、原点 ( 0, 0 ) に移す関数
 */
void to_origin ( Point2D *pPtr ) {
  pPtr -> x = 0;		/* x 座標を 0 にする */
  pPtr -> y = 0;		/* y 座標を 0 にする */
	  /*
		注意 : 「pPtr -> x」 は 「(*pPtr).x 」と同じ
	  */
  /*
	main 側で &pa を渡すので、ここでは
		(*(&pa)).x = 0
		(*(&pa)).y = 0
	とおなじで、これは
		pa.x = 0
		pa.y = 0
	とおなじ、すなわち、元 main の変数の値を (0,0) した
  */
}
void print_point_2d ( Point2D point ) {
  /* Point2D の値がわかればよいので * は不要 */
  /* ※ * と & をつかっても良い (may) */
  printf ( "(%d, %d)", point.x, point.y );
}
int main(int ac, char *av[] ) {
  Point2D pa = { 1, 2 };		/* pa = (1,2) にする */
  printf ( "pa = " );
  print_point_2d ( pa );		/* ここでは値をわたしている */
								/* & はいらない */
  printf ( "です\n" );
  printf ( "これを原点に移動させると\n" );
  to_origin ( &pa );		/* 変数の値を変更するのでポインターを渡す */
							/* & を利用 */
  printf ( "pa = " );
  print_point_2d ( pa );		/* ここでは値をわたしている */
								/* & はいらない */
  printf ( "となります\n" );
  return 0;
}
/*
 * 20141212-02-QQQQ.c
 * ポインター演算子を利用して構造体を操作
 */
#include <stdio.h>
/*
 *	二次元の「点」を表す構造体型 Point2D の宣言
 */
typedef	struct {
	int x;
	int y;
} Point2D;
/*
 *	move_to_x_axis_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を x 軸に対象な点に移す
 *		 Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 *
 *
 *			Y	^
 *				|
 *				|
 *				|   P(x,y)			<- 元の点
 *				|     |
 *			----+-----+-----> X
 *				|	  |
 *				|	P'(x,-y)		<- X 軸に対称点( y 座標の符号反転する)
 *				|
 *				|
 *
 */
void move_to_x_axis_symmetry ( Point2D *p2dPtr ) {
	/* x 軸に対称なので、y 座標の符号だけを変更 */
	p2dPtr -> y = - p2dPtr -> y;	/* y 座標の符号を逆転 */
	/* その点の y 座標 ( (*p2dPtr).y == p2dPtr -> y ) の符号を変更すればよい */
}
/*
 *	move_to_y_axis_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を y 軸に対象な点に移す
 *		Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 */
void move_to_y_axis_symmetry ( Point2D *p2dPtr ) {
	/* y 軸に対称なので、x 座標の符号だけを変更 */
	/*
	**	 この部分を完成させなさい
	*/
}
/*
 *	move_to_origin_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を 原点に対象な点に移す
 *		Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 */
void move_to_origin_symmetry ( Point2D *p2dPtr )	{
	/* 原点対称に移動するには、
	   x 軸対称に移動して、から y 軸対称に移動すればよい
	*/
	move_to_x_axis_symmetry ( p2dPtr );	/* 引数は初めからポインター値 */
	/* '&' はいらない (すでにポインタ値になっている) */
	move_to_y_axis_symmetry ( p2dPtr );	/* 今度は y 座標 */
	/* 同様に '&' はいらない (すでにポインタ値になっている) */
}
/*
 *	print_point2d ( Point2D p2dVar )
 *		指定された Point2D 型の値を表示する
 *		Point2D p2dVar; Point2D 型の値
 */
void print_point2d ( Point2D p2dVar ) {
	 /* x, y 座標をそれぞれ出力するだけ */
	 printf ( "(%d, %d)", p2dVar.x, p2dVar.y );
}
/* ポインター版もつくれる */
void print_point2d_by_pointer ( Point2D *p2dVar ) {
	 /* x, y 座標をそれぞれ出力するだけ */
	 printf ( "(%d, %d)", p2dVar -> x, p2dVar -> y );
}
/*
 *
 */
int main ( void ) {
	Point2D Pa = { -1, 3 };	/* 座標 ( -1, 3 ) の点 Pa */
	Point2D Pb = { 2, 5 };	/* 座標 ( 2, 5 ) の点 Pb */
	printf ( "Pa = " );
	print_point2d ( Pa );				/* Point2D の値を指定 */
	printf ( "\nを、x 軸対称な位置に移動すると.." );
	move_to_x_axis_symmetry ( &Pa );	/* Point2D 型の変数のポインター値を指定 */
	/*	print_point2d ( Pa ); */
	print_point2d_by_pointer ( &Pa );
	printf ( "になります\n" );
	printf ( "Pb = " );
	print_point2d ( Pb );
	printf ( "\nを、原点対称な位置に移動すると.." );
	move_to_origin_symmetry ( /*ここ*/ ); /* Pb を利用した何か */
	print_point2d ( Pb );
	printf ( "になります\n" );
    return 0;
}
/*
 *
 */
#include <stdio.h>
typedef	struct	{
  char bytes[sizeof(int)];
} Int;
void print_low_byte ( Int v ) {	/* 引数は Int 型 sturct { int bytes[4] } */
  /*
		+-----------+						+-----------+
	int	|	20		|		Int.bytes[0]	|	20		|
		+-----------+						+-----------+
		|	10		|		Int.bytes[1]	|	10		|
		+-----------+						+-----------+
		|	0		|		Int.bytes[2]	|	0		|
		+-----------+						+-----------+
		|	0		|		Int.bytes[3]	|	0		|
		+-----------+						+-----------+
  */
  printf ( "low byte = %d\n", v.bytes[0] );
}
#include <stdio.h>
int main(int ac, char *av[] ) {
  print_low_byte ( 10 * 256 + 20 );	/* 引数は int 型 */
  /*
		+-----------+
	int	|	20		|	=	10 * 256 + 20
		+-----------+
		|	10		|
		+-----------+
		|	0		|
		+-----------+
		|	0		|
		+-----------+
  */
  return 0;
}
/*
	変数 ( メモリのセル集まり.. ) は、それ自身は、型情報をもっていない
		それをどようにつかうかは、その内容を「どの型として利用するか」できまる
*/
#include <stdio.h>
#include <stdio.h>
typedef	struct	{
  char bytes[sizeof(int)];
} Int;
void print_low_byte ( Int v ) {	/* 引数は Int 型 sturct { int bytes[4] } */
  /*
		+-----------+						+-----------+
	int	|	20		|		Int.bytes[0]	|	20		|
		+-----------+						+-----------+
		|	10		|		Int.bytes[1]	|	10		|
		+-----------+						+-----------+
		|	0		|		Int.bytes[2]	|	0		|
		+-----------+						+-----------+
		|	0		|		Int.bytes[3]	|	0		|
		+-----------+						+-----------+
  */
  printf ( "low byte = %d\n", v.bytes[0] );
}
int main(int ac, char *av[] ) {
  print_low_byte ( 10 * 256 + 20 );	/* 引数は int 型 */
  /*
		+-----------+
	int	|	20		|	=	10 * 256 + 20
		+-----------+
		|	10		|
		+-----------+
		|	0		|
		+-----------+
		|	0		|
		+-----------+
  */
  return 0;
}
/*
	変数 ( メモリのセル集まり.. ) は、それ自身は、型情報をもっていない
		それをどようにつかうかは、その内容を「どの型として利用するか」できまる
*/
#include <stdio.h>
#include <stdio.h>
void print_low_byte_with_pointer ( int *v ) {	/* 引数は (int *) 型 */
  printf ( "value = %d\n", *v );	/* *(&iVar) == iVar = 10 * 256 + 20 */
}
int main(int ac, char *av[] ) {
  int iVar = 10 * 256 + 20;
  print_low_byte_with_pointer ( &iVar );	/* 引数は (int*) 型 */
  return 0;
}
/*
	変数 ( メモリのセル集まり.. ) は、それ自身は、型情報をもっていない
		それをどようにつかうかは、その内容を「どの型として利用するか」できまる
*/
#include <stdio.h>
#include <stdio.h>
void print_low_byte_with_pointer ( int *v ) {	/* 引数は (int *) 型 */
  printf ( "value = %d\n", *(char *)v );
  /*
		+-----------+
	iVar|	20		|	← v は、ココのアドレス + int 型という情報
		+-----------+		もし、単に *v とすれば、4 byte 分を利用する
		|	10		|		ところが、(char *) 型であれば 1 byte 分しか
		+-----------+		利用しない
		|	0		|
		+-----------+
		|	0		|
		+-----------+
  */
  /*
	キャスト
		v は int * 型の値 ( int へのポインター型 ) だが、
		それをむりやり char * 型 ( char へのポインター型 ) に強制できる
  */
}
int main(int ac, char *av[] ) {
  int iVar = 10 * 256 + 20;
  /*
		+-----------+
	iVar|	20		|	← &iVar は、ココのアドレス + int 型という情報
		+-----------+
		|	10		|
		+-----------+
		|	0		|
		+-----------+
		|	0		|
		+-----------+
  */
  print_low_byte_with_pointer ( &iVar );	/* 引数は (int*) 型 */
  return 0;
}
/*
	変数 ( メモリのセル集まり.. ) は、それ自身は、型情報をもっていない
		それをどようにつかうかは、その内容を「どの型として利用するか」できまる
*/
#include <stdio.h>
/* 階乗の計算 */
int fac ( int n ) {
  if ( n <= 0 ) {
	return 1;
  } else {
	return fac ( n - 1 ) * n;
  }
}
int main(int ac, char *av[] ) {
  printf ( "4! = %d\n", fac ( 4 ) );
  /* 
	4! = 4 * 3 * 2 * 1 = 24
	fac ( 4 )
		n ← 4; fac( n )
		n ← 4; if ( n <= 0 ) {
			  		return 1;
			  } else {
				return fac ( n - 1 ) * n;
			  }
			if ( 4 <= 0 ) {
				return 1;
			} else {
				return fac ( 4 - 1 ) * 4;
			}
			return fac ( 4 - 1 ) * 4;
			return fac ( 3 ) * 4;
						4 をかけるというはおいておいて ..
  				fac(3 )は...
  */
  return 0;
}
#include <stdio.h>
/* 階乗の計算 */
int fac ( int n ) {
  printf ( "*(%x) = %d\n", &n, n );		/* n のアドレス値を表示してみる */
  if ( n <= 0 ) {
	return 1;
  } else {
	return fac ( n - 1 ) * n;
  }
}
int main(int ac, char *av[] ) {
  printf ( "4! = %d\n", fac ( 4 ) );
  /* 
	4! = 4 * 3 * 2 * 1 = 24
	fac ( 4 )
		n ← 4; fac( n )
		n ← 4; if ( n <= 0 ) {
			  		return 1;
			  } else {
				return fac ( n - 1 ) * n;
			  }
			if ( 4 <= 0 ) {
				return 1;
			} else {
				return fac ( 4 - 1 ) * 4;
			}
			return fac ( 4 - 1 ) * 4;
			return fac ( 3 ) * 4;
						4 をかけるというはおいておいて ..
  				fac(3 )は...
  */
  return 0;
}
sizeof ( 型名 )
	引数は、「型名」あるいは、「型」を表す表現
		その型が、幾つのセルをしめるかを byte 数でしめしてくれる
前回は
	char 型変数					 <-> メモリモデルの一つセル
	& をつける					 <-> セルのアドレスを取り出す
	& をつけたものに * をつける   <-> セルそのものをさす
		※ & をつけたものは、「値」なので、計算に利用したり、
			関数に引数として渡す事や、関数の値として返す事ができる
	今回は、int 型に関しても ( int が 4 つ分のセルを占有する以外は、 )
		char 型と同じ
	同様に、
		double 型 / 構造体なども同じように説明できる
==
	ポインター値
		アドレスと型の二つの情報を持つ値
			アドレス : メモリモデルにおける、番地(address)同じもの
			型 : それがしめるセルサイズと、それが表す情報の操作方法
				-> char, int, double, struct { int x; int y; }, etc.. と同じ
		!! ポインター値は、アドレス値 *だけ* をもっているわけではない
		!!	アドレス値は、整数値として表示できるが、型情報は表示できない
==
関数の引数 (など、変数) は、
	スタックにとられている
		「スタック」=「棚」
			上に、どんどん、物を載せる事ができて、
			必要ならば、上にあるものを下して使う使う事ができる
				------------------
					スタック (最初は空っぽ)
					+-------+
					|	1	|		<- 一つ物を載せた (push)
					+-------+
				------------------
					スタック (内容が 1 つのもの)
					+-------+
					|	4	|		<- 沢山のっている
					+-------+
					+-------+
					|	3	|
					+-------+
					+-------+
					|	2	|
					+-------+
					+-------+
					|	1	|
					+-------+
				------------------
		とりだすときは、最後にいれたものだけがとりだせる
		+-------+
		|	4	|		<- 取り出せるのは、さいごにつんだもの (pop)
		+-------+
					+-------+
					|	3	|
					+-------+
					+-------+
					|	2	|
					+-------+
					+-------+
					|	1	|
					+-------+
				------------------
	fac(int n) {
								+----------+
							n->	|     4    |
								+----------+
								------------
			fac ( n - 1 ) = fac ( 4 - 1 ) = fac ( 3 )
								+----------+
							n->	|     3    |
								+----------+
								+----------+
								|     4    |
								+----------+
								------------
	}
	main()
	{
		fac (4)					------------
	}
	1. 再帰呼出し
		メモリモデルで説明ができる
	2. 引数が「スタック」とよばれる「メモリ」に保存されている
	   -> printf の秘密につながる
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20151211-01.c ( SJIS 版 )
/*
 * 20151211-01-QQQQ.c
 * ポインター演算子を利用して構造体を操作
 */
#include <stdio.h>
/*
 *	二次元の「点」を表す構造体型 Point2D の宣言
 */
typedef	struct {
	int x;
	int y;
} Point2D;
/*
 *	move_to_x_axis_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を x 軸に対象な点に移す
 *		 Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 */
void move_to_x_axis_symmetry ( Point2D *p2dPtr ) {
	/* x 軸に対称なので、y 座標の符号だけを変更 */
	p2dPtr -> y = - p2dPtr -> y;	/* y 座標の符号を逆転 */
}
/*
 *	move_to_y_axis_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を y 軸に対象な点に移す
 *		Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 */
void move_to_y_axis_symmetry ( Point2D *p2dPtr ) {
	/* y 軸に対称なので、x 座標の符号だけを変更 */
	/*
	**	 この部分を完成させなさい
	*/
}
/*
 *	move_to_origin_symmetry ( Point2D *p2dPtr )
 *		指定された Point2D 型の変数へのポインターの値を 原点に対象な点に移す
 *		Point2D *p2dPtr : Point2D 型の変数へのポインターの値
 */
void move_to_origin_symmetry ( Point2D *p2dPtr )	{
	/* 原点対称に移動するには、
	   x 軸対称に移動して、から y 軸対称に移動すればよい
	*/
	move_to_x_axis_symmetry ( p2dPtr );	/* 引数は初めからポインター値 */
	/*
	**	 この部分を完成させなさい
	*/
}
/*
 *	print_point2d ( Point2D p2dVar )
 *		指定された Point2D 型の値を表示する
 *		Point2D p2dVar; Point2D 型の値
 */
void print_point2d ( Point2D p2dVar ) {
	 /* x, y 座標をそれぞれ出力するだけ */
	 printf ( "(%d, %d)", p2dVar.x, p2dVar.y );
}
/*
 *
 */
int main ( void ) {
	Point2D Pa = { -1, 3 };	/* 座標 ( -1, 3 ) の点 Pa */
	Point2D Pb = { 2, 5 };	/* 座標 ( 2, 5 ) の点 Pb */
	printf ( "Pa = " );
	print_point2d ( Pa );				/* Point2D の値を指定 */
	printf ( "\nを、x 軸対称な位置に移動すると.." );
	move_to_x_axis_symmetry ( &Pa );	/* Point2D 型の変数のポインター値を指定 */
	print_point2d ( Pa );
	printf ( "になります\n" );
	printf ( "Pb = " );
	print_point2d ( Pb );
	printf ( "\nを、原点対称な位置に移動すると.." );
	/*
	**	 この部分を完成させなさい
	*/
	print_point2d ( Pb );
	printf ( "になります\n" );
    return 0;
}
/*
 *
 */
2.3 9.1 5.9 2.7 3.2
$ ./20151211-01-QQQQ.exe Pa = (-1, 3) を、x 軸対称な位置に移動すると..(-1, -3)になります Pb = (2, 5) を、原点対称な位置に移動すると..(-2, -5)になります $