Powered by SmartDoc

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

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

目次

講義資料

当日の OHP 資料

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

Download : sample-001.c

sample-001.c
/*
 * 2018/12/14 sample-001.c
 */

/*
 * 多次元配列
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-001.c
 *		リンク 
 *			cc -o sample-001.exe sample-001.c 
 *		実行
 *			./sample-001.exe
 */

#include <stdio.h>

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int a[3][4];	/* 二次元配列の宣言 3 x 4 (= 12) 個の変数を宣言 */
					/* int a00, a01, .., a03, a10, .., a13, .., a23; と同様 */
	int i;
	int j;

	a[0][0] = 0;	/* 添字は、二つ必要 ( 二次なので.. ) で、0 から始まる */
	a[2][3] = 6;	/* 添字の大きさは、配列の大きさ - 1 まで */

	/* 0 〜 2 と 0 〜 3 のかけ算表を作ってみる */
	for ( i = 0; i < 3; i++ )	{
		for ( j = 0; j < 4; j++ ) {
			a[i][j] = i * j;	/* a[i][j] 成分の値が i*j になるようにする */
		}
	}

	printf ( "2 * 1 = %d\n", a[2][1] );	/* 2 と表示される筈 */

	if ( a[1][2] == a[2][1] ) {	/* 1 * 2 = 2 * 1 か ? */
		printf ( "1 * 2 = 2 * 1 が成立\n" );
	} else {
		printf ( "1 * 2 = 2 * 1 が成立しない.. 何か変だ..\n" );
	}

	/* 0 〜 2 と 0 〜 3 のかけ算表を画面に表示 */

	printf ( " * |" );
	for ( j = 0; j < 4; j++ ) {
		printf ( "%2d", j );
	}
	printf ( "\n" );
	printf ( "---+---------\n" );

	for ( i = 0; i < 3; i++ )	{
		printf ( " %1d |", i );
		for ( j = 0; j < 4; j++ ) {
			printf ( "%2d", a[i][j] );
		}
		printf ( "\n" );
	}

	return 0;
}
sample-001.c の実行結果
$ ./sample-001.exe
2 * 1 = 2
1 * 2 = 2 * 1 が成立
 * | 0 1 2 3
---+---------
 0 | 0 0 0 0
 1 | 0 1 2 3
 2 | 0 2 4 6
$ 

Download : sample-002.c

sample-002.c
/*
 * 2018/12/14 sample-002.c
 */

/*
 * 集合の操作は操作の集合
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-002.c
 *		リンク 
 *			cc -o sample-002.exe sample-002.c 
 *		実行
 *			./sample-002.exe
 */

#include <stdio.h>

/*
 *	main
 *
 */

#define	ARRAY_SIZE	5		/* 配列のサイズを 5 とする */

int main( int argc, char *argv[] )
{
	int a[ARRAY_SIZE];	/* ARRAY_SIZE の配列の宣言 */
	int i;

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		a[i] = 2 * i;		/* 一桁の偶数の表を作る */
							/* a = { 0, 2, 4, 6, 8 } */ 
	}

	/* 偶数を出力 */
	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		printf ( "%d ", a[i] );
	}
	printf ( "\n" );

	/* 全ての要素に 1 を加えれば奇数の表になる */
	/* { 0, 2, 4, 6, 8 } -> { 1, 3, 5, 7, 9 } */

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		a[i] = a[i] + 1;
	}

	/* 奇数を出力 */
	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		printf ( "%d ", a[i] );
	}
	printf ( "\n" );

	return 0;
}
sample-002.c の実行結果
$ ./sample-002.exe
0 2 4 6 8 
1 3 5 7 9 
$ 

Download : sample-003.c

sample-003.c
/*
 * 2018/12/14 sample-003.c
 */

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

#include <stdio.h>

/*
 *	main
 *
 */

#define	CSIZE	10
#define	EOS		'\0'			/* End Of String */

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

	cary[0] = 'a';
	cary[1] = 'b';
	cary[2] = 'c';
	cary[3] = EOS;
		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'c'|EOS| ? | ? | ? | ? | ? | ? |
		*/

	printf ( "普通に文字列 \"abc\" を出力してみる : %s\n", "abc" );
		/* 文字列を出力する場合の書式は「%s」を利用する */

	printf ( "文字列の代りに文字配列を出力してみる : %s\n", cary );
		/* 文字列の代りに文字配列名が使える */

	return 0;
}
sample-003.c の実行結果
$ ./sample-003.exe
普通に文字列 "abc" を出力してみる : abc
文字列の代りに文字配列を出力してみる : abc
$ 

