Powered by SmartDoc

ソフトウェア概論A (2012/06/15)
Ver. 1.0

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

目次

講義資料

当日の OHP 資料

当日のOHP資料です。

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

sample-001

Download : sample-001.c ( SJIS 版 )

sample-001.c
/*
 * 2012/06/15 sample-001.c
 */

/*
 * 関数の値と return 命令
 */

#include <stdio.h>

/*
 * char *myname ( void )
 *	引数
 *		void : なし
 *	返値
 *		char * : 自分の名前を返す
 */

char *myname ( void ) {
	/* 「関数の型」として「char *」が指定されている */

	return "栗野俊一";	/* 自分の名前を関数の値として返す */
}

/*
 *
 */

int main ( void ) {

	printf ( "私の名前は「" );
	printf ( myname() );	/* 関数を呼び出し、その値を printf で利用する */
	printf ( "」です。\n" );

	return 0;
}

/*
 *
 */
sample-001.c の実行結果
C:\usr\c>sample-001
私の名前は「栗野俊一」です。
C:\usr\c> 

sample-002

Download : sample-002.c ( SJIS 版 )

sample-002.c
/*
 * 2012/06/15 sample-002.c
 */

/*
 * 関数の値と return 命令 (2)
 */

#include <stdio.h>

/*
 * char *remove_top ( char *string )
 *
 *	機能
 *		引数で指定された文字列の最初の文字列を取り除いた文字列を求める
 *		引数として指定される文字列は空文字列でない事を仮定している
 *	引数
 *		char * string : 空でない文字列
 *	返値
 *		char * : 与えられた文字列の最初の文字を取り除いた文字列
 *
 */

char *remove_top ( char *string ) {

	return string + 1;	/* return 命令の後ろには「計算式」がかける */
						/* 文字列に 1 を加えると、先頭の文字がなくなる */
						/* ここでは空文字が指定される事は想定しない */
						/* 計算した結果を return 命令で「返す」 */
}

/*
 *
 */

int main ( void ) {

	printf ( "文字列 \"abc\" の先頭の一文字を取り除いた文字列は「" );

		/* remove_top が返す値を printf で出力する */
	printf ( remove_top ( "abc" ) );

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

	return 0;
}

/*
 *
 */
sample-002.c の実行結果
C:\usr\c>sample-002
文字列 "abc" の先頭の一文字を取り除いた文字列は「bc」になります。
C:\usr\c> 

sample-003

Download : sample-003.c ( SJIS 版 )

sample-003.c
/*
 * 2012/06/15 sample-003.c
 */

/*
 * 関数の値と return 命令 (3)
 */

#include <stdio.h>

/*
 * char get_top_char ( char *string )
 *
 *	機能
 *		引数で指定された文字列の最初の文字を求める
 *		引数として指定される文字列は空文字列でない事を仮定している
 *	引数
 *		char * string : 空でない文字列
 *	返値
 *		char : 与えられた文字列の最初の文字を返す
 */

char get_top_char ( char *string ) {
	/*
		今回返すのは「文字」なので、返り値の型は「char」となる
	*/

	return *string;		/* 文字列表現の頭に '*' を付ければ先頭の「文字」になる */
}

/*
 *
 */

int main ( void ) {

	printf ( "文字列 \"abc\" の先頭の一文字は「" );

		/* get_top_char が返す値を putchar で出力する */
	putchar ( get_top_char ( "abc" ) );
		/* 返り値が「char 型」(文字型)なので、出力には putchar を使う */

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

	return 0;
}

/*
 *
 */
sample-003.c の実行結果
C:\usr\c>sample-003
文字列 "abc" の先頭の一文字は「a」になります。
C:\usr\c> 

sample-004

Download : sample-004.c ( SJIS 版 )

sample-004.c
/*
 * 2012/06/15 sample-004.c
 */

/*
 * 条件分岐
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void echo_twice_message ( char *message )
 *
 *	機能
 *		引数で指定された文字列をそのまま、二度出力する
 *		引数が空文字列の時には、「空文字列です」を一回だけ出力する
 *	引数
 *		char * message : 文字列
 *	返値
 *		void : なし
 */

void	echo_twice_message ( char *message ) {

	if ( *message == EOS ) {		/* 空文字列だった */
		printf ( "空文字列です" );	/* 「空文字列です」を出力 */
	} else {						/* そうでなかった */
		printf ( message );			/* 与えられた文字列をそのまま二度出力 */
		printf ( message );
	}
}

