#include <stdio.h>
/*
	あること(命令)を繰り返したい
		=> 「Hello, World」を出力
	繰り返し : 同じ事を k 回数行う
		=> k をどうするか ?
		例: 繰り返す回数を 3 とした場合... ??
	ここでは、
		1. 文字列には長さがある
			例 : "abc" => 長さ 3
		2. (原理は不明だが..) 文字列に +1 すると、文字列の長さは
			短くなる
		3. 文字列を、短くしてゆく(+1 する)と、最後に "" 空文字列になる
			=> 条件判定で、判断(チェック)できる
	という文字列の性質を利用し
		繰り返し回数を文字列(の長さ)で表現する
			例 : 3 という回数を示すのに、"abc" 長さ 3 の文字列を利用する
	times_hello ( "abc" );
		=> 3 回、「Hello, World」を表示する
*/
void times_hello (char *n ) {
	/* 引数 n は、文字列だが、中身はどうでもよくて、長さだけが重要 */
	/* 繰り返しのパターン[再帰] */
	
	if ( !strcmp ( n, "" ) ) {
		/* 空文字列 : 長さが 0 ということ... */
		/* 繰り返しの回数が、0 なので、なにもしないで「終わり」にしてよい */
	} else {
		/* 少なくても、一度は、Hello World を出す必要がある */
		/* 繰り返したい命令 */
		printf ( "Hello, World\n" );
		/* 残りは ? ( やりたい目的の回数 - 1 回 )*/
		times_hello ( n + 1 );
		/* 残りは、再帰呼び出しにする */
		/* ポイントは、引数の文字列に +1 する事により、
			長さを 1 つだけ、短くする(繰り返し回数が 1 減る ) */
	}
}
int main(void) {
	printf ( "3 回数出力\n" );
	times_hello ( "123" );
	printf ( "10 回数出力\n" );
	times_hello ( "1234567890" );
	return 0;
}
#include <stdio.h>
int main(void) {
	putchar ( 'A' );	/* 画面に「A」という文字を出力する */
						/* 「文字」を出すので「'A'」という形 */
						/* 「文字」を扱うので putchar を利用している */
						/* cf.
								printf ( "A" );
						*/
	putchar ( '\n' );	/* 「\n」は「改行」を表す「文字」 */
	
	return 0;
}
#include <stdio.h>
int main(void) {
	putchar ( getchar() );	/* キーボードから一文字読み込む(getchar)
								その文字を画面に出す(putchar) */
	putchar ( '\n' );	/* 「\n」は「改行」を表す「文字」 */
	return 0;
}
#include <stdio.h>
/*
	三文字入力して、三文字出力する
*/
int main(void) {
	putchar ( getchar() );
	putchar ( getchar() );
	putchar ( getchar() );
		/* 関数合成を行っている事に注意 */
		/* 	順接のもう一つの形 */
		/*		getchar() => putchar() : 二つの関数を順序付けている */
	putchar ( '\n' );	/* 「\n」は「改行」を表す「文字」 */
	return 0;
}
#include <stdio.h>
/*
	入力が、毎回、1 文字 + 改行になる事を想定して、画面に出す
*/
int main(void) {
	putchar ( getchar() );	/* 入力された文字列 */
	getchar();				/* 次に「改行」が来るはずだが、読み飛ばす */
	putchar ( '?' );
	putchar ( '\n' );
	putchar ( getchar() );	/* 入力された文字列 */
	getchar();				/* 次に「改行」が来るはずだが、読み飛ばす */
	putchar ( '?' );
	putchar ( '\n' );
	putchar ( getchar() );	/* 入力された文字列 */
	getchar();				/* 次に「改行」が来るはずだが、読み飛ばす */
	putchar ( '?' );
	putchar ( '\n' );
	putchar ( '\n' );	/* 「\n」は「改行」を表す「文字」 */
	return 0;
}
#include <stdio.h>
/*
	目的
		Turtle Grapics をしたい
			プログラム作成上の注意
				#include "s_turtle.h"
			を冒頭にいれる
		プログラムを実行する場合は、
			make test BASE=ファイルのベース名とする
				例: p-006.c を実行するには、
					make test BASE=p-006
				とする。
				# getchar() が最後にあるので、[Enter] キーを
				# 押さないと、プログラムが終了しない事に注意
*/
#include "s_turtle.h"	/* turtle graphics をする場合の追加のおまじない */
/*
	命令
		Turtle Graphics で利用できる命令
		s_turtle_move(); : 現在の位置に足跡を残し、現在の方向に一歩進みます
		s_turtle_jump(); : 現在の位置に足跡を残さず、現在の方向に一歩進みます
		s_turtle_turn(); : 現在の方向を時計回りに 45 度変更します 
		s_turtle_stop(); : 亀プログラムの終了 (「return 0;」の直前に実行)
*/
int main(void) {
	/* Turtle Graphics の命令を書く */
	s_turtle_move();	/* 亀への命令をする */
						/* 亀は、今いる場所に、足跡を残し、
							自分が向いている方向に一歩進む */
	/* 結果的に、画面に「足跡」が一歩(一点)だけ残る */
	getchar();			/* いきなり終了せず、いったん改行を待つ */
	s_turtle_stop();
	return 0;
}
#include <stdio.h>
#include "s_turtle.h"
int main(void) {
	/* Turtle Graphics の命令を書く */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	getchar();
	s_turtle_stop();
	return 0;
}
#include <stdio.h>
#include "s_turtle.h"
/* 一辺の長さが 10 である正方形を書くプログラム */
/*
	+---+
	|	| 一辺の長さが 10
	+---+
	1) 10 回 move すれば、長さ 10 直線がかける
	2) 2 回 turn すれば、90 度(直角)の向きがかえられる
	3) 正方形は、直角に交わる 4 辺からなる
*/
int main(void) {
	/* Turtle Graphics の命令を書く */
		/* 左辺 */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
		/* 上辺 */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
		/* 右辺 */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
		/* 下辺 */
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	getchar();
	s_turtle_stop();
	return 0;
}
#include <stdio.h>
#include "s_turtle.h"
/* 一辺の長さが 10 である正方形を書くプログラム */
/*
	関数を利用して、プログラムを整理しよう..
*/
/*
	move_ten()
	10 歩進む
*/
void move_ten(void) {
	s_turtle_move();	/* 10歩,歩きながら、足跡を残す */
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
	s_turtle_move();
}
/*
	turn_R()
	90 度向き変える
*/
void turn_R(void) {
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
}
int main(void) {
	/* Turtle Graphics の命令を書く */
		/* 左辺 */
	move_ten();
	turn_R();
		/* 上辺 */
	move_ten();
	turn_R();
		/* 右辺 */
	move_ten();
	turn_R();
		/* 下辺 */
	move_ten();
	getchar();
	s_turtle_stop();
	return 0;
}
#include <stdio.h>
#include "s_turtle.h"
/* 一辺の長さが 10 である正方形を書くプログラム */
/*
	関数を利用して、プログラムを整理しよう..
*/
/*
	move_n
		n 歩 move する(n は引数で、繰り返し回数を指定する )
			=> 引数に文字列を指定して、その長さだけ繰り返す
*/
void move_n(char *times) {
	if ( !strcmp ( times, "" ) ) {
	} else {
		s_turtle_move();
		move_n ( times + 1 );
	}
}
/*
	move_ten()
	10 歩進む
*/
void move_ten(void) {
	move_n ( "1234567890" );
}
/*
	turn_R()
	90 度向き変える
*/
void turn_R(void) {
	s_turtle_turn();	/* 亀の向きを 45 度変える */
	s_turtle_turn();	/* 亀の向きを 45 度変える */
}
/*
	辺の長さが 10 を書く
	rect_ten
*/
void rect_ten(void) {
		/* 左辺 */
	move_ten();
	turn_R();
		/* 上辺 */
	move_ten();
	turn_R();
		/* 右辺 */
	move_ten();
	turn_R();
		/* 下辺 */
	move_ten();
}
int main(void) {
	/* Turtle Graphics の命令を書く */
	rect_ten();	/* 辺の長さが 10 の正方形 */
				/* さらに、30 の正方形も *
	
	getchar();
	s_turtle_stop();
	return 0;
}
#include <stdio.h>
#include "s_turtle.h"
/* 一辺の長さが n である正方形を書くプログラム */
/*
	move_n
		n 歩 move する(n は引数で、繰り返し回数を指定する )
			=> 引数に文字列を指定して、その長さだけ繰り返す
*/
void move_n(char *times) {
	if ( !strcmp ( times, "" ) ) {
	} else {
		s_turtle_move();
		move_n ( times + 1 );
	}
}
void turn_n(char *times) {
	if ( !strcmp ( times, "" ) ) {
	} else {
		s_turtle_turn();
		turn_n ( times + 1 );
	}
}
/*
	turn_R()
	90 度向き変える
*/
void turn_R(void) {
	turn_n ( "01" );
}
/*
	辺の長さが n の正方形を書く
	rect_n
*/
void rect_n(char *length) {
		/* 左辺 */
	move_n(length);
	turn_R();
		/* 上辺 */
	move_n(length);
	turn_R();
		/* 右辺 */
	move_n(length);
	turn_R();
		/* 下辺 */
	move_n(length);
	turn_R();
}
int main(void) {
	/* Turtle Graphics の命令を書く */
	rect_n("1234567890" );	/* 辺の長さが 10 の正方形 */
	/* 外側の正方形の書き出し位置と向きを調整すればよい */
	/* 今いるところから、左下に 10 歩のところにゆけばよい */
	turn_n ( "12345" );	/* 亀の向きを右下に向ける */
	move_n ( "1234567890" );	/* 10 歩歩く */
	turn_n ( "123" );	/* 亀の向きを上に戻す */
				/* さらに、30 の正方形も */
	rect_n( "123456789012345678901234567890" );	/* 辺の長さが 10 の正方形 */
	
	getchar();
	s_turtle_stop();
	return 0;
}
BASE=p-001
all	:	${BASE}.exe
${BASE}.exe : ${BASE}.o
	cc -o ${BASE}.exe ${BASE}.o
${BASE}.o : ${BASE}.c
	cc -c ${BASE}.c
test	:	${BASE}.exe
	./${BASE}.exe
[復習]
	前回、再帰呼び出しを利用した、繰り返し
		繰り返しのパターン
			k 回、繰り返したい場合
			長さ k の文字列 n を引数として指定して、再帰呼び出しをする
		1. 関数の名前決める
		2. 次のひな型を作る
void 関数名 ( char *n ) {
	if ( !strcmp ( n, "" ) ) {
		/* なにもしない */
	} else {
		/* 繰り返したい命令 : 再帰とは無関係でよい */
			/* 「ここ」*/
		/* 再帰 */
		関数名 ( n + 1 );
	}
}
		3. 繰り返したい命令を「ここ」のところに挿入
		4. 繰り返しを実行する場合
			関数名 ( 繰り返す回数の長さ文字列 );
[今日の目標]
	「繰り返し」に慣れる
		命令が「文字列のプリント」だけではつまらないので、
			絵を描く事を考える
	文字
		C 言語では、「文字」を、表すためには、
			「'」 + その文字を表す文字(一字) + 「'」
				例 : 「'A'」は、「A」という文字を表す C 言語の表現
					特殊な例として '\' で始まる二文字で一文字を表す場合もある
						例 : '\n' => 改行一文字
							'\0' => NUL 文字(空文字) が実は、文字列の最後にある
							'\\' => 「\」という文字を表す
								# Windows では「\(円マーク)」
								# Ubuntu では「\(バックスラッシュ)」になる
				cf. 「"A"」は、「A」という文字を一つ含む文字列
		文字を出力するときには、
			putchar 関数を利用する
				例 : 「A」という文字を出力する場合は、
					putchar ( 'A' );
				とする。
		文字を入力するときには、
			getchar() 関数が利用できる
				getchar() を呼び出すと、キーボードから、一文字
				読み込み、その一文字が、「関数の値」となる
				例 : キーボードから、一文字入力し、それを画面に出すには、
					putchar ( getchar() );
				とする。
					putchar の引数は、「文字」でなければならないが、
					getchar が返す値が「文字」なので、うまくゆく
				# 入力は、[Enter] キーが押されるまで、待つ仕組みになっている
				#	待つ事を目的として getcharを使う
BASE=p-001
all	:	${BASE}.exe
${BASE}.exe : ${BASE}.o
	cc -o ${BASE}.exe ${BASE}.o
${BASE}.o : ${BASE}.c
	cc -c ${BASE}.c
test	:	${BASE}.exe
	./${BASE}.exe
Download : 20180601-01.c
/*
 * 20180601-01-QQQQ.c
 *	与えられた文字列の文字を二度ずつ出力する関数を作成する
 */
#include <stdio.h>
#include <strings.h>
/*
 * double_print
 *	与えられた文字列(message)の文字を二度ずつ出力する
 */
void double_print ( char *message ) {
  if ( !strcmp ( message, "" ) ) {	/* 空文字列だった */
	/* なにもする必要はない */
  } else {
  	putchar ( *message );			/* 取り敢えず、一つ分は出す */
	/*
	**	 この部分を完成させなさい
	*/
	double_print ( message + 1 );	/* 再帰呼出しをする */
  }
}
/*
 * main
 */
int main ( void ) {
	double_print ( "abc" );
	printf ( "\n" );
	double_print ( "1234567" );
	printf ( "\n" );
	return 0;
}
$ ./20180601-01-QQQQ.exe aabbcc 11223344556677 $
Download : 20180601-02.c
/*
 * 20180601-02-QQQQ.c
 *	与えられた文字列の文字を逆順に出力する関数を作る
 */
#include <stdio.h>
#include <strings.h>
/*
 * reverse_print
 *	与えられた文字列(message)の文字を逆順に出力する
 */
void reverse_print ( char *message ) {
  if ( !strcmp ( message, "" ) ) {	/* 空文字列だった */
	/* なにもする必要はない */
  } else {
	/* ここで再帰呼出しを行うのだが... */
	/*
	**	 この部分を完成させなさい
	*/
  }
}
/*
 * main
 */
int main ( void ) {
	reverse_print ( "abc" );
	printf ( "\n" );
	reverse_print ( "1234567" );
	printf ( "\n" );
	return 0;
}
$ ./20180601-02-QQQQ.exe cba 7654321 $