Download : sample-004.c

sample-004.c
/*
 * 2018/12/14 sample-004.c
 */

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

#include <stdio.h>

/*
 *	main
 *
 */

#define	CSIZE	10
#define	EOS		'\0'

int main( int argc, char *argv[] )
{
	char cary[CSIZE] = { 'a', 'b', 'c', 'd', 'e', EOS };
		/* 配列も「初期化」可能 (全ての要素を指定する必要はない) */
		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? |
		*/
	int i;
	int l;

	/*
	 *	文字列と文字配列
	 */

	printf ( "最初の cary = %s\n", cary );

	/*
	 *	文字の変更
	 */

	cary[2] = 'A';	/* 文字列の途中の文字を差し替える */
		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'A'|'d'|'e'|EOS| ? | ? | ? | ? |
		*/

	printf ( "文字列の途中の文字を変更すると cary = %s\n", cary );

	/*
	 *	文字の尻尾を切断
	 */

	cary[3] = EOS;	/* 文字列の後ろを切断 */
		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'A'|EOS|'e'|EOS| ? | ? | ? | ? |
		*/
	printf ( "文字列を途中で切ると cary = %s\n", cary );

	/*
	 *	文字を尻尾に追加
	 */

	cary[3] = 'X';
	cary[5] = 'Y';
	cary[6] = 'Z';
	cary[7] = EOS;		/* 文字列の最後に EOS を忘れずに !! */

		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'A'|'X'|'e'|'Y'|'Z'|EOS| ? | ? |
		*/

	printf ( "文字列の後ろに文字を追加すると cary = %s\n", cary );

	/*
	 *	文字配列の出力
	 */

	 printf ( "printf を使わず、文字配列を文字列のように出力すると : " );
	 for ( i = 0; cary[i] != EOS; i++ ) {
	 	putchar ( cary[i] );
	 }
	 printf ( "と、なります。\n" );

	 /* 文字列の長さを求める */

	 for ( l = 0; cary[l] != EOS; l++ ) {
		/* やる事は何もない (l を増やす事が目的) */
	 }

	/* cary の中の文字列の長さは、変数 l に入る */

	 printf ( "文字列 %d の長さは %d です。\n", cary, l );

	/*
	 *	途中の文字を削除
	 */

	for ( i = 3; cary[i] != EOS; i++ ) {
		cary[i] = cary[i+1];
	}

		/* 文字列の途中(4 文字目)の文字('X')を削除 */

		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'A'|'X'|'e'|'Y'|'Z'|EOS| ? | ? |
				  |   |   |     /   /   /   /
			    |'a'|'b'|'A'|'e'|'Y'|'Z'|EOS|EOS| ? | ? |
		*/

	printf ( "文字列の途中の文字を削除すると cary = %s\n", cary );

	return 0;
}
sample-004.c の実行結果
$ ./sample-004.exe
最初の cary = abcde
文字列の途中の文字を変更すると cary = abAde
文字列を途中で切ると cary = abA
文字列の後ろに文字を追加すると cary = abAXeYZ
printf を使わず、文字配列を文字列のように出力すると : abAXeYZと、なります。
文字列 -1474756688 の長さは 7 です。
文字列の途中の文字を削除すると cary = abAeYZ
$ 

Download : sample-005.c

sample-005.c
/*
 * 2018/12/14 sample-005.c
 */

/*
 * 配列の要素の参照
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-005.c
 *		リンク 
 *			cc -o sample-005.exe sample-005.c 
 *		実行
 *			./sample-005.exe
 */

#include <stdio.h>

/*
 *	main
 *
 */

#define	ARRAY_SIZE	10

