Download : sample-001.c ( SJIS 版 )
/*
* DATE sample-001.c
*/
/*
* [解説]
* ファイル tgc.c から N Times の部分を切り出して s_rtg.h を作成
* 残った main 関数のみを sample-001.c に残す。
* #include を利用して、N Times の部分を取り込む事により
* rtg.c と同じ動作のプログラムにする。
*/
#include <stdio.h> /* 実は不要だが、「お呪い」なので.. */
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/* turtle.h は不要 */
/* この中に turlte.h と N Times が入っている */
/*
* main 関数 (rtg.c と同じ事をする)
*/
int main ( void ) {
/* 一度目 */
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
/* ニ度目 */
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
/* 三度目 */
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
/* 四度目 */
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
/* 最後の turn は、「四角を書く」という立場からは不要 */
return 0;
}
$ ./sample-001.exe $
Download : sample-002.c ( SJIS 版 )
/*
* DATE sample-002.c
*/
/*
* [解説]
* main 中の繰返しパターンの二行を関数 draw_10_edge_2_turn
* として取り出す。
* rtg.c の main 関数の最後の行が無駄に思えたが、実は意味があり、
* プログラムをパターン化し、関数の利用を促進する意味があった事が、
* ここで、明らかになる。
*/
#include <stdio.h>
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_10_edge_2_turn
* 長さ 10 の辺を書き、向きを二度変更する
* (プログラムの共通部分を見つけ関数化)
*/
void draw_10_edge_2_turn ( void ) {
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* main 関数 (rtg.c と同じ事をする)
*/
int main ( void ) {
/* 一度目 */
draw_10_edge_2_turn();
/* ニ度目 */
draw_10_edge_2_turn();
/* 三度目 */
draw_10_edge_2_turn();
/* 四度目 */
draw_10_edge_2_turn();
/* 最後の turn がなかったら、ここだけ「特別扱い」にする必要がある */
/* プログラムの構造を簡単にする(パターン化)するために、敢えて無駄をする */
return 0;
}
$ ./sample-002.exe $
Download : sample-003.c ( SJIS 版 )
/*
* DATE sample-003.c
*/
/*
* [解説]
* 長さ 10 の矩形を書く関数 draw_rect_10 の作成と、その利用例
*/
#include <stdio.h>
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_10_edge_2_turn
* 長さ 10 の辺を書き、向きを二度変更する
* (プログラムの共通部分をみつけ関数化)
*/
void draw_10_edge_2_turn ( void ) {
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* draw_rect_10
* 長さ 10 の矩形を作成
*/
void draw_rect_10 ( void ) {
/* draw_10_edge_2_turn を 4 度呼び出す */
draw_10_edge_2_turn();
draw_10_edge_2_turn();
draw_10_edge_2_turn();
draw_10_edge_2_turn();
}
/*
* main 関数
*/
int main ( void ) {
/* 四角形を 3 つ書く */
draw_rect_10();
s_n_times_turtle_jump ( "123456789012345" ); /* 15 回 jump */
draw_rect_10();
s_n_times_turtle_jump ( "123456789012345" ); /* 15 回 jump */
draw_rect_10();
s_n_times_turtle_jump ( "123456789012345" ); /* 15 回 jump */
/* 最後の jump は不要だが... */
return 0;
}
$ ./sample-003.exe $
Download : sample-004.c ( SJIS 版 )
/*
* DATE sample-004.c
*/
/*
* [解説]
* 関数 draw_rect_10 の別の利用例
*/
#include <stdio.h>
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_10_edge_2_turn
* 長さ 10 の辺を書き、向きを二度変更する
* (プログラムの共通部分をみつけ関数化)
*/
void draw_10_edge_2_turn ( void ) {
s_n_times_turtle_move ( "1234567890" ); /* 10 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* draw_rect_10
* 長さ 10 の矩形を作成
*/
void draw_rect_10 ( void ) {
/* draw_10_edge_2_turn を 4 度呼び出す */
draw_10_edge_2_turn();
draw_10_edge_2_turn();
draw_10_edge_2_turn();
draw_10_edge_2_turn();
}
/*
* main 関数
*/
int main ( void ) {
/* 四角形を、向きを変更しながら 4 つ書く */
draw_rect_10();
s_n_times_turtle_turn ( "123456" ); /* 6 回 turn */
s_n_times_turtle_jump ( "12" ); /* 2 回 jump */
draw_rect_10();
s_n_times_turtle_turn ( "123456" ); /* 6 回 turn */
s_n_times_turtle_jump ( "12" ); /* 2 回 jump */
draw_rect_10();
s_n_times_turtle_turn ( "123456" ); /* 6 回 turn */
s_n_times_turtle_jump ( "12" ); /* 2 回 jump */
draw_rect_10();
s_n_times_turtle_turn ( "123456" ); /* 6 回 turn */
s_n_times_turtle_jump ( "12" ); /* 2 回 jump */
return 0;
}
$ ./sample-004.exe $
Download : sample-005.c ( SJIS 版 )
/*
* DATE sample-005.c
*/
/*
* [解説]
* 引数を利用して、矩形の辺の長さを可変する
*/
#include <stdio.h>
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_n_edge_2_turn
* 長さ n の辺を書き、向きを二度変更する
* (プログラムの共通部分を見つけ関数化)
*/
void draw_n_edge_2_turn ( char *n ) {
s_n_times_turtle_move ( n ); /* n 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* draw_rect_n
* 長さ n の矩形を作成
*/
void draw_rect_n ( char *n ) {
/* draw_n_edge_2_turn を 4 度呼び出す */
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
}
/*
* main 関数
*/
int main ( void ) {
/* 大きさの違う四角形を 3 つ書く */
draw_rect_n( "123456789012" ); /* 一辺が 12 の矩形 */
s_n_times_turtle_jump ( "123456789012345" ); /* 15 回 jump */
draw_rect_n( "123456789" ); /* 一辺が 9 の矩形 */
s_n_times_turtle_jump ( "123456789012" ); /* 12 回 jump */
draw_rect_n( "123456" ); /* 一辺が 6 の矩形 */
s_n_times_turtle_jump ( "123456789" ); /* 9 回 jump */
/* 最後の jump は不要だが... */
return 0;
}
$ ./sample-005.exe $
Download : sample-006.c ( SJIS 版 )
/*
* DATE sample-006.c
*/
/*
* [解説]
* 連続的に小くなる四角の列を作る
*/
#include <stdio.h>
#include <string.h> /* strcmp を利用する場合に必要 */
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_n_edge_2_turn
* 長さ n の辺を書き、向きを二度変更する
* (プログラムの共通部分を見つけ関数化)
*/
void draw_n_edge_2_turn ( char *n ) {
s_n_times_turtle_move ( n ); /* n 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* draw_rect_n
* 長さ n の矩形を作成
*/
void draw_rect_n ( char *n ) {
/* draw_n_edge_2_turn を 4 度呼び出す */
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
draw_n_edge_2_turn( n );
}
/*
* draw_down_3_size
* 長さ 3 * n から 3 ずつ小くした矩形列を作る
* <<<注意>>> 元の n の長さは、必ず 3 の倍数にする必要がある
*/
void draw_down_3_size ( char *n ) {
if ( !strcmp ( n, "" ) ) { /* n が空文字列の時 */
/* 何もしなくてよい */
} else {
draw_rect_n ( n ); /* 1 辺が n の矩形を描画 */
s_n_times_turtle_jump ( n ); /* 1 辺分を jump */
s_n_times_turtle_jump ( "123" ); /* 更に隙間を空けために 3 jump */
draw_down_3_size ( n + 3 ); /* 3 だけ、辺の長さを短かく */
}
}
/*
* main 関数
*/
int main ( void ) {
/* 大きさの違う四角形系列を描画 */
draw_down_3_size ( "123456789012345678" ); /* 18 から開始 */
draw_down_3_size ( "123456" ); /* 6 から開始 */
return 0;
}
$ ./sample-006.exe $
/*
* 20150501-03-QQQQ.c
* 底辺の長さが指定した文字列の二倍の長さ - 1 の横向のピラミッドを作成するプログラムを作成する
*/
#include <stdio.h>
#include <strings.h>
/*
*/
void down ( char *edge ) {
if ( !strcmp ( edge, "" ) ) {
/* なにもする必要はない */
} else {
printf ( edge );
printf ( "\n" );
down ( edge + 1 );
}
}
void up ( char *edge ) {
if ( !strcmp ( edge, "" ) ) {
/* なにもする必要はない */
} else {
up ( edge + 1 );
/*
** この部分を完成させなさい
*/
}
}
void pyramid ( char *edge ) {
up ( edge + 1 );
printf ( edge );
printf ( "\n" );
/*
** この部分を完成させなさい
*/
}
/*
* main
*/
int main ( void ) {
pyramid ( "*****" );
printf ( "\n" );
pyramid ( "**********" );
return 0;
}
/*
* 20150501-03-QQQQ.c
* 底辺の長さが指定した文字列の二倍の長さ - 1 の横向のピラミッドを作成するプログラムを作成する
*/
#include <stdio.h>
#include <strings.h>
/*
*/
void down ( char *edge ) { /* p-006.c と同じ考え方 */
if ( !strcmp ( edge, "" ) ) {
/* なにもする必要はない */
} else {
printf ( edge );
printf ( "\n" );
down ( edge + 1 );
}
}
void up ( char *edge ) { /* p-006.c とはちょっと違う */
if ( !strcmp ( edge, "" ) ) {
/* なにもする必要はない */
} else {
up ( edge + 1 );
/*
** この部分を完成させなさい
*/
}
}
void pyramid ( char *edge ) {
/* pyramid ( "***" ); の時 */
up ( edge + 1 ); /* 上の部分 */
/*
*
**
*/
printf ( edge ); /* *** *.
printf ( "\n" );
/*
**
*
*/
/*
** この部分を完成させなさい
*/
down ( egde + 1 );
}
/*
* main
*/
int main ( void ) {
pyramid ( "*****" );
printf ( "\n" );
pyramid ( "**********" );
return 0;
}
#include <stdio.h>
int main(void)
{
printf ( "Hello, World\n" );
return 0;
}
#include <stdio.h>
int main(void)
{
printf ( "Hello, World\n" + 1 );
/* 文字列に 1 を加えると何がおきるか ? */
return 0;
}
#include <stdio.h>
int main(void)
{
printf ( "Hello, World\n" );
printf ( "Hello, World\n" + 1 );
printf ( "Hello, World\n" + 2 ); /* +2 -> +1 +1 */
printf ( "Hello, World\n" + 3 );
printf ( "Hello, World\n" + 4 );
return 0;
}
#include <stdio.h>
int main(void)
{
printf ( "Hello, World\n" ); /* 13 文字 */
printf ( "Hello, World\n" + 1 );
printf ( "Hello, World\n" + 2 ); /* +2 -> +1 +1 */
printf ( "Hello, World\n" + 3 );
printf ( "Hello, World\n" + 4 );
printf ( "Hello, World\n" + 5 );
printf ( "Hello, World\n" + 6 );
printf ( "Hello, World\n" + 7 );
printf ( "Hello, World\n" + 8 );
printf ( "Hello, World\n" + 9 );
printf ( "Hello, World\n" + 10 );
printf ( "Hello, World\n" + 11 );
printf ( "Hello, World\n" + 12 ); /* "\n" の改行のみ */
printf ( "Hello, World\n" + 13 ); /* "" 空文字列なので何もしない*/
return 0;
}
#include <stdio.h>
void print_hello_7(char *X) {
printf ( X + 0 ); /* 13 文字 */
printf ( X + 1 );
printf ( X + 2 ); /* +2 -> +1 +1 */
printf ( X + 3 );
printf ( X + 4 );
printf ( X + 5 );
printf ( X + 6 );
}
int main(void)
{
printf ( "test 1\n" );
print_hello_7("0123456789\n");
printf ( "test 2\n" );
print_hello_7("Hello, World\n");
/*
printf ( "Hello, World\n" + 0 );
printf ( "Hello, World\n" + 1 );
printf ( "Hello, World\n" + 2 );
printf ( "Hello, World\n" + 3 );
printf ( "Hello, World\n" + 4 );
printf ( "Hello, World\n" + 5 );
printf ( "Hello, World\n" + 6 );
*/
print_hello_7("Hello, World\n"+7);
/*
printf ( ("Hello, World\n" + 7) + 0 );
printf ( ("Hello, World\n" + 7) + 1 );
printf ( ("Hello, World\n" + 7) + 2 );
printf ( ("Hello, World\n" + 7) + 3 );
printf ( ("Hello, World\n" + 7) + 4 );
printf ( ("Hello, World\n" + 7) + 5 );
printf ( ("Hello, World\n" + 7) + 6 );
*/
return 0;
}
#include <stdio.h>
/*
*/
void print_down(char *X) {
if ( !strcmp ( X, "" ) ) { /* X が "" (空文字列) だった */
/* 何もしない */
} else { /* そうでなかったら.. */
printf ( X ); /* とりあえず、その文字列を出す */
print_down ( X + 1 ); /* 問 : 残りはどうやって出せばよいか */
} /* 答 : 再帰呼出を利用する */
}
int main(void)
{
printf ( "test 1\n" );
print_down ("0123456789\n");
printf ( "test 2\n" );
print_down ("Hello, World\n");
return 0;
}
2015/05/08
文字列に 1 を加えると、先頭の文字が一文字かけて、
一文字短かい文字列ににかわる
例 :
"abc" + 1 -> "bc"
"abc" + 3 -> "" 文字列の長さだけ足すと空文字列("")になる
<<疑問>> 文字の長さより大きな数を加えたら.. ?
-> なにがおきるかわからない
-> プログラムをかく人が気を付ける
「¥(エンマーク)」と「\(バックスラッシュ)」
windows では「¥」が ubuntu では「\」になる
<目的>
print_down( "abc\n" );
->
abc -> printf ( "abc\n" );
bc -> printf ( "bc\n" );
c -> printf ( "c\n" );
((空行))-> printf ( "\n" );
となるようにしたい
結果は
abc
bc
c
((空行))
なので、これを、最初の一つと残りに分ける
つまり、
abc (step-1)
と
bc (step-2)
c
((空行))
に分けて考える (分割統治法)
(step-1)
printf ( "abc\n" );
(step-2)
print_down( "bc\n" );
-> print_down( "abc\n" + 1 );
<結論>
void print_down ( char *X ) {
if ( !strcmp ( X, "" ) ) {
/* do nothing */
} else {
printf ( X );
print_down( X + 1 ); /* 再帰呼出 */
}
}
<課題 20150501-03>
pyramid ( "***" );
->
*
**
***
**
*
<考え方>
* <step-1>
**
*** <step-2>
**
*
<理由>
0: step-2 はできている (p-006)
step-2 -> print_down ( "*** );
1:
<step-1> と <step-2> は
ルールが違う
<up>
up ( "***" );
->
*
**
***
->
*
**
と
***
に分割
->
??? -> up ( "**" );
printf ( "***" ); printf ( "\n" );
<結論>
void up ( char *X ) {
if ( !strcmp ( X, "" ) ) {
/* do nothing */
} else {
up ( X + 1 );
printf ( X );
printf ( "\n" );
}
}
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20150508-01.c ( SJIS 版 )
/*
* 20150508-01-QQQQ.c
*
* 入れ子になった四角を書く関数
*/
#include <stdio.h>
#include <string.h> /* strcmp を利用する場合に必要 */
#include "s_rtg.h" /* N Tims turtle graphics の時に必要 */
/*
* draw_n_edge_2_turn
* 長さ n の辺を書き、向きを二度変更する
* (プログラムの共通部分を見つけ関数化)
*/
void draw_n_edge_2_turn ( char *n ) {
s_n_times_turtle_move ( n ); /* n 回 move */
s_n_times_turtle_turn ( "12" ); /* 2 回 turn */
}
/*
* draw_rect_n
* 長さ n の矩形を作成
*/
void draw_rect_n ( char *n ) {
/* draw_n_edge_2_turn を 4 度呼び出す */
draw_n_edge_2_turn( n );
/* ヒント: 後、三回呼び出す必要がある */
/*
** この部分を完成させなさい
*/
}
/*
* draw_down_4_size
* 長さ 4 * n から 4 ずつ小くした矩形列を作る
* <<<注意>>> 元の n の長さは、必ず 4 の倍数にする必要がある
*/
void draw_down_4_size ( char *n ) {
if ( !strcmp ( n, "" ) ) { /* n が空文字列の時 */
/* 何もしなくてよい */
} else {
draw_rect_n ( n ); /* 1 辺が n の矩形を描画 */
s_n_times_turtle_turn ( "1" ); /* 向きを 1 つだけ変更 */
s_n_times_turtle_jump ( "12" ); /* 2 つだけ jump */
s_n_times_turtle_turn ( "1234567" ); /* 向きを 7 つだけ変更 */
/* ヒント: 再帰呼出し ( n は幾つ変更する必要があるか ? ) */
/*
** この部分を完成させなさい
*/
}
}
/*
* main 関数
*/
int main ( void ) {
/* 大きさの違う四角形系列を描画 */
draw_down_4_size ( "12345678901234567890" ); /* 20 から開始 */
s_n_times_turtle_jump ( "12345678901234" ); /* 14 jump */
draw_down_4_size ( "12345678" ); /* 6 から開始 */
return 0;
}
$ ./20150508-01-QQQQ.exe $