Powered by SmartDoc

ソフトウェア概論B (2010/12/03)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

当日のOHP資料です。

本日の概要

10.ポインター( Text p.226 - 245 )

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

sample-001

Download : sample-001.c ( SJIS 版 )

sample-001.c
#include <stdio.h>

#define	INT_ARRAY_SIZE	6
#define	SAMPLE_INDEX	2

#define	D1	3
#define	D2	5
#define	D3	7

int main ( void ) {
  float simple_var;
  int array_var[INT_ARRAY_SIZE];
  double n_array_var[D1][D2][D3];
  int row;

  /* 単純変数のサイズ */

  printf ( "単純変数(simple_var)のサイズ\n" );

  printf ( "sizeof(simple_var)                 = %d\n", sizeof(simple_var) );
  printf ( "sizeof(float = type of simple_var) = %d\n", sizeof(float) );

  printf ( "\n" );

  /* 一次元配列のサイズ */

  printf ( "一次元配列(array_var)のサイズ\n" );

  printf ( "sizeof(array_var)                  = %d\n", sizeof(array_var) );
  printf ( "sizeof(int = type of array_var[0]) = %d, ", sizeof(int) );
  printf ( "(sizeof(array_var[0]) = %d)\n", sizeof(array_var[0]) );
  printf ( "array size                         = %d\n", INT_ARRAY_SIZE );

  printf ( "\n" );

  /* 配列要素のアドレス値 */

  printf ( "配列要素(array_var[%d])のアドレス値\n", SAMPLE_INDEX );
  printf ( "array_var                       = %p\n", array_var );
  printf ( "&array_var[0]                   = %p\n", &array_var[0] );
  printf ( "(sizeof(int)=%3d) x (index=%3d) = %d\n", sizeof(int), SAMPLE_INDEX, sizeof(int) * SAMPLE_INDEX );
  printf ( "&array_var[%3d]                 = %p\n", SAMPLE_INDEX, &array_var[ SAMPLE_INDEX ] );
  printf ( "array_var + %3d                 = %p\n", SAMPLE_INDEX, array_var + SAMPLE_INDEX );

  printf ( "\n" );

  /* 多次元配列 */

  printf ( "一次元配列(n_array_var)のサイズ\n" );

  printf ( "sizeof(n_array_var)                     = %d\n", sizeof(n_array_var) );
  printf ( "sizeof(double = type of n_array_var[0]) = %d, ", sizeof(double) );
  printf ( "(sizeof(n_array_var[0]) = %d)\n", sizeof(n_array_var[0]) );
  printf ( "array size ( = %3d x %3d x %3d )        = %d\n", D1, D2, D3, D1 * D2 * D3 );

  printf ( "\n" );

  return 0;
}
sample-001.c の実行結果
C:\usr\c\> sample-001
単純変数(simple_var)のサイズ
sizeof(simple_var)                 = 4
sizeof(float = type of simple_var) = 4

一次元配列(array_var)のサイズ
sizeof(array_var)                  = 24
sizeof(int = type of array_var[0]) = 4, (sizeof(array_var[0]) = 4)
array size                         = 6

配列要素(array_var[2])のアドレス値
array_var                       = 0xbf9ba140
&array_var[0]                   = 0xbf9ba140
(sizeof(int)=  4) x (index=  2) = 8
&array_var[  2]                 = 0xbf9ba148
array_var +   2                 = 0xbf9ba148

一次元配列(n_array_var)のサイズ
sizeof(n_array_var)                     = 840
sizeof(double = type of n_array_var[0]) = 8, (sizeof(n_array_var[0]) = 280)
array size ( =   3 x   5 x   7 )        = 105

C:\usr\c\> 

sample-002

Download : sample-002.c ( SJIS 版 )

sample-002.c
#include <stdio.h>

#define	ROW_SIZE	3
#define	COL_SIZE	5