int main( int argc, char *argv[] )
{
	int iary[ARRAY_SIZE];
	int i;

	/* 配列の初期化 */
	/* iary[i] = i*i */

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		iary[i] = i*i;
	}

	/*
		これで、iary は i=0〜9 なら、関数 f(x)=x^2 と同じ振舞いをする
	*/

	/*
		配列参照 : 普通の「添字参照」の場合
	*/

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		printf ( "iary[%d]=%d\n", i, iary[i] );
	}

	/*
		配列参照 : 「間接参照("*" の利用)」の場合
			*(iary + i) == iary[i]
	*/

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		printf ( "*(iary + %d)=%d\n", i, *(iary + i) );
	}

	/*
		配列参照 : 配列名を使った計算 ( 添字を 1 からスタート )
			(iary-1)[i] = *((iary - 1) + i) == *(iary + (i-1)) = iary[i-1]
	*/

	for ( i = 1; i <= ARRAY_SIZE; i++ ) {
		printf ( "(iary-1)[i]=%d, iary[i-1]=%d\n", i, (iary-1)[i], i, iary[i-1] );
	}

	return 0;
}
sample-005.c の実行結果
$ ./sample-005.exe
iary[0]=0
iary[1]=1
iary[2]=4
iary[3]=9
iary[4]=16
iary[5]=25
iary[6]=36
iary[7]=49
iary[8]=64
iary[9]=81
*(iary + 0)=0
*(iary + 1)=1
*(iary + 2)=4
*(iary + 3)=9
*(iary + 4)=16
*(iary + 5)=25
*(iary + 6)=36
*(iary + 7)=49
*(iary + 8)=64
*(iary + 9)=81
(iary-1)[i]=1, iary[i-1]=0
(iary-1)[i]=2, iary[i-1]=1
(iary-1)[i]=3, iary[i-1]=4
(iary-1)[i]=4, iary[i-1]=9
(iary-1)[i]=5, iary[i-1]=16
(iary-1)[i]=6, iary[i-1]=25
(iary-1)[i]=7, iary[i-1]=36
(iary-1)[i]=8, iary[i-1]=49
(iary-1)[i]=9, iary[i-1]=64
(iary-1)[i]=10, iary[i-1]=81
$ 

Download : sample-006.c

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

/*
 * 配列名の関数への引渡し
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-006.c
 *		リンク 
 *			cc -o sample-006.exe sample-006.c 
 *		実行
 *			./sample-006.exe
 */

#include <stdio.h>

/*
 * 配列サイズ
 */

#define	ARRAY_SIZE	10

/*
 * 引数に配列を持つ関数
 */

void print_array ( int a[ARRAY_SIZE] ) {
	int i;

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		printf ( "a[%d]=%d, %d*%d = %d\n", i, a[i], i, i, i*i );
	}
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int iary[ARRAY_SIZE];
	int i;

	/* 配列の初期化 */
	/* iary[i] = i*i */

	for ( i = 0; i < ARRAY_SIZE; i++ ) {
		iary[i] = i*i;
	}

	/*
		これで、iary は i=0〜9 なら、関数 f(x)=x^2 と同じ振舞いをする
	*/

	print_array ( iary );	/* 関数の引数に「配列名」を指定できる */

	return 0;
}
sample-006.c の実行結果
$ ./sample-006.exe
a[0]=0, 0*0 = 0
a[1]=1, 1*1 = 1
a[2]=4, 2*2 = 4
a[3]=9, 3*3 = 9
a[4]=16, 4*4 = 16
a[5]=25, 5*5 = 25
a[6]=36, 6*6 = 36
a[7]=49, 7*7 = 49
a[8]=64, 8*8 = 64
a[9]=81, 9*9 = 81
$ 

Download : sample-007.c

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

/*
 * 配列名の関数への引渡し(2)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-007.c
 *		リンク 
 *			cc -o sample-007.exe sample-007.c 
 *		実行
 *			./sample-007.exe
 */

#include <stdio.h>

/*
 * 配列サイズ
 */

#define	I_ARRAY_SIZE	10
#define	J_ARRAY_SIZE	5

/*
 * 配列のサイズは、省略可能
 *		サイズの異る配列に対しても同じ関数が利用できる !!
 */