/*
 *
 */

void check_echo_twice_message ( char *message ) {

	printf ( "文字列 \"" );
	printf ( message );
	printf ( "\" を二度繰り返すと「" );

	echo_twice_message ( message );

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

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_echo_twice_message ( "abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_echo_twice_message ( "" );

	return 0;
}

/*
 *
 */
sample-004.c の実行結果
C:\usr\c>sample-004
"abc" の場合 : 文字列 "abc" を二度繰り返すと「abcabc」になります。
"" (空文字列) の場合 : 文字列 "" を二度繰り返すと「空文字列です」になります。
C:\usr\c> 

sample-005

Download : sample-005.c ( SJIS 版 )

sample-005.c
/*
 * 2012/06/15 sample-005.c
 */

/*
 * 条件分岐 ( else if )
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void echo_once_or_twice_message ( char *message )
 *
 *	機能
 *		引数が空文字列の時には、「空文字列です」を一回だけ出力する
 *		引数で指定された文字列の先頭が '*' の時は、その後の文字列を二度出力
 *		そうでなければ、一度だけ出力
 *	引数
 *		char * message : 出力する文字列
 *	返値
 *		void : なし
 */

void	echo_once_or_twice_message ( char *message ) {

	if ( *message == EOS ) {		/* 空文字列だった */
		printf ( "空文字列です" );	/* 「空文字列です」を出力 */
	} else if ( *message == '*' ) {	/* 先頭が '*' で始まる */
		printf ( message + 1 );		/* '*' を取り除いた残りを二度出力 */
		printf ( message + 1 );
	} else {						/* そうでなかった */
		printf ( message );			/* 文字列をそのまま一度だけ出力 */
	}
}

/*
 *
 */

void check_echo_once_or_twice_message ( char *message ) {

	printf ( "文字列 \"" );
	printf ( message );
	printf ( "\" を出力させると「" );

	echo_once_or_twice_message ( message );

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

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_echo_once_or_twice_message ( "abc" );

	printf ( "\"*abc\" 先頭に '*' を付けた場合 : " );
	check_echo_once_or_twice_message ( "*abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_echo_once_or_twice_message ( "" );

	return 0;
}

/*
 *
 */
sample-005.c の実行結果
C:\usr\c>sample-005
"abc" の場合 : 文字列 "abc" を出力させると「abc」になります。
"*abc" 先頭に '*' を付けた場合 : 文字列 "*abc" を出力させると「abcabc」になります。
"" (空文字列) の場合 : 文字列 "" を出力させると「空文字列です」になります。
C:\usr\c> 

sample-006

Download : sample-006.c ( SJIS 版 )

sample-006.c
/*
 * 2012/06/15 sample-004.c
 */

/*
 * 条件分岐
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * char *remove_top2 ( char *string ) : 改良版(空文字列に対応)
 *
 *	機能
 *		引数で指定された文字列の最初の文字列を取り除いた文字列を求める
 *		引数が空文字列の時には、空文字列を返す
 *	引数
 *		char * string : 文字列
 *	返値
 *		char * : 与えられた文字列の最初の文字を取り除いた文字列
 *				 但し、空文字列が指定された場合は空文字列を返す
 */

char *remove_top2 ( char *string ) {

	if ( *string == EOS ) {	/* 空文字列だった */
		return string;		/* その文字列(空文字列)をそのまま返す */
	} else {				/* そうでなかった */
		return string + 1;	/* 安心して 1 が足せる */
	}
}

/*
 *
 */

void check_remove_top2 ( char *string ) {

	printf ( "文字列 \"" );
	printf ( string );
	printf ( "\" の先頭の一文字を取り除いた文字列は「" );

		/* remove_top が返す値を printf で出力する */
	printf ( remove_top2 ( string ) );

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

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_remove_top2 ( "abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_remove_top2 ( "" );

	return 0;
}

/*
 *
 */
sample-006.c の実行結果
C:\usr\c>sample-006
"abc" の場合 : 文字列 "abc" の先頭の一文字を取り除いた文字列は「bc」になります。
"" (空文字列) の場合 : 文字列 "" の先頭の一文字を取り除いた文字列は「」になります。
C:\usr\c> 

sample-007

Download : sample-007.c ( SJIS 版 )

sample-007.c
/*
 * 2012/06/15 sample-007.c
 */

/*
 * 再帰
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void print_reverse_string ( char *string )
 *
 *	機能
 *		引数で指定された文字列を逆順に出力
 *	引数
 *		char * string : 文字列
 *	返値
 *		void : なし
 */

void print_reverse_string ( char *string ) {

	if ( *string == EOS ) {		/* 空文字列 ( "" ) の場合 */
								/* なにもする事はない */
	} else {					/* そうでなければ.. */

			/* まず、残りの文字列の「逆順出力をする」*/
		print_reverse_string ( string + 1 );	/* 再帰 */

			/* そして、(最後に?) 先頭の文字を出力すればよい */
		putchar ( *string );	/* 先頭の文字の出力 */	

	}
}

/*
 *
 */

void check_print_reverse_string ( char *string ) {

	printf ( "文字列 \"" );
	printf ( string );
	printf ( "\" の逆順の出力は「" );
	print_reverse_string ( string );
	printf ( "」になります。\n" );

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_print_reverse_string ( "abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_print_reverse_string ( "" );

	return 0;
}

/*
 *
 */
sample-007.c の実行結果
C:\usr\c>sample-007
"abc" の場合 : 文字列 "abc" の逆順の出力は「cba」になります。
"" (空文字列) の場合 : 文字列 "" の逆順の出力は「」になります。
C:\usr\c> 

sample-008

Download : sample-008.c ( SJIS 版 )

sample-008.c
/*
 * 2012/06/15 sample-008.c
 */

/*
 * 再帰
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void print_nth_string ( char *length, char *string )
 *
 *	機能
 *		一つ目引数で指定された文字列の長さだけ、二つ目の文字列を繰り返す
 *	引数
 *		char * string : 文字列
 *	返値
 *		void : なし
 */

void print_nth_string ( char *length, char *string ) {

	if ( *length == EOS ) {		/* 空文字列 ( "" ) の場合 */
								/* なにもする事はない */
	} else {					/* そうでなければ.. */
		printf ( string );		/* 文字列を出力する */
		print_nth_string ( length + 1, string );	/* length の文字列を短く */
	}
}

/*
 *
 */

void check_print_nth_string ( char *length, char *string ) {

	printf ( "文字列 \"" );
	printf ( string );
	printf ( "\" を\"" );
	printf ( length );
	printf ( "\"回繰り返す場合の出力は「" );
	print_nth_string ( length, string );
	printf ( "」になります。\n" );

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の \"12345\" 回数の場合 : " );
	check_print_nth_string ( "12345", "abc" );

	printf ( "\"abc\" の \"\" (空文字列) 回数の場合 : " );
	check_print_nth_string ( "", "abc" );

	return 0;
}

/*
 *
 */
sample-008.c の実行結果
C:\usr\c>sample-008
"abc" の "12345" 回数の場合 : 文字列 "abc" \
    を"12345"回繰り返す場合の出力は「abcabcabcabcabc」になります。
"abc" の "" (空文字列) 回数の場合 : 文字列 "abc" を""回繰り返す場合の出力は「」になります。
C:\usr\c> 

sample-009

Download : sample-009.c ( SJIS 版 )

sample-009.c
/*
 * 2012/06/15 sample-008.c
 */

/*
 * 再帰と return 命令
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * char get_last_char ( char *string )
 *
 *	機能
 *		引数で指定された文字列の最後の文字を求める
 *		引数として指定される文字列が空文字列なら '?' を返す
 *	引数
 *		char * string : 文字列
 *	返値
 *		char : 与えられた文字列の最後の文字を返す
 */

char get_last_char ( char *string ) {

	if ( *string == EOS ) {				/* 空文字列 ( "" ) の場合 */
		return '?';						/* '?' を返す */
	} else if ( string[1] == EOS ) {	/* 先頭の次の文字が空文字 */
		return *string;					/* 現在の先頭の文字が最後の文字 */
	} else {							/* いずれでもなければ.. */
		return get_last_char ( string + 1 );	/* 再帰 */
	}
}

/*
 *
 */

void check_get_last_char ( char *string ) {

	printf ( "文字列 \"" );
	printf ( string );
	printf ( "\" の最後の一文字は「" );
	putchar ( get_last_char ( string ) );
	printf ( "」になります。\n" );

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_get_last_char ( "abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_get_last_char ( "" );

	printf ( "\"How do you do ?\" (最後に '?' がある) 場合 : " );
	check_get_last_char ( "How do you do ?" );

	return 0;
}

/*
 *
 */
sample-009.c の実行結果
C:\usr\c>sample-009
"abc" の場合 : 文字列 "abc" の最後の一文字は「c」になります。
"" (空文字列) の場合 : 文字列 "" の最後の一文字は「?」になります。
"How do you do ?" (最後に '?' がある) 場合 : 文字列 "How do you do ?" \
    の最後の一文字は「?」になります。
C:\usr\c> 

sample-010

Download : sample-010.c ( SJIS 版 )

sample-010.c
/*
 * 2012/06/15 sample-009.c
 */

/*
 * void 関数の return
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void is_char_in_string ( char charactor, char *string )
 *
 *	機能
 *		第一引数で指定された文字が第二引数で指定された文字列に含まれかを判定
 *			含まれれば「はい」を出力し、そうでなければ「いいえ」を出力
 *	引数
 *		char charactor : 含まれているかどうかを判定する文字
 *		char *string : 含まれているかどうかを判定する文字列
 *	返値
 *		void : なし
 */

void	is_char_in_string ( char charactor, char *string ) {

	if ( *string == EOS ) {				/* 空文字列 ( "" ) の場合 */
		printf ( "いいえ" );
		return;							/* 処理はこれでおしまい */
	} else if ( *string == charactor ) {	/* 先頭文字が指定された文字 */
		printf ( "はい" );
		return;							/* 処理はこれでおしまい */
	} else {
		is_char_in_string ( charactor, string + 1 ); /* 再帰 */
	}
}

/*
 *
 */

void check_is_char_in_string ( char charactor, char *string ) {

	printf ( "「文字列 \"" );
	printf ( string );
	printf ( "\" の中に '" );
	putchar ( charactor );
	printf ( "' が入っていますか ?」の回答は「" );
	is_char_in_string ( charactor, string );
	printf ( "」になります。\n" );

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" と 'b' の場合 : " );
	check_is_char_in_string ( 'b', "abc" );

	printf ( "\"\" (空文字列) と 'b' の場合 : " );
	check_is_char_in_string ( 'b', "" );

	printf ( "\"abc\" と 'x' の場合 : " );
	check_is_char_in_string ( 'x', "abc" );

	return 0;
}

/*
 *
 */
sample-010.c の実行結果
C:\usr\c>sample-010
"abc" と 'b' の場合 : 「文字列 "abc" の中に 'b' が入っていますか ?」の回答は「はい」になります。
"" (空文字列) と 'b' の場合 : 「文字列 "" の中に 'b' が入っていますか ?」の回答は「いいえ」になります。
"abc" と 'x' の場合 : 「文字列 "abc" の中に 'x' が入っていますか ?」の回答は「いいえ」になります。
C:\usr\c> 

sample-011

Download : sample-011.c ( SJIS 版 )

sample-011.c
/*
 * 2012/06/15 sample-001.c
 */

/*
 * 整数の扱い
 */

#include <stdio.h>
#include "s_print.h"

int main ( void ) {

  s_print_int ( 1 );	/* 整数 1 を出力する */
  s_print_newline();	/* 改行 */

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

sample-012

Download : sample-012.c ( SJIS 版 )

sample-012.c
/*
 * 2012/06/15 sample-002.c
 */

/*
 * 整数と文字列の扱い
 */

#include <stdio.h>
#include "s_print.h"

int main ( void ) {

  s_print_int ( 123 );		/* 整数 123 を出力する */
  s_print_newline();		/* 改行 */

  s_print_string ( "123" );	/* 文字列 "123" を出力する */
  s_print_newline();		/* 改行 */

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

sample-013

Download : sample-013.c ( SJIS 版 )

sample-013.c
/*
 * 2012/06/15 sample-003.c
 */

/*
 * 整数と文字列と取り違えると .. ?
 */

#include <stdio.h>
#include "s_print.h"

int main ( void ) {

  s_print_int ( "123" );	/* 文字列を整数として出力しようとした */
  s_print_newline();		/* 改行 */

  s_print_string ( 123 );	/* 整数を文字列として出力しようとした */
  s_print_newline();		/* 改行 */

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

sample-014

Download : sample-014.c ( SJIS 版 )

sample-014.c
/*
 * 2012/06/15 sample-004.c
 */

/*
 * 関数に整数を渡す
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 同じ整数を二度出力する
 */

void print_int_two ( int n ) {	// 引数が整数なので、引数の宣言は int になる

  s_print_int ( n );
  s_print_newline();
  s_print_int ( n );
  s_print_newline();

}

/*
 * main
 */

int main ( void ) {

  s_print_int_two ( 123 );	/* 整数 123 を二度出力する */

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

sample-015

Download : sample-015.c ( SJIS 版 )

sample-015.c
/*
 * 2012/06/15 sample-005.c
 */

/*
 * 整数の計算
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 二つの和を出力する
 */

void print_int_wa ( int n, int m ) {

  s_print_int ( n );
  s_print_string ( " と " );
  s_print_int ( m );
  s_print_string ( " の和は " );
  s_print_int ( n + m );
  s_print_string ( " です。" );
  s_print_newline();

}

/*
 * main
 */

int main ( void ) {

  print_int_wa ( 123, 957 );
  print_int_wa ( -21, 45 );

  return 0;
}
sample-015.c の実行結果
C:\usr\c>sample-015
123 と 957 の和は 1080 です。
-21 と 45 の和は 24 です。
C:\usr\c> 

sample-016

Download : sample-016.c ( SJIS 版 )

sample-016.c
/*
 * 2012/06/15 sample-006.c
 */

/*
 * 整数の大小比較
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 二つの比較結果を出力する
 */

void print_int_compare ( int n, int m ) {

  s_print_int ( n );
  s_print_string ( " と " );
  s_print_int ( m );
  s_print_string ( " では " );

  if ( n > m ) {	/* n の方が大きければ.. */
	  s_print_int ( n );
  } else {
	  s_print_int ( m );
  }

  s_print_string ( " の方が大きい。" );
  s_print_newline();

}

/*
 * main
 */

int main ( void ) {

  print_int_compare ( 10, 20 );
  print_int_compare ( 40, 30 );
  print_int_compare ( 4, -4 );

  return 0;
}
sample-016.c の実行結果
C:\usr\c>sample-016
10 と 20 では 20 の方が大きい。
40 と 30 では 40 の方が大きい。
4 と -4 では 4 の方が大きい。
C:\usr\c> 

sample-017

Download : sample-017.c ( SJIS 版 )

sample-017.c
/*
 * 2012/06/15 sample-007.c
 */

/*
 * 整数の等号比較 ( == を使う )
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 二つの比較結果を出力する
 */

void print_int_equal ( int n, int m ) {

  s_print_int ( n );
  s_print_string ( " と " );
  s_print_int ( m );
  s_print_string ( " は等し" );

  if ( n == m ) {	/* n と m は等しい */
	s_print_string ( "い" );
  } else {
	s_print_string ( "くない" );
  }

  s_print_string ( "です。" );
  s_print_newline();

}

/*
 * main
 */

int main ( void ) {

  print_int_equal ( 10, 20 );
  print_int_equal ( 30, 30 );

  return 0;
}
sample-017.c の実行結果
C:\usr\c>sample-017
10 と 20 は等しくないです。
30 と 30 は等しいです。
C:\usr\c> 

sample-018

Download : sample-018.c ( SJIS 版 )

sample-018.c
/*
 * 2012/06/15 sample-008.c
 */

/*
 * 整数の等号比較 ( != を使う )
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 二つの比較結果を出力する
 */

void print_int_equal ( int n, int m ) {

  s_print_int ( n );
  s_print_string ( " と " );
  s_print_int ( m );
  s_print_string ( " は等し" );

  if ( n != m ) {	/* n と m は等しくない */
	s_print_string ( "くな" );
  } else {
  }

  s_print_string ( "いです。" );
  s_print_newline();

}

/*
 * main
 */

int main ( void ) {

  print_int_equal ( 10, 20 );
  print_int_equal ( 30, 30 );

  return 0;
}
sample-018.c の実行結果
C:\usr\c>sample-018
10 と 20 は等しくないです。
30 と 30 は等しいです。
C:\usr\c> 

sample-019

Download : sample-019.c ( SJIS 版 )

sample-019.c
/*
 * 2012/06/15 sample-009.c
 */

/*
 * 再帰と整数
 */

#include <stdio.h>
#include "s_print.h"

/*
 * n から 1 までを出力する
 */

void print_n_to_one ( int n ) {

  if ( n == 0 ) {			/* n が 0 の時 */
	/* なにもしなくてよい */
  } else {				/* そうでなければ... */
	s_print_int ( n );		/* n を出し.. */
	s_print_newline();
	print_n_to_one ( n - 1 );	/* 再帰で残りをする */
  }
}

/*
 * main
 */

int main ( void ) {

  s_print_string ( "5 〜 1 : \n" );
  print_n_to_one ( 5 );	/* 5 〜 1 を出力 */

  s_print_newline();
  s_print_string ( "10 〜 1 : \n" );
  print_n_to_one ( 10 );	/* 10 〜 1 を出力 */

  return 0;
}
sample-019.c の実行結果
C:\usr\c>sample-019
5 〜 1 : 
5
4
3
2
1

10 〜 1 : 
10
9
8
7
6
5
4
3
2
1
C:\usr\c> 

sample-020

Download : sample-020.c ( SJIS 版 )

sample-020.c
/*
 * 2012/06/15 sample-010.c
 */

/*
 * 総和の計算
 */

#include <stdio.h>
#include "s_print.h"

/*
 * n から 1 までを sum に加えた結果を出力する
 */

void print_n_to_one_sum_sub ( int n, int sum ) {

  if ( n == 0 ) {			/* n が 0 の時 */
	/* もう計算しなくてもよいので結果を出力 */
	s_print_string ( "合計は " );
	s_print_int ( sum );
	s_print_string ( "です。" );
	s_print_newline();
  } else {				/* そうでなければ... */
	print_n_to_one_sum_sub ( n - 1, sum + n );
					/* 再帰処理 */
  }
}

void print_n_to_one_sum ( int n ) {

  print_n_to_one_sum_sub ( n, 0 );	/* 最初は 1 〜 n を 0 に加える */
}

/*
 * main
 */

int main ( void ) {

  s_print_string ( "1 から 5 : " );
  print_n_to_one_sum ( 5 );

  s_print_string ( "1 から 10 : " );
  print_n_to_one_sum ( 10 );

  return 0;
}
sample-020.c の実行結果
C:\usr\c>sample-020
1 から 5 : 合計は 15です。
1 から 10 : 合計は 55です。
C:\usr\c> 

sample-021

Download : sample-021.c ( SJIS 版 )

sample-021.c
/*
 * 2012/06/15 sample-011.c
 */

/*
 * 何かを n 回繰り返す
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 文字列を 10 回出力する
 */

void print_string_n_times ( int n, char *str ) {

  if ( n == 0 ) {			/* n が 0 の時 */
	/* 仕事はすんだので何もしない */
  } else {				/* そうでなければ... */
	s_print_string ( str );	/* 取りあえず、文字列を出力し.. */
	print_string_n_times ( n - 1, str );
					/* 再帰処理 */
  }
}

/*
 * main
 */

int main ( void ) {

print_string_n_times ( 3, "Hello, World\n" );	/* "Hello, World\n" を 3 回出力 \
    */

  print_string_n_times ( 5, "こんにちは\n" );		/* "こんにちは\n" を 5 回出力 */

  return 0;
}
sample-021.c の実行結果
C:\usr\c>sample-021
Hello, World
Hello, World
Hello, World
こんにちは
こんにちは
こんにちは
こんにちは
こんにちは
C:\usr\c> 

sample-022

Download : sample-022.c ( SJIS 版 )

sample-022.c
/*
 * 2012/06/15 sample-012.c
 */

/*
 * 何かを n 回繰り返す
 */

#include <stdio.h>
#include "s_print.h"

/*
 * "*" を n 回出力
 */

void print_asta_n_times ( int n ) {

  if ( n == 0 ) {			/* n が 0 の時 */
	/* 仕事はすんだので何もしない */
  } else {				/* そうでなければ... */
	s_print_string ( "*" );	/* 取りあえず、"*" 出力し.. */
	print_asta_n_times ( n - 1 );
					/* 再帰処理 */
  }
}

void print_triangle ( int n ) {

  if ( n == 0 ) {			/* n が 0 の時 */
	/* 仕事はすんだので何もしない */
  } else {				/* そうでなければ... */
	print_asta_n_times ( n );	/* アスタリスクを n 個出力 */
	s_print_newline();

	print_triangle ( n - 1 );
					/* 再帰処理 */
  }
}

/*
 * main
 */

int main ( void ) {

  print_triangle ( 3 );

  s_print_newline();

  print_triangle ( 5 );

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

*****
****
***
**
*
C:\usr\c> 

sample-023

Download : sample-023.c ( SJIS 版 )

sample-023.c
/*
 * 2012/06/15 sample-013.c
 */

#include <stdio.h>
#include "s_print.h"

/*
 * ペアノの公理 (自然数の定義)
 *   i) 0 は自然数
 *  ii) x が自然数ならば x + 1 も自然数
 * iii) i) と ii) 以外に自然数はない
 */

/*
 * 和の定義
 *	n, m が自然数の時に n + m とは何か
 * 
 *                m        	( n が 0 の時 )
 *      n + m { 
 *		( x + m ) + 1   ( n = x + 1 の時 )
 */

/*
 * a と b の和を計算する
 */

void addition ( int n, int m ) {

  if ( n == 0 ) {	/* n が 0 の時 */
	s_print_int ( m );
  } else {
	addition ( n - 1, m + 1 );	/* x + m を計算 */
  }
}

main()
{

  addition ( 3, 4 );
  printf ( "\n" );

  addition ( 5, 9 );
  printf ( "\n" );

  /* 足し算をする */

}
sample-023.c の実行結果
C:\usr\c>sample-023
7
14
C:\usr\c> 

sample-024

Download : sample-024.c ( SJIS 版 )

sample-024.c
/*
 * 2012/06/15 sample-014.c
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 積の定義
 *	n, m が自然数の時に n * m とは何か
 * 
 *                  0      	( n が 0 の時 )
 *      n + m { 
 *		( x * m ) + m   ( n = x + 1 の時 )
 */

/*
 * n と m のかけ算
 */

void multiply_sub ( int n, int m, int mul ) {

  if (  n == 0 ) {	/* n が 0 の時 */
	s_print_int ( mul );			/* 結果を出力 */
  } else {
	multiply_sub ( n - 1, m, mul + m );	/* x * m を計算 */
  }
}

void multiply ( int n, int m ) {

  multiply_sub ( n, m, 0 );
}

main()
{

  multiply ( 3, 4 );
  s_print_newline();

  multiply ( 5, 8 );
  s_print_newline();

}
sample-024.c の実行結果
C:\usr\c>sample-024
12
40
C:\usr\c> 

sample-025

Download : sample-025.c ( SJIS 版 )

sample-025.c
/*
 * 2012/06/15 sample-015.c
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 引き算の定義
 *	n, m が自然数の時に n - m とは何か ( n >= m )
 * 
 *                n        	( m が 0 の時 )
 *      n - m { 
 *		 y - x          ( m = x + 1 の時 )
 *		                ( n = y + 1 の時 )
 */

/*
 * n と m の差
 */

void diffirence ( int n, int m ) {

  if ( m == 0 ) {	/* m が 0 の時 */
	s_print_int ( n );
  } else {
	diffirence ( n - 1, m - 1 );	/* y - x を計算 */
  }
}

main()
{

  diffirence ( 7, 3 );
  printf ( "\n" );

  diffirence ( 13, 8 );
  printf ( "\n" );

}
sample-025.c の実行結果
C:\usr\c>sample-025
4
5
C:\usr\c> 

講義中に作成したサンプルプログラム

本日の課題

課題 20120615-01

Download : 20120615-01.c ( SJIS 版 )

20120615-01.c
/*
 * DATE-DIR-QQQQ.c
 *
 *	先頭の文字が数字の場合、その後の文字列を、その回数だけ繰り返す
 */

#include <stdio.h>

/*
 *
 */

#define	EOS		'\0'

/*
 *
 */

/*
 * void echo_n_times_message ( char *message )
 *
 *	機能
 *		引数が空文字列の時には、「空文字列です」を一回だけ出力する
 *		引数で指定された文字列の先頭が数字の場合は、その後をその数字の表わす回数だけ繰り返す
 *		そうでなければ、一度だけ出力
 *	引数
 *		char * message : 出力する文字列
 *	返値
 *		void : なし
 */

void	echo_n_times_message ( char *message ) {

	if ( *message == EOS ) {		/* 空文字列だった */
		printf ( "空文字列です" );	/* 「空文字列です」を出力 */
	} else if ( *message == '0' ) {	/* 先頭が '0' で始まる */
									/* なにもしない */
	} else if ( *message == '1' ) {	/* 先頭が '1' で始まる */
		printf ( message + 1 );		/* '1' を取り除いた残りを1度出力 */
	} else if ( *message == '2' ) {	/* 先頭が '2' で始まる */
		printf ( message + 1 );		/* '2' を取り除いた残りを 2 度出力 */
		printf ( message + 1 );

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

	} else if ( *message == '6' ) {	/* 先頭が '6' で始まる */
		printf ( message + 1 );		/* '6' を取り除いた残りを 6 度出力 */
		printf ( message + 1 );
		printf ( message + 1 );
		printf ( message + 1 );		/* '6' を取り除いた残りを 6 度出力 */
		printf ( message + 1 );
		printf ( message + 1 );
	} else if ( *message == '7' ) {	/* 先頭が '7' で始まる */
		printf ( message + 1 );		/* '7' を取り除いた残りを 7 度出力 */
		printf ( message + 1 );
		printf ( message + 1 );
		printf ( message + 1 );
		printf ( message + 1 );
		printf ( message + 1 );
		printf ( message + 1 );

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

	} else {						/* そうでなかった */
		printf ( message );			/* 文字列をそのまま一度だけ出力 */
	}
}

/*
 *
 */

void check_echo_n_times_message ( char *message ) {

	printf ( "文字列 \"" );
	printf ( message );
	printf ( "\" を出力させると「" );

	echo_n_times_message ( message );

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

}

/*
 *
 */

int main ( void ) {

	printf ( "\"abc\" の場合 : " );
	check_echo_n_times_message ( "abc" );

	printf ( "\"abc\" 先頭に '3' を付けた場合 : " );
	check_echo_n_times_message ( "3abc" );

	printf ( "\"abc\" 先頭に '6' を付けた場合 : " );
	check_echo_n_times_message ( "6abc" );

	printf ( "\"\" (空文字列) の場合 : " );
	check_echo_n_times_message ( "" );

	return 0;
}

/*
 *
 */
20120615-01.c の実行結果
C:\usr\c\> 20120615-01
"abc" の場合 : 文字列 "abc" を出力させると「abc」になります。
"abc" 先頭に '3' を付けた場合 : 文字列 "3abc" を出力させると「abcabcabc」になります。
"abc" 先頭に '6' を付けた場合 : 文字列 "6abc" \
    を出力させると「abcabcabcabcabcabc」になります。
"" (空文字列) の場合 : 文字列 "" を出力させると「空文字列です」になります。
C:\usr\c\> 

次の課題は次回に回す。

課題 20120615-02

Download : 20120615-02.c ( SJIS 版 )

20120615-02.c
/*
 * DATE-DIR-QQQQ.c
 *
 *	余りを計算するプログラム
 */

#include <stdio.h>
#include "s_print.h"

/*
 * 余りの定義
 *	n, m が自然数の時に n mod m ( n を m で割った余り ) とは何か ( m > 0 )
 * 
 *                	n        	( m > n の時 ) 
 *      n mod m { 
 *		 	(n-m) mod m	( その他の時 )
 */

void remainder_sub ( int n, int m, int mm, int nn ) {
	/*                 ^        ^ 変化*/
	/*                                  ^^ 最初の m を記憶して、後から利用できるようにしている */ 
	/*                                             ^^ 割り始め n を覚えておく */
  if ( m == 0 ) {		/* m が 0 : 引き算が終った */

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

  } else if ( n == 0 ) {	/* n が 0 : m の方が大きかった */
        s_print_int ( nn );					/* 余りを出力 */
  } else {

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

  }

}

/*
 *	remainder : print ( n mod m )
 */

void remainder ( int n, int m ) {


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

}

/*
 *	main
 */

int main()
{

  printf ( "10 mod 4 = " );
  remainder ( 10, 4 );
  printf ( "\n" );

  printf ( "10 mod 3 = " );
  remainder ( 10, 3 );
  printf ( "\n" );

  printf ( "10 mod 2 = " );
  remainder ( 10, 2 );
  printf ( "\n" );

  return 0;
}
20120615-02.c の実行結果
C:\usr\c\> 20120615-02
10 mod 4 = 2
10 mod 3 = 1
10 mod 2 = 0
C:\usr\c\>