36日目 K&RのExerciseをやってみた
K&Rの1章のエクササイズで、0〜9までの数字をカウントして、その数だけ*を出力せよというやつがあった。
ぱっと思いつかなかったので、「困難は分割せよ」メソッドを発動。
まず、forで*の階段を表示させようと思った。
/*とりあえず何も見ないで*で階段作ってみた*/ #include <stdio.h> main() { int i,j; for (i=0; i<10; i++){ // i回目の試行 for (j=0; j<i; j++){ printf("*"); } printf("\n"); } return 0; } 出力結果 * ** *** **** ***** ****** ******* ******** ********* **********
→*が何個あるのかわかりづらい。表示しよう。
/*数字を表示させてみた*/ #include <stdio.h> main() { int i, j; for (i=0; i<10; i++){ printf("%d\t", i); // i回目の試行(この行ではiはカウンタ) for (j=0; j<i; j++){ // この行ではiは定数、jがカウンタ printf("*"); } printf("\n"); } return 0; } 実行結果 0 1 * 2 ** 3 *** 4 **** 5 ***** 6 ****** 7 ******* 8 ******** 9 *********
宿題
- 8行目をの引数をjにしたらうまくいかないのはなぜか簡潔に説明せよ
- プログラムを読み込んで行数を表示するソースをつくろう
- いまは関係ないけど変数一個にできないか
- そもそもforに関係なく変数の値のみに依存して*の数を自由に変えたい
- for文の中身が不適当
/*配列の中身だけ*を表示*/ #include <stdio.h> main() { int i,j,wc[10]={0,1,2,3,4,5,6,7,8,9}; for (i=0; i<10; i++){ printf("%d\t", i); for (j=0; j<wc[i]; j++){ printf("*"); } printf("\n"); } return 0; } 出力結果 0 1 * 2 ** 3 *** 4 **** 5 ***** 6 ****** 7 ******* 8 ******** 9 *********
さっきとおなじになった。よかったよかった。
ちなみにここでwc[i]でなくwc[j]ではうまくいかないのだが、その理由をすぐに説明できないのがくやしい。おちつけ。少し考えればわかるはずだ。
さて問題のexcerciseなわけだが
/*1.6 Arrays*/ #include <stdio.h> /* count digits, white spaces, others */ main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); for (i = 0; i < 10; ++i) printf(" %d",ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); }
OKわかった。最後のforループの中身をいじればよい。
とりあえずもう一個変数がいる。
と、そのまえにこのソースを実行して円周率内の数字の分布を見たい。
実行結果 3.1415926535897932384626433832795028841971693993751058209749445923078164 ^Z digits = 4 6 7 10 8 7 5 6 7 11, white space = 1, other = 1
これを視覚的に表示させる。
#include <stdio.h> main() { int c, i, j, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits :\n"); for (i = 0; i < 10; ++i){ printf(" %d\t", i); for (j=0; j<ndigit[i]; j++){ printf("*"); } printf("\n"); } printf(" white space = %d, other = %d\n", nwhite, nother); } 実行結果 3.1415926535897932384626433832795028841971693993751058209749445923078164 ^Z digits : 0 **** 1 ****** 2 ******* 3 ********** 4 ******** 5 ******* 6 ***** 7 ****** 8 ******* 9 *********** white space = 1, other = 1
できた!
→宿題
「横方向ではなく、縦方向に*を積み上げて表示せよ」
…がんばる。