void print_n_array ( int a[], int size ) {
	int i;

	for ( i = 0; i < size; i++ ) {
		printf ( "a[%d]=%d\n", i, a[i] );
	}
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int iary[I_ARRAY_SIZE];
	int jary[J_ARRAY_SIZE];
	int i;

	/* 配列の初期化 */
	/* iary[i] = i*i */

	for ( i = 0; i < I_ARRAY_SIZE; i++ ) {
		iary[i] = i*i;
	}

	/* jary[i] = i*i*i */

	for ( i = 0; i < J_ARRAY_SIZE; i++ ) {
		jary[i] = i*i*i;
	}

	printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 );
	print_n_array ( iary, I_ARRAY_SIZE );	/* iary の内容を出力 */

	printf ( "jary: 0 〜 %d\n", J_ARRAY_SIZE - 1 );
	print_n_array ( jary, J_ARRAY_SIZE );	/* jary の内容を出力 */

	/* 配列の一部の表示も可能 */
	printf ( "iary: 0 〜 %d\n", J_ARRAY_SIZE - 1 );
	print_n_array ( iary, J_ARRAY_SIZE );

	/* 配列の途中からの表示も可能 */
	printf ( "iary: %d 〜 %d\n", J_ARRAY_SIZE, I_ARRAY_SIZE - 1 );
	print_n_array ( iary + J_ARRAY_SIZE, I_ARRAY_SIZE - J_ARRAY_SIZE );

	return 0;
}
sample-007.c の実行結果
$ ./sample-007.exe
iary: 0 〜 9
a[0]=0
a[1]=1
a[2]=4
a[3]=9
a[4]=16
a[5]=25
a[6]=36
a[7]=49
a[8]=64
a[9]=81
jary: 0 〜 4
a[0]=0
a[1]=1
a[2]=8
a[3]=27
a[4]=64
iary: 0 〜 4
a[0]=0
a[1]=1
a[2]=4
a[3]=9
a[4]=16
iary: 5 〜 9
a[0]=25
a[1]=36
a[2]=49
a[3]=64
a[4]=81
$ 

Download : sample-008.c

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

/*
 * 配列名の関数への引渡し(3)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-008.c
 *		リンク 
 *			cc -o sample-008.exe sample-008.c 
 *		実行
 *			./sample-008.exe
 */

#include <stdio.h>

/*
 * 配列サイズ
 */

#define	I_ARRAY_SIZE	10

/*
 * 1 次元配列 (a[]) の仮引数変数宣言は、「*a」形の宣言でも良い
 */

void print_n_array ( int *a, int size ) {
	int i;

	for ( i = 0; i < size; i++ ) {
		printf ( "a[%d]=%d\n", i, a[i] );
	}
}

/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int iary[I_ARRAY_SIZE];
	int i;

	/* 配列の初期化 */
	/* iary[i] = i*i */

	for ( i = 0; i < I_ARRAY_SIZE; i++ ) {
		iary[i] = i*i;
	}

	printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 );
	print_n_array ( iary, I_ARRAY_SIZE );	/* iary の内容を出力 */

	return 0;
}
sample-008.c の実行結果
$ ./sample-008.exe
iary: 0 〜 9
a[0]=0
a[1]=1
a[2]=4
a[3]=9
a[4]=16
a[5]=25
a[6]=36
a[7]=49
a[8]=64
a[9]=81
$ 

Download : sample-009.c

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

/*
 * 配列名の関数への引渡し(4)
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-009.c
 *		リンク 
 *			cc -o sample-009.exe sample-009.c 
 *		実行
 *			./sample-009.exe
 */

#include <stdio.h>

/*
 * 配列サイズ
 */

#define	I_ARRAY_SIZE	10

/*
 * 1 次元配列 (a[]) の仮引数変数宣言は、「*a」形の宣言でも良い
 */

void print_n_array ( int *a, int size ) {
	int i;

	for ( i = 0; i < size; i++ ) {
		printf ( "a[%d]=%d\n", i, a[i] );
	}
}

/*
 * 配列引数の要素の値を書き換える
 */

void change_at ( int *a, int pos, int value ) {

	 a[pos] = value;
}


/*
 *	main
 *
 */

int main( int argc, char *argv[] )
{
	int iary[I_ARRAY_SIZE];
	int i;

	/* 配列の初期化 */
	/* iary[i] = i*i */

	for ( i = 0; i < I_ARRAY_SIZE; i++ ) {
		iary[i] = i*i;
	}

	printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 );
	print_n_array ( iary, I_ARRAY_SIZE );	/* iary の内容を出力 */

	printf ( "%d 番目の要素を %d に書き換える\n", 5, 100 );

	change_at ( iary, 5, 100 );

	printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 );
	print_n_array ( iary, I_ARRAY_SIZE );	/* iary の内容を出力 */

	return 0;
}
sample-009.c の実行結果
$ ./sample-009.exe
iary: 0 〜 9
a[0]=0
a[1]=1
a[2]=4
a[3]=9
a[4]=16
a[5]=25
a[6]=36
a[7]=49
a[8]=64
a[9]=81
5 番目の要素を 100 に書き換える
iary: 0 〜 9
a[0]=0
a[1]=1
a[2]=4
a[3]=9
a[4]=16
a[5]=100
a[6]=36
a[7]=49
a[8]=64
a[9]=81
$ 

