Powered by SmartDoc

ソフトウェア概論B (2009/11/27)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

当日のOHP資料です。

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

sample-001

Download : sample-001.c ( SJIS 版 )

sample-001.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-001.c の実行結果
C:\usr\c\> sample-001
二次元配列のサイズ
sizeof( int )       =   4
sizeof( int ) * 5  =  20
sizeof( darray[0] ) =  20
sizeof( darray    ) =  60
二次元配列のアドレス値
 darray        = 0xbfdf321c
 darray[0]     = 0xbfdf321c
 darray[0] + 1 = 0xbfdf3220
&darray[0][1]  = 0xbfdf3220
二次元配列の一部を指すポインター
 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-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;
  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-002.c の実行結果
C:\usr\c\> sample-002
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-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 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-003.c の実行結果
C:\usr\c\> sample-003
0000 0001 0002 
0003 0004 1000 
1001 1002 1003 
1004 2000 2001 
2002 2003 2004 
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 *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-004.c の実行結果
C:\usr\c\> sample-004
darray[2][0] = 0
darray[2][1] = 1
darray[2][2] = 4
darray[2][3] = 9
darray[2][4] = 16
C:\usr\c\> 

sample-005

Download : sample-005.c ( SJIS 版 )

sample-005.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-005.c の実行結果
C:\usr\c\> sample-005
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-006

Download : sample-006.c ( SJIS 版 )

sample-006.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	pascal_triangle ( 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];

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

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

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-007

Download : sample-007.c ( SJIS 版 )

sample-007.c
/*
 *
 */

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

/*
 *
 */

#define PASCAL_SIZE	6
#define	FIELD_SIZE	3

/*
 *
 */

void print_pascal ( int *pascal_pointer[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_pointer[deep][width] );
		}
		printf ( "\n" );
	}
}

/*
 *
 */

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

	pascal_pointer[0][0] = 1;
	for ( deep = 1; deep < PASCAL_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 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;
	}

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

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

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-008

Download : sample-008.c ( SJIS 版 )

sample-008.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	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;
	}

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

	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>

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-009.c の実行結果
C:\usr\c\> sample-009
&main_v = 0xbf8edcb0
&sub1_v = 0xbf8edc84
&sub1_1_v = 0xbf8edc64
&sub1_2_v = 0xbf8edc64
&sub2_v = 0xbf8edc84
&sub2_1_v = 0xbf8edc64
&sub2_2_v = 0xbf8edc64
C:\usr\c\> 

sample-010

Download : sample-010.c ( SJIS 版 )

sample-010.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-010.c の実行結果
C:\usr\c\> sample-010
&main_v = 0xbfad8f10
&sub1_v = 0xbfad8ee4
&sub_sub_v = 0xbfad8ec4
&sub2_v = 0xbfad8ee4
&sub_sub_v = 0xbfad8eb4
C:\usr\c\> 

sample-011

Download : sample-011.c ( SJIS 版 )

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

sample-012

Download : sample-012.c ( SJIS 版 )

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

sample-013

Download : sample-013.c ( SJIS 版 )

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

課題

malloc の利用法

課題20091127-01
mallocとfreeをもちいて、プログラムの実行後に、指定される任意のサイズのパスカルの三角形を作り、それを表示するプログラムを作成しなさい。

課題の実行例

20091127-1

入力例
9
20091127-1.c の実行結果
C:\usr\c\> 20091127-1
Pascal Size = 
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\> 

参考 Link