int main ( void ) {
  int darray[ROW_SIZE][COL_SIZE];
  int row;
  int col;

  for ( row = 0; row < ROW_SIZE; row++ ) {
	  for ( col = 0; col < COL_SIZE; col++ ) {
		darray[row][col] = row * 1000 + col;
	  }
  }

  printf ( "darray                             = %p\n", darray );
  printf ( "sizeof(int)                        = %d ( = sizeof(darray[0][0] = %d )\n", sizeof(int), sizeof(darray[0][0]) );
  printf ( "sizeof(darray[0])                  = %d ( = 0x%x )\n", sizeof(darray[0]), sizeof(darray[0]) );

  for ( row = 0; row < ROW_SIZE; row++ ) {
	  for ( col = 0; col < COL_SIZE; col++ ) {
		printf ( "darray[%d][%d] = %04d, ", row, col, darray[row][col] );
		printf ( "&darray[%d][%d] = %p\n", row, col, &darray[row][col] );
	  }
  }

  return 0;
}
sample-002.c の実行結果
C:\usr\c\> sample-002
darray                             = 0xbf9da14c
sizeof(int)                        = 4 ( = sizeof(darray[0][0] = 4 )
sizeof(darray[0])                  = 20 ( = 0x14 )
darray[0][0] = 0000, &darray[0][0] = 0xbf9da14c
darray[0][1] = 0001, &darray[0][1] = 0xbf9da150
darray[0][2] = 0002, &darray[0][2] = 0xbf9da154
darray[0][3] = 0003, &darray[0][3] = 0xbf9da158
darray[0][4] = 0004, &darray[0][4] = 0xbf9da15c
darray[1][0] = 1000, &darray[1][0] = 0xbf9da160
darray[1][1] = 1001, &darray[1][1] = 0xbf9da164
darray[1][2] = 1002, &darray[1][2] = 0xbf9da168
darray[1][3] = 1003, &darray[1][3] = 0xbf9da16c
darray[1][4] = 1004, &darray[1][4] = 0xbf9da170
darray[2][0] = 2000, &darray[2][0] = 0xbf9da174
darray[2][1] = 2001, &darray[2][1] = 0xbf9da178
darray[2][2] = 2002, &darray[2][2] = 0xbf9da17c
darray[2][3] = 2003, &darray[2][3] = 0xbf9da180
darray[2][4] = 2004, &darray[2][4] = 0xbf9da184
C:\usr\c\> 

sample-003

Download : sample-003.c ( SJIS 版 )

sample-003.c
#include <stdio.h>

#define	ROW_SIZE	3
#define	COL_SIZE	5

int main ( void ) {

  int darray[ROW_SIZE][COL_SIZE];
  int col;
  int *iptr;			// 整数型変数へのポインタ
  int (*dptr)[COL_SIZE];	// サイズ COL_SIZE の整数型配列へのポインタ
				// (*dptr) が int [COL_SIZE] となっている

  /*
   */

  printf ( "二次元配列のサイズ\n" );
  printf ( "sizeof( int )       = %3d\n", sizeof ( int ) );
  printf ( "sizeof( int ) * %d  = %3d\n", COL_SIZE, sizeof ( int ) * COL_SIZE );
  printf ( "sizeof( darray[0] ) = %3d\n", sizeof ( darray[0] ) );
  printf ( "sizeof( darray    ) = %3d\n", sizeof ( darray ) );

  /*
   */

  printf ( "二次元配列のアドレス値\n" );
  printf ( " darray        = %p\n",  darray );
  printf ( " darray[0]     = %p\n",  darray[0] );
  printf ( " darray[0] + 1 = %p\n",  darray[0] + 1 );
  printf ( "&darray[0][1]  = %p\n", &darray[0][1] );

  /*
   */

  printf ( "二次元配列の一部を指すポインター\n" );

  iptr = darray[2];		// iptr は 2 行目を指す ( &darray[2][0] に同じ )
  for ( col = 0; col < COL_SIZE; col++ ) {
    iptr[col] = col * col;	// ポインター経由で、2 行目の要素を書き換える
  }

  for ( col = 0; col < COL_SIZE; col++ ) {
    printf ( " darray[2][%d] = %d\n", col, darray[2][col] );
  }

  /*
   */

  dptr = darray;		// 二次元配列へのポインターの初期化

  for ( col = 0; col < COL_SIZE; col++ ) {
    printf ( " dptr[2][%d] = %d\n", col, dptr[2][col] );
  }

  /*
   */

  return 0;
}
sample-003.c の実行結果
C:\usr\c\> sample-003
二次元配列のサイズ
sizeof( int )       =   4
sizeof( int ) * 5  =  20
sizeof( darray[0] ) =  20
sizeof( darray    ) =  60
二次元配列のアドレス値
 darray        = 0xbf9c3978
 darray[0]     = 0xbf9c3978
 darray[0] + 1 = 0xbf9c397c
&darray[0][1]  = 0xbf9c397c
二次元配列の一部を指すポインター
 darray[2][0] = 0
 darray[2][1] = 1
 darray[2][2] = 4
 darray[2][3] = 9
 darray[2][4] = 16
 dptr[2][0] = 0
 dptr[2][1] = 1
 dptr[2][2] = 4
 dptr[2][3] = 9
 dptr[2][4] = 16
C:\usr\c\> 

sample-004

Download : sample-004.c ( SJIS 版 )

sample-004.c
#include <stdio.h>

#define	ROW_SIZE	3
#define	COL_SIZE	5

int main ( void ) {

  int darray[ROW_SIZE][COL_SIZE];
  int row;
  int col;
  int *iptr;			// 単純な整数へのポインタ
  int index;

  /*
   */

  for ( row = 0; row < ROW_SIZE; row++ ) {
    for ( col = 0; col < COL_SIZE; col++ ) {
      darray [ row ][ col ] = row * 1000 + col;
    }
  }

  for ( row = 0; row < ROW_SIZE; row++ ) {
    for ( col = 0; col < COL_SIZE; col++ ) {
      printf ( "%04d ", darray [ row ][ col ] );
    }
    printf ( "\n" );
  }

  /*
   */

  iptr = (int *)darray;	// 二次元の配列の領域を一次元の配列として参照する

  for ( index = 0; index < ROW_SIZE * COL_SIZE; index++ ) {
    printf ( "iptr[%d] = %04d ( %d, %d )\n", index, iptr [ index ], index / COL_SIZE, index % COL_SIZE );
  }

  /*
   */

  return 0;
}
sample-004.c の実行結果
C:\usr\c\> sample-004
0000 0001 0002 0003 0004 
1000 1001 1002 1003 1004 
2000 2001 2002 2003 2004 
iptr[0] = 0000 ( 0, 0 )
iptr[1] = 0001 ( 0, 1 )
iptr[2] = 0002 ( 0, 2 )
iptr[3] = 0003 ( 0, 3 )
iptr[4] = 0004 ( 0, 4 )
iptr[5] = 1000 ( 1, 0 )
iptr[6] = 1001 ( 1, 1 )
iptr[7] = 1002 ( 1, 2 )
iptr[8] = 1003 ( 1, 3 )
iptr[9] = 1004 ( 1, 4 )
iptr[10] = 2000 ( 2, 0 )
iptr[11] = 2001 ( 2, 1 )
iptr[12] = 2002 ( 2, 2 )
iptr[13] = 2003 ( 2, 3 )
iptr[14] = 2004 ( 2, 4 )
C:\usr\c\> 

sample-005

Download : sample-005.c ( SJIS 版 )

sample-005.c
#include <stdio.h>

#define	ROW_SIZE	3
#define	COL_SIZE	5

int main ( void ) {

  int darray[ROW_SIZE][COL_SIZE];
  int row;
  int col;
  int (*marray)[ROW_SIZE];

  /*
   */

  for ( row = 0; row < ROW_SIZE; row++ ) {
    for ( col = 0; col < COL_SIZE; col++ ) {
      darray [ row ][ col ] = row * 1000 + col;
    }
  }

  marray = (int (*)[ROW_SIZE])darray;	// 型を変えれば、違う二次元配列に見える

  for ( col = 0; col < COL_SIZE; col++ ) {
    for ( row = 0; row < ROW_SIZE; row++ ) {
      printf ( "%04d ", marray [ col ][ row ] );
    }
    printf ( "\n" );
  }

  /*
   */

  return 0;
}
sample-005.c の実行結果
C:\usr\c\> sample-005
0000 0001 0002 
0003 0004 1000 
1001 1002 1003 
1004 2000 2001 
2002 2003 2004 
C:\usr\c\> 

sample-006

Download : sample-006.c ( SJIS 版 )

sample-006.c
#include <stdio.h>

#define	ROW_SIZE	3
#define	COL_SIZE	5

int main ( void ) {

  int darray[ROW_SIZE][COL_SIZE];
  int *parray[ROW_SIZE];	// ROW_SIZE 個のポインター型変数からなる配列
				// 「int *(parray[i])」 なので、
  				// 添字([i]) を付けるとポインター値 (int *)
  int row;
  int col;

  /*
   */

  for ( row = 0; row < ROW_SIZE; row++ ) {
    parray[row] = darray[row];	// darray の各々の行へのポインターを parray に代入
  }

  /*
   */

  for ( col = 0; col < COL_SIZE; col++ ) {
    parray[2][col] = col * col;	// parray を利用して、darray の 2 行目を変更
  }

  for ( col = 0; col < COL_SIZE; col++ ) {
    printf ( "darray[2][%d] = %d\n", col, darray[2][col] );
  }

  /*
   */

  return 0;
}
sample-006.c の実行結果
C:\usr\c\> sample-006
darray[2][0] = 0
darray[2][1] = 1
darray[2][2] = 4
darray[2][3] = 9
darray[2][4] = 16
C:\usr\c\> 

sample-007

Download : sample-007.c ( SJIS 版 )

sample-007.c
#include <stdio.h>

#define	ROW_SIZE	5
#define	BASE_SIZE	((ROW_SIZE)*((ROW_SIZE)+1)/2)

int main ( void ) {

  int barray[BASE_SIZE];
  int index;

  int *parray[ROW_SIZE];	// ROW_SIZE 個のポインター型変数からなる配列
  int row;
  int col;

  /*
   */

  parray[0] = barray;
  for ( row = 1; row < ROW_SIZE; row++ ) {
    parray[row] = parray[row-1] + row;
  }

  /*
   */

  for ( row = 0; row < ROW_SIZE; row++ ) {
    for ( col = 0; col <= row ; col++ ) {
      parray[row][col] = row * 1000 + col;
    }
  }

  /*
   */

  for ( index = 0; index < BASE_SIZE; index++ ) {
    printf ( "barray[%2d] = %04d\n", index, barray[index] );
  }

  /*
   */

  return 0;
}
sample-007.c の実行結果
C:\usr\c\> sample-007
barray[ 0] = 0000
barray[ 1] = 1000
barray[ 2] = 1001
barray[ 3] = 2000
barray[ 4] = 2001
barray[ 5] = 2002
barray[ 6] = 3000
barray[ 7] = 3001
barray[ 8] = 3002
barray[ 9] = 3003
barray[10] = 4000
barray[11] = 4001
barray[12] = 4002
barray[13] = 4003
barray[14] = 4004
C:\usr\c\> 

sample-008

Download : sample-008.c ( SJIS 版 )

sample-008.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define PASCAL_SIZE	6
#define FIELD_SIZE	3

/*
 *
 */

void print_pascal ( int pascal_array[PASCAL_SIZE][PASCAL_SIZE] ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < PASCAL_SIZE; deep++ ) {
		for ( width = 0; width < PASCAL_SIZE - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_array[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 *
 */

void	make_pascal_array ( int pascal_array[PASCAL_SIZE][PASCAL_SIZE] ) {
	int	deep;
	int	width;

	pascal_array[0][0] = 1;
	for ( deep = 1; deep < PASCAL_SIZE; deep++ ) {
		pascal_array[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_array[deep][width] = pascal_array[deep-1][width-1] + pascal_array[deep-1][width];
		}
		pascal_array[deep][width] = 1;
	}

}

/*
 *
 */

int main(void) {
  	int pascal_array[PASCAL_SIZE][PASCAL_SIZE];

	make_pascal_array ( pascal_array );
	printf ( "\nPasscal Triangle\n" );
	print_pascal ( pascal_array );

	return 0;
}
sample-008.c の実行結果
C:\usr\c\> sample-008

Passcal Triangle
                       1
                    1     1
                 1     2     1
              1     3     3     1
           1     4     6     4     1
        1     5    10    10     5     1
C:\usr\c\> 

sample-009

Download : sample-009.c ( SJIS 版 )

sample-009.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define	PASCAL_SIZE	6
#define	FIELD_SIZE	3

/*
 *
 */

void print_pascal ( int *pascal_triangle[PASCAL_SIZE] ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < PASCAL_SIZE; deep++ ) {
		for ( width = 0; width < PASCAL_SIZE - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_triangle[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 *
 */

void	make_pascal_triangle ( int *pascal_triangle[PASCAL_SIZE] ) {
	int	deep;
	int	width;

	pascal_triangle[0][0] = 1;
	for ( deep = 1; deep < PASCAL_SIZE; deep++ ) {
		pascal_triangle[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_triangle[deep][width] = pascal_triangle[deep-1][width-1] + pascal_triangle[deep-1][width];
		}
		pascal_triangle[deep][width] = 1;
	}

}

/*
 *
 */

#define BASE_SIZE	((PASCAL_SIZE)*((PASCAL_SIZE)+1)/2)

int main ( void ) {
	int pascal_base [ BASE_SIZE ];
	int *pascal_triangle[ PASCAL_SIZE ];
	int row;

	pascal_triangle[0] = pascal_base;
	for ( row = 1; row < PASCAL_SIZE; row++ ) {
		pascal_triangle[row] = pascal_triangle[row-1] + row;
	}

	make_pascal_triangle ( pascal_triangle );
	printf ( "\nPasscal Triangle\n" );
	print_pascal ( pascal_triangle );

	return 0;
}
sample-009.c の実行結果
C:\usr\c\> sample-009

Passcal Triangle
                       1
                    1     1
                 1     2     1
              1     3     3     1
           1     4     6     4     1
        1     5    10    10     5     1
C:\usr\c\> 

sample-010

Download : sample-010.c ( SJIS 版 )

sample-010.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define	FIELD_SIZE	3

/*
 *
 */

void print_pascal ( int *pascal_pointer[], int size ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < size; deep++ ) {
		for ( width = 0; width < size - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_pointer[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 *
 */

void	make_pascal_triangle ( int *pascal_pointer[], int size ) {
	int	deep;
	int	width;

	pascal_pointer[0][0] = 1;
	for ( deep = 1; deep < size; deep++ ) {
		pascal_pointer[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_pointer[deep][width] = pascal_pointer[deep-1][width-1] + pascal_pointer[deep-1][width];
		}
		pascal_pointer[deep][width] = 1;
	}

}

/*
 *
 */

#define PASCAL_SIZE	6
#define BASE_SIZE	((PASCAL_SIZE)*((PASCAL_SIZE)+1)/2)

int main(void) {
	int pascal_base [ BASE_SIZE ];
	int *pascal_pointer[ PASCAL_SIZE ];
	int row;

	pascal_pointer[0] = pascal_base;
	for ( row = 1; row < PASCAL_SIZE; row++ ) {
		pascal_pointer[row] = pascal_pointer[row-1] + row;
	}

	make_pascal_triangle ( pascal_pointer, PASCAL_SIZE );
	printf ( "\nPasscal Triangle\n" );
	print_pascal ( pascal_pointer, PASCAL_SIZE );

	return 0;
}
sample-010.c の実行結果
C:\usr\c\> sample-010

Passcal Triangle
                       1
                    1     1
                 1     2     1
              1     3     3     1
           1     4     6     4     1
        1     5    10    10     5     1
C:\usr\c\> 

sample-011

Download : sample-011.c ( SJIS 版 )

sample-011.c
#include <stdio.h>

void sub1_1() {
	int sub1_1_v;

	printf ( "&sub1_1_v = %p\n", &sub1_1_v );
}

void sub1_2() {
	int sub1_2_v;

	printf ( "&sub1_2_v = %p\n", &sub1_2_v );
}

void sub2_1() {
	int sub2_1_v;

	printf ( "&sub2_1_v = %p\n", &sub2_1_v );
}

void sub2_2() {
	int sub2_2_v;

	printf ( "&sub2_2_v = %p\n", &sub2_2_v );
}

void sub1() {
	int sub1_v;

	printf ( "&sub1_v = %p\n", &sub1_v );
	sub1_1();
	sub1_2();
}

void sub2() {
	int sub2_v;

	printf ( "&sub2_v = %p\n", &sub2_v );
	sub2_1();
	sub2_2();
}


int main ( void ) {
	int main_v;

	printf ( "&main_v = %p\n", &main_v );
	sub1();
	sub2();

	return 0;
}
sample-011.c の実行結果
C:\usr\c\> sample-011
&main_v = 0xbff40c9c
&sub1_v = 0xbff40c6c
&sub1_1_v = 0xbff40c3c
&sub1_2_v = 0xbff40c3c
&sub2_v = 0xbff40c6c
&sub2_1_v = 0xbff40c3c
&sub2_2_v = 0xbff40c3c
C:\usr\c\> 

sample-012

Download : sample-012.c ( SJIS 版 )

sample-012.c
#include <stdio.h>

void sub_sub() {
	int sub_sub_v;

	printf ( "&sub_sub_v = %p\n", &sub_sub_v );
}

void sub1() {
	int sub1_v;

	printf ( "&sub1_v = %p\n", &sub1_v );
	sub_sub();
}

void sub2() {
	int sub2_v;
	int array[5];

	printf ( "&sub2_v = %p\n", &sub2_v );
	sub_sub();
}


int main ( void ) {
	int main_v;

	printf ( "&main_v = %p\n", &main_v );
	sub1();
	sub2();

	return 0;
}
sample-012.c の実行結果
C:\usr\c\> sample-012
&main_v = 0xbfed474c
&sub1_v = 0xbfed471c
&sub_sub_v = 0xbfed46ec
&sub2_v = 0xbfed471c
&sub_sub_v = 0xbfed46dc
C:\usr\c\> 

sample-013

Download : sample-013.c ( SJIS 版 )

sample-013.c
/*
 *
 */

#include <stdio.h>

/*
 *
 */

void reverse ( int array[], int size ) {
	int index;

	for ( index = 0; index < size; index++ ) {
	  printf ( "%d ", array[size-index-1] );
	}
	printf ( "\n" );

}

/*
 * 入力された数値を逆順に出力する ( 従来の配列版 )
 */

#define ARRAY_SIZE	10

/*
 *
 */

int main ( void ) {
	int array[ARRAY_SIZE];	// 配列のサイズはこの時点で決定される
	int index;

	printf ( "%d 以下の個数の非負の整数値をいれてください。\n", ARRAY_SIZE );
	printf ( "%d 個の数か、あるいは負の整数値をいれると入力は終了します。\n", ARRAY_SIZE );

	for ( index = 0; index < ARRAY_SIZE; index++ ) {
		scanf ( "%d", &array[index] );
		if ( array[index] < 0 ) {
			break;
		}
	}

	reverse ( array, index );

	return 0;
}

/*
 *
 */
入力例
3
9
8
4
7
-1
sample-013.c の実行結果
C:\usr\c\> sample-013
10 以下の個数の非負の整数値をいれてください。
10 個の数か、あるいは負の整数値をいれると入力は終了します。
3
9
8
4
7
-1
7 4 8 9 3 
C:\usr\c\> 

sample-014

Download : sample-014.c ( SJIS 版 )

sample-014.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>	// malloc/free を利用する場合に追加

/*
 *
 */

void reverse ( int array[], int size ) {
	int index;

	for ( index = 0; index < size; index++ ) {
	  printf ( "%d ", array[size-index-1] );
	}
	printf ( "\n" );

}

/*
 * 入力された数値を逆順に出力する ( malloc / free 版 )
 */

#define ARRAY_SIZE	10

/*
 *
 */

int main ( void ) {
	int *array;	// 配列のサイズはこの時点では決定されていない
	int index;

	array = malloc ( sizeof(int) * ARRAY_SIZE );
			// malloc を利用して、必要なサイズのメモりーを確保
			// 最初に决める必要がないことに注意

	if ( array != NULL ) { // 確保に成功した場合だけ

		printf ( "%d 以下の個数の非負の整数値をいれてください。\n", ARRAY_SIZE );
		printf ( "%d 個の数か、あるいは負の整数値をいれると入力は終了します。\n", ARRAY_SIZE );

		for ( index = 0; index < ARRAY_SIZE; index++ ) {
			scanf ( "%d", &array[index] );
			if ( array[index] < 0 ) {
				break;
			}
		}

		reverse ( array, index );

		free ( array );		// 確保したら開放も行う必要がある

	} else {
		printf ( "array の領域の確保に失敗しました\n" );
	}

	return 0;
}

/*
 *
 */
入力例
3
9
8
4
7
-1
sample-014.c の実行結果
C:\usr\c\> sample-014
10 以下の個数の非負の整数値をいれてください。
10 個の数か、あるいは負の整数値をいれると入力は終了します。
3
9
8
4
7
-1
7 4 8 9 3 
C:\usr\c\> 

sample-015

Download : sample-015.c ( SJIS 版 )

sample-015.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>	// malloc/free を利用する場合に追加

/*
 *
 */

void reverse ( int array[], int size ) {
	int index;

	for ( index = 0; index < size; index++ ) {
	  printf ( "%d ", array[size-index-1] );
	}
	printf ( "\n" );

}

/*
 * 入力された数値を逆順に出力する ( malloc / free 版 )
 * 入力する数値の個数もいれさせる。
 */

int main ( void ) {
	int *array;	// 配列のサイズはこの時点では決定されていない
	int index;
	int num_size;	// 入力するデータの個数

	printf ( "入力データ数をいれてください\n" );
	scanf ( "%d", &num_size );

	array = malloc ( sizeof(int) * num_size );
			// 必要なサイズを入力して决める事ができる

	if ( array != NULL ) { // 確保に成功した場合だけ

		printf ( "%d 以下の個数の非負の整数値をいれてください。\n", num_size );
		printf ( "%d 個の数か、あるいは負の整数値をいれると入力は終了します。\n", num_size );

		for ( index = 0; index < num_size; index++ ) {
			scanf ( "%d", &array[index] );
			if ( array[index] < 0 ) {
				break;
			}
		}

		reverse ( array, index );

		free ( array );		// 確保したら開放も行う必要がある

	} else {
		printf ( "array の領域の確保に失敗しました\n" );
	}

	return 0;
}

/*
 *
 */
入力例
5
3
9
8
4
7
sample-015.c の実行結果
C:\usr\c\> sample-015
入力データ数をいれてください
5
5 以下の個数の非負の整数値をいれてください。
5 個の数か、あるいは負の整数値をいれると入力は終了します。
3
9
8
4
7
7 4 8 9 3 
C:\usr\c\> 

sample-016

Download : sample-016.c ( SJIS 版 )

sample-016.c
/*
 *
 */

#include <stdio.h>
#include <stdlib.h>	// malloc/free を利用する場合に追加

/*
 *
 */

#define	END_OF_ARRAY		(-1)
#define	is_end_array(X)	((X)<0)

/*
 *	指定された配列の内容を逆に出力する ( ポインター / 再帰版 )
 */

void reverse_print ( int *array ) {

	if ( ! is_end_array( *array ) ) {	/* 最後でない */
		reverse_print ( array + 1 );	/* 逆順なので、残りを先に出力する */
		printf ( "%d ", *array );	/* 先頭の要素を出力 */
	}					/* 最後なので何もしない */

}

/*
 * 負の数が入力されるまで、整数値を入力し、その結果を配列に入れて返す
 */

int *input_any_size_data ( int size ) {
	int *input_array;
	int input_data;

	scanf ( "%d", &input_data );	/* とりあえず、データの入力させる */

	if ( input_data > 0 ) {					/* まだ、データは続く */
		input_array = input_any_size_data ( size + 1 );	/* 続きのデータ入力 */
	  	if ( input_array != NULL ) {				/* 領域が確保できた */
			input_array[size] = input_data;		/* データを配列にセット */
		}
	} else {							/* 入力は終った */
		input_array = malloc ( sizeof(int) * ( size + 1 ) );	/* 領域を確保(EOA のために + 1) */
		if ( input_array != NULL ) {				/* 確保できれば */
			input_array [ size ] = END_OF_ARRAY;		/* 入力の終了を表す数値を入れる */
		}
	}

	return input_array;						/* 結果を返す */
}

/*
 * 入力された数値を逆順に出力する ( malloc / free 版 )
 */

int main ( void ) {
	int *array;	// 配列のサイズはこの時点では決定されていない
	int index;

	printf ( "複数の非負の整数値をいれてください。\n" );
	printf ( "負の整数値をいれると入力は終了します。\n" );

	array = input_any_size_data ( 0 );	/* 入力するデータ数には制限がない */

	if ( array != NULL ) {			/* 領域が確保できたら.. */
		printf ( "入力されたデータを逆順に出力します\n" );
		reverse_print ( array );	/* 逆順の表示 : サイズは指定しない (EOA で示す) */
		printf ( "\n" );
		free ( array );		/* 確保したら必ず開放も行う必要がある */
	} else {				/* 領域の失敗も配慮する必要がある */
		printf ( "array の領域の確保に失敗しました\n" );
	}

	return 0;
}

/*
 *
 */
入力例
7
8
3
1
4
2
9
5
-1
sample-016.c の実行結果
C:\usr\c\> sample-016
複数の非負の整数値をいれてください。
負の整数値をいれると入力は終了します。
7
8
3
1
4
2
9
5
-1
入力されたデータを逆順に出力します
5 9 2 4 1 3 8 7 
C:\usr\c\> 

本日の課題

[問題]与えられたサイズのパスカルの三角形を作成して表示するプログラムを作成しなさい

課題プログラム内の「/*名前:ここ*/」の部分を書き換えてプログラムを完成させます。なお「名前」の部分が同じ所には同じものが入ります。

課題 20101203-01

Download : 20101203-01.c ( SJIS 版 )

20101203-01.c
/*
 * 課題 パスカルの三角形(二次元配列版) 20101203-01
 */

/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define	FIELD_SIZE		3
#define	PASCAL_MAX_SIZE	10

/*
 * パスカルの三角形をプリントアウトする
 */

void print_pascal ( /* a:ここに pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < size; deep++ ) {
		for ( width = 0; width < size - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_triangle[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 * パスカルの三角形を作成する
 */

void	make_pascal_triangle ( /* a:ここに pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	pascal_triangle[0][0] = 1;
	for ( deep = 1; deep < size; deep++ ) {
		pascal_triangle[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_triangle[deep][width] = /* b:ここに pascal_triangle と deep と width からなる式が入る */;
		}
		pascal_triangle[deep][width] = 1;
	}
}

/*
 * 二次元配列を利用したパスカルの三角形
 *
 *	nCr = pascal_triangle[n][r] となるが、
 *		n\r| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 
 *		---+---+---+---+---+---+---+---+---+---+---
 *		 0 |0C0| - | - | - | - | - | - | - | - | -
 *		 1 |1C0|1C1| - | - | - | - | - | - | - | -
 *		 2 |2C0|2C1|2C2| - | - | - | - | - | - | -
 *		 		...
 *		 9 |8C0|8C1|8C2|8C3|8C4|8C5|8C6|8C7|8C8| -
 *		 9 |9C0|9C1|9C2|9C3|9C4|9C5|9C6|9C7|9C8|9C9
 *	と、半分しか配列を使わない
 */

int main(void) {
	int size;
	/* a:ここに pascal_triangle の宣言が入る */;

	printf ( "Pascal Size ( 1 - %d ) = ", PASCAL_MAX_SIZE - 1 );
	scanf ( "%d", &size );

	if ( 0 < size && size < PASCAL_MAX_SIZE ) {
	  make_pascal_triangle ( pascal_triangle, size );
	  printf ( "\nPasscal Triangle\n" );
	  print_pascal ( pascal_triangle, size );
	} else {
	  printf ( "error : size must be 1 - %d\n", PASCAL_MAX_SIZE - 1 );
	}

	return 0;
}
入力例
9
20101203-01.c の実行結果
C:\usr\c\> 20101203-01
Pascal Size ( 1 - 9 ) = 9

Passcal Triangle
                                1
                             1     1
                          1     2     1
                       1     3     3     1
                    1     4     6     4     1
                 1     5    10    10     5     1
              1     6    15    20    15     6     1
           1     7    21    35    35    21     7     1
        1     8    28    56    70    56    28     8     1
C:\usr\c\> 

課題 20101203-02

Download : 20101203-02.c ( SJIS 版 )

20101203-02.c
/*
 * 課題 パスカルの三角形(ポインタ配列版) 20101203-02
 */

/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define	FIELD_SIZE		3
#define	PASCAL_MAX_SIZE	10

/*
 * パスカルの三角形をプリントアウトする
 */

void print_pascal ( /* a:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < size; deep++ ) {
		for ( width = 0; width < size - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_triangle[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 * パスカルの三角形を作成する
 */

void	make_pascal_triangle ( /* a:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	pascal_triangle[0][0] = 1;
	for ( deep = 1; deep < size; deep++ ) {
		pascal_triangle[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_triangle[deep][width] = /* d:ここに pascal_triangle と deep と width からなる式が入る */;
				/* パスカルの三角の値の計算 */
		}
		pascal_triangle[deep][width] = 1;
	}

}

/*
 * パスカルの三角形を入れる pascal_triangle を作成する
 */

void	make_pointer_array ( /* a:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_triangle の宣言が入る */, /* b:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_base の宣言が入る */, int size ) {
	int	deep;

	for ( deep = 0; deep < size; deep++ ) {
		pascal_triangle[deep] = /* c: pascal_base と deep を使った式が入る */;
	}
}

/*
 * ポインター配列を利用したパスカルの三角形
 *
 *	nCr = pascal_triangle[n][r] となり、
 *		pascal_triangle[0][0] = pascal_base[0] = 0C0
 *		pascal_triangle[1][0] = pascal_base[1] = 1C0
 *		pascal_triangle[1][1] = pascal_base[2] = 1C1
 *		pascal_triangle[2][0] = pascal_base[3] = 2C0
 *		pascal_triangle[2][1] = pascal_base[4] = 2C1
 *		pascal_triangle[2][2] = pascal_base[5] = 2C2
 *				...
 *		pascal_triangle[9][8] = pascal_base[53] = 9C8
 *		pascal_triangle[9][9] = pascal_base[54] = 9C9
 *	という対応関係になる
 */

int main(void) {
	int size;
	/* a:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_triangle の宣言が入る */;
	/* b:ここに、PASCAL_MAX_SIZE のサイズに対応した pascal_base の宣言が入る */;

	printf ( "Pascal Size ( 1 - %d ) = ", PASCAL_MAX_SIZE - 1 );
	scanf ( "%d", &size );

	if ( 0 < size && size < PASCAL_MAX_SIZE ) {
	   make_pointer_array ( pascal_triangle, pascal_base, size );
	   make_pascal_triangle ( pascal_triangle, size );
	   printf ( "\nPasscal Triangle\n" );
	   print_pascal ( pascal_triangle, size );
	} else {
		printf ( "error : size must be 1 - %d\n", PASCAL_MAX_SIZE - 1 );
	}

	return 0;
}
入力例
9
20101203-02.c の実行結果
C:\usr\c\> 20101203-02
Pascal Size ( 1 - 9 ) = 9

Passcal Triangle
                                1
                             1     1
                          1     2     1
                       1     3     3     1
                    1     4     6     4     1
                 1     5    10    10     5     1
              1     6    15    20    15     6     1
           1     7    21    35    35    21     7     1
        1     8    28    56    70    56    28     8     1
C:\usr\c\> 

課題 20101203-03

Download : 20101203-03.c ( SJIS 版 )

20101203-03.c
/*
 * 課題 パスカルの三角形(alloc 版) 20101203-03
 */

/*
 *
 */

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

#define	FIELD_SIZE		3

/*
 *
 */

#define	xalloc(Type,Size)	((Type *) malloc( sizeof (Type) * (Size) ))

/*
 * パスカルの三角形をプリントアウトする
 */

void print_pascal ( /* a:ここに、pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	for ( deep = 0; deep < size; deep++ ) {
		for ( width = 0; width < size - deep; width++ ) {
			printf ( "%*s", FIELD_SIZE, "" );
		}
		for ( width = 0; width < deep + 1; width++ ) {
			printf ( "%*d", FIELD_SIZE * 2, pascal_triangle[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 * パスカルの三角形を作成する
 */

void	make_pascal_triangle ( /* a:ここに、pascal_triangle の宣言が入る */, int size ) {
	int	deep;
	int	width;

	pascal_triangle[0][0] = 1;
	for ( deep = 1; deep < size; deep++ ) {
		pascal_triangle[deep][0] = 1;
		for ( width = 1; width < deep; width++ ) {
			pascal_triangle[deep][width] = /* e:ここに pascal_triangle と deep と width からなる式が入る */;
		}
		pascal_triangle[deep][width] = 1;
	}

}

/*
 * パスカルの三角形を入れる pascal_triangle を作成する
 */

void	free_pascal_triangle ( /* a:ここに、pascal_triangle の宣言が入る */, int size ) {
	int	deep;

	if ( /* c:ここに、確保したメモリへのポインタを保存する変数が入る */ != NULL ) {
		for ( deep = 0; deep < size; deep++ ) {
			if ( /* b:ここに、解放するメモリへのポインタの値が入る */ == NULL ) {
				break;
			}
			free ( /* b:ここに、解放するメモリへのポインタの値が入る */ );
		}
		free ( /* c:ここに、確保したメモリへのポインタを保存する変数が入る */ );
	}
}

/*
 *
 */

int	**alloc_pascal_triangle ( int size ) {
	/* a:ここに、pascal_triangle の宣言が入る */;
	int deep;

	if ( ( /* c:ここに、確保したメモリへのポインタを保存する変数が入る */ = xalloc ( int *, size ) ) != NULL ) {
		for ( deep = 0; deep < size; deep++ ) {
			if ( ( /* b:ここに、解放するメモリへのポインタの値が入る */ = xalloc ( int, deep + 1 ) ) == NULL ) {
				free_pascal_triangle ( /* c:ここに、確保したメモリへのポインタを保存する変数が入る */, size );
				/* c:ここに、確保したメモリへのポインタを保存する変数が入る */ = NULL;
				break;
			}
		}
	}

	return pascal_triangle;
}

/*
 * alloc を利用したパスカルの三角形
 *
 *	nCr = pascal_triangle[n][r] となり、
 *		pascal_triangle = { { 0C0 }
 *		                    { 1C0, 1C1 },
 *		                    { 2C0, 2C1, 2C2 },
 *				          ...
 *		                    { 9C0, 9C1, ..., 9C9 } }
 *	という対応関係になる
 */

int main(void) {
	int size;
	/* a:ここに、pascal_triangle の宣言が入る */;

	printf ( "Pascal Size = ( 1 - )" );	/* 動的に領域を確保するので、サイズの制限はない */
	scanf ( "%d", &size );

	if ( size > 0 ) {
		if ( ( pascal_triangle = alloc_pascal_triangle ( size ) ) != NULL ) {
			make_pascal_triangle ( pascal_triangle, size );
			printf ( "\nPasscal Triangle\n" );
			print_pascal ( pascal_triangle, size );
			free_pascal_triangle ( pascal_triangle, size );
		} else {
			printf ( "error : Too huge size(%d)\n", size );
		}
	} else {
		printf ( "error : size(%d) must be positive\n", size );
	}

	return 0;
}
入力例
12
20101203-03.c の実行結果
C:\usr\c\> 20101203-03
Pascal Size = ( 1 - )12

Passcal Triangle
                                         1
                                      1     1
                                   1     2     1
                                1     3     3     1
                             1     4     6     4     1
                          1     5    10    10     5     1
                       1     6    15    20    15     6     1
                    1     7    21    35    35    21     7     1
                 1     8    28    56    70    56    28     8     1
              1     9    36    84   126   126    84    36     9     1
           1    10    45   120   210   252   210   120    45    10     1
        1    11    55   165   330   462   462   330   165    55    11     1
C:\usr\c\>