Download : sample-011.c

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

/*
 * 文字列の入力\n *\tscanf の「%s」で文字列を入力する事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-011.c
 *		リンク 
 *			cc -o sample-011.exe sample-011.c 
 *		実行
 *			./sample-011.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

#define	LINE_SIZE	128		/* 入力する文字列より大きなサイズにする */

int main ( int argc, char *argv[] ) {
	char line[LINE_SIZE];	/* 入力する文字列を収める文字型配列 */

	printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " );

	scanf ( "%s", line );	/* 書式は「%s」で、文字型配列名を直接使う(&)は不要 */

	printf ( "あなたが入力した文字列は「%s」です。\n", line );
		/* 空白文字(空白/タブ/改行)があると、「文字列の区切」とみなされる */

	return 0;
}
入力例
空白(' ')を含んだ、適当な長さの文字列
sample-011.c の実行結果
$ ./sample-011.exe < sample-011.in
キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白('
あなたが入力した文字列は「空白('」です。
$ 

Download : sample-012.c

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

/*
 * 文字列の入力 (2)
 *	gets で文字列を入力する事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-012.c
 *		リンク 
 *			cc -o sample-012.exe sample-012.c 
 *		実行
 *			./sample-012.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

#define	LINE_SIZE	128		/* 入力する文字列より大きなサイズにする */

int main ( int argc, char *argv[] ) {
	char line[LINE_SIZE];	/* 入力する文字列を収める文字型配列 */

	printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " );

	gets ( line );
		/* gets では、「一行(改行の直前迄:改行含まず)」の文字列が入力される */

	printf ( "あなたが入力した文字列は「%s」です。\n", line );
		/* gets は一行(改行)までを入力する */

	return 0;
}
入力例
空白(' ')を含んだ、適当な長さの文字列
sample-012.c の実行結果
$ ./sample-012.exe < sample-012.in
キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白(' ')を含んだ、適当な長さの文字列
あなたが入力した文字列は「空白(' ')を含んだ、適当な長さの文字列」です。
$ 

Download : sample-013.c

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

/*
 * 文字列の入力 (3)\n *\tfgets で文字列を入力する事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-013.c
 *		リンク 
 *			cc -o sample-013.exe sample-013.c 
 *		実行
 *			./sample-013.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

#define	LINE_SIZE	128		/* 入力する文字列より大きなサイズにする */

int main ( int argc, char *argv[] ) {
	char line[LINE_SIZE];	/* 入力する文字列を収める文字型配列 */

	printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " );

	fgets ( line, LINE_SIZE, stdin );
		/* 入力先は、「標準入力 (stdin)」となる */
		/* fgets では、文字列サイズが指定できる (安全) */
		/* 指定したサイズより長い文字列は、入力が「待たされ」る */

	printf ( "あなたが入力した文字列は「%s」です。\n", line );
		/* 入力文字列内には、「改行」も含まれる */

	return 0;
}
入力例
空白(' ')を含んだ、適当な長さの文字列
sample-013.c の実行結果
$ ./sample-013.exe < sample-013.in
キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白(' ')を含んだ、適当な長さの文字列
あなたが入力した文字列は「空白(' ')を含んだ、適当な長さの文字列
」です。
$ 

Download : sample-021.c

sample-021.c
/*
 * 2018/12/14 sample-021.c
 */

/*
 * sizeof 演算子\n *\t型名を指定する事により、そのサイズ(byte 単位)を得る事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-021.c
 *		リンク 
 *			cc -o sample-021.exe sample-021.c 
 *		実行
 *			./sample-021.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

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

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

	return 0;
}
sample-021.c の実行結果
$ ./sample-021.exe
sizeof ( char   ) = 1
sizeof ( int    ) = 4
sizeof ( double ) = 8
$ 

Download : sample-022.c

sample-022.c
/*
 * 2018/12/14 sample-022.c
 */

/*
 * sizeof 演算子 (2)\n *\t変数名を指定する事により、そのサイズ(byte 単位)を得る事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-022.c
 *		リンク 
 *			cc -o sample-022.exe sample-022.c 
 *		実行
 *			./sample-022.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	char cvar;
	int ivar;
	double dvar;

	printf ( "sizeof ( cvar ) = %d\n", sizeof ( cvar ) );
	printf ( "sizeof ( ivar ) = %d\n", sizeof ( ivar ) );
	printf ( "sizeof ( dvar ) = %d\n", sizeof ( dvar ) );

	return 0;
}
sample-022.c の実行結果
$ ./sample-022.exe
sizeof ( cvar ) = 1
sizeof ( ivar ) = 4
sizeof ( dvar ) = 8
$ 

Download : sample-023.c

sample-023.c
/*
 * 2018/12/14 sample-023.c
 */

/*
 * sizeof 演算子 (3)\n *\t配列名を指定する事により、そのサイズ(byte 単位)を得る事ができる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-023.c
 *		リンク 
 *			cc -o sample-023.exe sample-023.c 
 *		実行
 *			./sample-023.exe
 */


#include <stdio.h>

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	char cary[100];
	int iary[100];
	double dary[100];

	printf ( "sizeof ( cary ) = %d\n", sizeof ( cary ) );
	printf ( "sizeof ( iary ) = %d\n", sizeof ( iary ) );
	printf ( "sizeof ( dary ) = %d\n", sizeof ( dary ) );

	return 0;
}
sample-023.c の実行結果
$ ./sample-023.exe
sizeof ( cary ) = 100
sizeof ( iary ) = 400
sizeof ( dary ) = 800
$ 

Download : sample-024.c

sample-024.c
/*
 * 2018/12/14 sample-024.c
 */

/*
 * sizeof 演算子 (4)\n *\t値を指定する事もできる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-024.c
 *		リンク 
 *			cc -o sample-024.exe sample-024.c 
 *		実行
 *			./sample-024.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

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

	printf ( "sizeof ( 'a'  ) = %d\n", sizeof ( 'a' ) );
			/* sizeof ( int ) [整数] になっている */
	printf ( "sizeof ( 123  ) = %d\n", sizeof ( 123 ) );
	printf ( "sizeof ( 12.3 ) = %d\n", sizeof ( 12.3 ) );

	return 0;
}
sample-024.c の実行結果
$ ./sample-024.exe
sizeof ( 'a'  ) = 4
sizeof ( 123  ) = 4
sizeof ( 12.3 ) = 8
$ 

