C言語に限らずforループは使います。そのときのカウンターの値はどうしているでしょうか? Cなのだから0始まり、1始まりはダサい、アマチュアっぽいって考えでは無いでしょうか?
鉄則はロジック通りに設定する
- for(int i=0;i<9;i++){
- for(int j=0;j<9;j++){
- printf("%3d",(i+1)*(j+1)); //計算式に不本意な+1が入っている。これは良くない。
- }
- printf("\n");
- }
掛け算の九九を書くよくあるサンプルです。これでも動作はしますが、多くの混乱の元があります。
一番は、ループが0から始まることです。これは大問題です。理由は現在の目的は九九を書くことですから。九九は1から9までです。だからループもそう書くべきです。
04行目の掛け算も問題です。(i+1)*(j+1)と謎の1を加えています。今回の場合なら単純なので分かりますが、本来なら i*j とするべきです。
低速度でメモリー資源が乏しいマイコンのプログラムは別として、ある程度計算資源のあるコンピュータならパフォーマンスよりコードの可読性を重視してみて下さい。
そうだ、ループも
- for(int i=1;i<=9;i++){
- for(int j=1;j<=9;j++)
として下さい。始まりは1,終わりは9とロジック的に整合性のある数字のループであると考えます。
計算結果を配列に入れる直前で操作する
しかし、配列は0から始まります。今回の九九の計算結果も、最終的には一の段は0に収納されます。非常に悩ましいですが、この場合は配列にアクセスする直前に処理して下さい。
- for(int i=1;i<=9;i++){
- for(int j=i;j<=9;j++){
- buf[i-1][j-1]=i*j; //バッファへの収納時に初めてマイナスする。
- }
- }
このコードでは計算結果を二次元配列に入れていますが、計算用のループは1~9までとし、計算も変数通りで、配列への代入時に添え字をマイナス1しています。出来る限りロジック通りの数字を使い、仕方がない部分の直前で変換しています。
今回の場合、配列のゼロ要素を使わないと言う方法論もあります。現代のメモリが潤沢にあるコンピュータなら大して問題にならないことだと思います。しかし、テキストではなくグラフィックスの場合だとロジックに関係ない表示のためだけのパラメーターが多く現れます。なのでその意味として配列のゼロ要素も使うようにしています。
復習
- 必ずロジック的に意味のある数字でループをする
- 同じかそれ以上を罪悪だと思わないこと。九九で i=1;i<10;i++はダメです。唐突に10と言う数字がありなぜ九九で10という話になります。
- 見た目のコードは確実にロジックから分離する
です。