Download : sample-025.c

sample-025.c
/*
 * 2018/12/14 sample-025.c
 */

/*
 * sizeof 演算子 (5)\n *\t式のサイズも得られる\n *\tchar 型のデータは、計算の時に、int 型に昇格する
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-025.c
 *		リンク 
 *			cc -o sample-025.exe sample-025.c 
 *		実行
 *			./sample-025.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

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

	printf ( "sizeof ( ch ) = %d\n", sizeof ( ch ) );
			/* sizeof ( char ) [文字] になっている */

	printf ( "sizeof ( ch + dh ) = %d\n", sizeof ( ch + dh ) );
			/* sizeof ( int ) [整数] になっている */
			/* 無条件の型の昇格がおきている */

	return 0;
}
sample-025.c の実行結果
$ ./sample-025.exe
sizeof ( ch ) = 1
sizeof ( ch + dh ) = 4
$ 

Download : sample-026.c

sample-026.c
/*
 * 2018/12/14 sample-026.c
 */

/*
 * 型の昇格\n *\tint 型から double 型への変換
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-026.c
 *		リンク 
 *			cc -o sample-026.exe sample-026.c 
 *		実行
 *			./sample-026.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

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

	printf ( "sizeof ( num )       = %d\n", sizeof ( num ) );
	printf ( "sizeof ( num + 'A' ) = %d\n", sizeof ( num + 'A' ) );
	printf ( "sizeof ( num + mum ) = %d\n", sizeof ( num + mum ) );
	printf ( "sizeof ( num + 1.0 ) = %d\n", sizeof ( num + 1.0 ) );

	return 0;
}
sample-026.c の実行結果
$ ./sample-026.exe
sizeof ( num )       = 4
sizeof ( num + 'A' ) = 4
sizeof ( num + mum ) = 4
sizeof ( num + 1.0 ) = 8
$ 

Download : sample-027.c

sample-027.c
/*
 * 2018/12/14 sample-027.c
 */

/*
 * 型の変換\n *\t代入では、必要に応じて型変換が行わる
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-027.c
 *		リンク 
 *			cc -o sample-027.exe sample-027.c 
 *		実行
 *			./sample-027.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	char ch = 'A';		/* そもそも 'A' は int 型 */
	int num = 'A';
	double fp = 'A';	/* int 型から double 型へ */

	ch = ch - 'A' + 'a';	/* int 型から char 型へ */
	ch = num;				/* int 型から char 型へ */
	num = fp;				/* double 型から int 型へ */

	printf ( "ch  = %c\n", ch );
	printf ( "num = %d\n", num );
	printf ( "fp  = %f\n", fp );

	return 0;
}
sample-027.c の実行結果
$ ./sample-027.exe
ch  = A
num = 65
fp  = 65.000000
$ 

Download : sample-028.c

sample-028.c
/*
 * 2018/12/14 sample-028.c
 */

/*
 * 型の変換 (2)\n *\tサイズの大きい方から、小さい方への変換は危険
 *
 * 利用方法
 *		コンパイル 
 *			cc  -c sample-028.c
 *		リンク 
 *			cc -o sample-028.exe sample-028.c 
 *		実行
 *			./sample-028.exe
 */

#include <stdio.h>

/*
 * main 関数
 */

int main ( int argc, char *argv[] ) {
	char ch = 'A';
	int num = 'A';
	double fp = 'A';

	/* 個々に適切な値を入れれば問題はない */

	printf ( "[適切な値]\n" );
	printf ( "\tch  = '%c' [%d]\n", ch, ch );
	printf ( "\tnum = %d\n", num );
	printf ( "\tfp  = %f\n", fp );

	/* char 型に収まらないサイズの値を代入すると ?? */

	num = 1000;		/* 1000 > 255 なので、1000 は char 型に収まらない */
	ch = num;		/* 代入を行うとどうなるか */

	printf ( "[char に大きな値]\n" );
	printf ( "\tch  = '%c' [%d]\n", ch, ch );
	printf ( "\tnum = %d\n", num );

	/* int 型に収まらないサイズの値を代入すると ?? */

	fp = 1000000000000;
	num = fp;
	ch = fp;

	printf ( "[int に大きな値]\n" );
	printf ( "\tch  = '%c' [%d]\n", ch, ch );
	printf ( "\tnum = %d\n", num );
	printf ( "\tfp  = %f\n", fp );

	return 0;
}
sample-028.c の実行結果
$ ./sample-028.exe
[適切な値]
	ch  = 'A' [65]
	num = 65
	fp  = 65.000000
[char に大きな値]
	ch  = '?' [-24]
	num = 1000
[int に大きな値]
	ch  = '' [0]
	num = -2147483648
	fp  = 1000000000000.000000
$ 

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

本日の課題

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

課題 20181214-01 : 配列内の浮動小数点数の合計を求める

Download : 20181214-01.c

20181214-01.c
/*
 * 課題 20181214-01
 *
 * 20181214 20181214-01-QQQQ.c
 *
 *	浮動小数点数の配列の要素内の数値の総和を求める。
 */

#include <stdio.h>

/*
 *  浮動小数点数の配列の要素内の数値の総和を求める。
 *
 * 利用方法
 *		コンパイル
 *			cc -o BASENAME.exe 20181214-01-QQQQ.c
 *		実行
 *			./BASENAME.exe
 */

#include <stdio.h>

/*
 * double dsum ( double ary[], int size )
 *		浮動小数点数の配列の要素内の数値の総和を求める関数
 *	double ary[]; 総和を求める要素を含む配列
 *	int size; 配列のサイズ
 */

double dsum ( double ary[], int size ) {
	double sum = 0.0;	/* 総和は最初は 0 */
	int i;				/* 配列の要素を参照する添字変数 */

	for ( i = 0; i < size; i++ ) {	/* i = 0 〜 sum - 1 の間.. */

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

								/* 「sum += ary[i]」とも書きける */
	}

	return sum;					/* 結果を返す */

}

/*
 *	main
 */

#define	ARY_SIZE	5

int main( int argc, char *argv[] )
{
	double data[ARY_SIZE];	/* 大きさ ARY_SIZE の配列の宣言 */
	int i;					/* 配列の要素を参照する添字変数 */
	double sum;				/* 総和の計算結果を保持する */

	printf ( "%d 個のデータを入力します。\n", ARY_SIZE );
	for ( i = 0; i < ARY_SIZE; i++ ) {
		printf ( "%d 番目の数値を入力してください : ", i + 1 );

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

	}

	sum = dsum ( data, ARY_SIZE );

	printf ( "入力されたデータの総和は %f です。\n", sum );

	return 0;
}
入力例
2.3
9.1
5.9
2.7
3.2
20181214-01.c の実行結果
$ ./20181214-01-QQQQ.exe
5 個のデータを入力します。
1 番目の数値を入力してください : 2.300000
2 番目の数値を入力してください : 9.100000
3 番目の数値を入力してください : 5.900000
4 番目の数値を入力してください : 2.700000
5 番目の数値を入力してください : 3.200000
入力されたデータの総和は 23.200000 です。
$ 

課題 20181214-02 : 文字配列に入った文字列の途中に文字を挿入する

Download : 20181214-02.c

20181214-02.c
/*
 * 課題 20181214-02
 *
 * 20181214 20181214-02-QQQQ.c
 *
 * 文字列の途中に文字を挿入する
 *
 * 利用方法
 *		コンパイル
 *			cc -o BASENAME.exe 20181214-02-QQQQ.c
 *		実行
 *			./BASENAME.exe
 */

#include <stdio.h>

/*
 *
 */

/*
 *	main
 *
 */

#define	CSIZE	10
#define	EOS		'\0'

int main( int argc, char *argv[] )
{
	char cary[CSIZE] = { 'a', 'b', 'c', 'd', 'e', EOS };
		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? |
		*/
	int i;
	int l;

	printf ( "最初の cary = %s\n", cary );

	/*
		文字列 "abcde" の入った文字配列 cary の
		3 文字目 ('c') と 4 文字目 'd' の間に、一文字 'X' を入れる
	*/

	 /* 文字列の長さを求める */


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


	/* cary の中の文字列の長さは、変数 l に入る */

	 for ( i = l; 3 <= i; i-- )	{		/* 後ろからコピーする必要がある */

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

	 }
	 cary[3] = 'X';						/* 空けた場所に 'X' を入れる */

		/*
		 		| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
			cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? |
			      |   |   |     \   \   \
			cary|'a'|'b'|'c'|'X'|'d'|'e'|EOS| ? | ? | ? | ? |
		*/

	printf ( "'X' を挿入した結果 : %s\n", cary );

	return 0;
}
入力例
123
987
456
20181214-02.c の実行結果
$ ./20181214-02-QQQQ.exe
最初の cary = abcde
'X' を挿入した結果 : abcXde
$ 

課題 20181214-03 : 一行文の文字列を入力して、その中の文字列を全て大文字に変換する

Download : 20181214-03.c

20181214-03.c
/*
 * 20181214-03-QQQQ.c
 *	一行文の文字列を入力して、その中の文字列を全て大文字に変換する
 */

#include <stdio.h>

/*
 *  islower (ch) : 指定された文字が、小文字かどうかを判定する
 */

int islower ( int ch ) {

	return 'a' <= ch && ch <= 'z';	/* 'a' 〜 'z' なら小文字 */
}

/*
 * toupper ( ch ) : 指定された文字が、小文字なら大文字に変換
 */

int toupper ( int ch ) {

	if ( islower ( ch ) ) {		/* 小文字だった.. */

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

	} else {					/* そうでないなら */
		return ch;				/* そのまま返す */
	}
}

/*
 * main
 */

#define	EOS			'\0'	/* EOS を定義 */
#define	LINE_SIZE	128		/* 入力するのに十分に大きなサイズにする */

int main ( void ) {
	char line[LINE_SIZE];
	int i;

	printf ( "小文字を含んだ文字列を入力してください : " );


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


	for ( i = 0; line[i] != EOS; i++ ) {
		line[i] = toupper ( line[i] );	/* 小文字を大文字に変換 */
	}

	printf ( "結果 : %s", line );

	return 0;
}
入力例
aBcd123[]
20181214-03.c の実行結果
$ ./20181214-03-QQQQ.exe
小文字を含んだ文字列を入力してください : aBcd123[]
結果 : ABCD123[]
$