第13講 3次魔方陣の自動生成 
第5話 1行1行のトレースその1
#include<iostream>
using namespace std;
voi
d f(int **a);
int main(){
  int i1,i2,i3,i4,i5,i6,i7,i8,i9;
  int **a,cn;
  cn=0;
  a=(int **)malloc(12);
  for(i1=0;i1<3;i1++)a[i1]=(int *)malloc(12);
  for(i1=1;i1<10;i1++){
    a[0][0]=i1;
    for(i2=1;i2<10;i2++){
      a[0][1]=i2;
      if(a[0][1]!=a[0][0]){
 
本日は、ここまで1行1行解説していきましょう。
#include<iostream>
using namespace std;
この2行はcoutを使うためのお呪いでした。
学習が進んできた、前半についてはもう少し正確に説明できます。
iostream はインクルードファイルです。
インクルードファイルとは、よく使う関数や定義をまとめておいたものです。
coutを使うためには、iostream に関連する関数があるのでインクルードする必要があるわけです。
インクルードとは読み込みですね。
もう1行は後に名前空間の講を設けて、
namespaceについて学習すると、
お呪いという比喩的な説明から、脱することができます。
何度か言いました。
(プログラミングの勉強だけでなく、
一般に言えることですが、一気に理解しようとする姿勢は禁物です。
わからなかった点も、学習が進めばすっきりわかってくるからです。
推理小説でも最後まで読み進めないと、いろいろな伏線の意味がわかりませんよね。
哲学書でも社会科学の本でも、辞典を片手に1行1行理解していこうとすると、
必ず挫折することになります。
哲学用語の意味は、決して辞典には書いてはなく、
著者がその用語に込めている独自の意味を著書全体から学ぶしかないからです。)

名前空間について簡単に説明しておくと、
変数の適応範囲を示すものです。
変数には関数の中で通用するローカル変数、
ファイルの中で通用するグローバル変数、
ファイルを超えて通用する変数
がありましたが、範囲をより広げたり絞ったりするのが名前空間すなわちnamespaceです。
変数の通用する範囲をスコープと言います。
スコープを関数より広げるものが、名前空間です。

int main(){
  int i1,i2,i3,i4,i5,i6,i7,i8,i9;
変数が多いので、今回はこのような変数名にしてみました。
なぜ、9つも制御変数(for文を制御する変数)も必要なのでしょうか。
3次魔方陣は、9つのセルがあるからです。
そのすべてのセルについて、1から9まで入れていかないとすべての場合を網羅したことになりませんね。

  int **a,cn;
  cn=0;
  a=(int **)malloc(12);
  for(i1=0;i1<3;i1++)a[i1]=(int *)malloc(12);
の4行については、解説は入りませんね。
ポインタのポインタを使うためには
  a=(int **)malloc(12);
  for(i1=0;i1<3;i1++)a[i1]=(int *)malloc(12);
の2行による初期化が必要でした。int型は4バイトですので、
添え字を3つ使うために
4×3=12
バイトを確保しておく必要があります。
添え字が3つというのは、1辺が3の3次魔方陣を考えているからです。

  for(i1=1;i1<10;i1++){
    a[0][0]=i1;
では、

ピンクのセルに1から9まで入れていきます。最初の試行は、

    for(i2=1;i2<10;i2++){
      a[0][1]=i2;
ここだけ条件なしに進むのは、2つの条件
① 数字の重複がない
② 行・列・対角線の合計がすべて同じである
のいずれにも抵触しません。
数字が1個しか入っていないのですから、数字が重複することはありません。

    for(i2=1;i2<10;i2++){
      a[0][1]=i2;
では

が入力対象になります。はじめに1が入りますので、

ここで、
      if(a[0][1]!=a[0][0]){   
の検査を受けます。残念ながら、重複していますので 

      if(a[0][1]!=a[0][0]){
        for(i3=1;i3<10;i3++){
              ・
              ・
              ・
          }
        }

      }
の部分は実行されず、i2++が実行され
    for(i2=1;i2<10;i2++){
      a[0][1]=i2;

によって、

となり、重複検査
      if(a[0][1]!=a[0][0]){   
をクリアして、今度は

      if(a[0][1]!=a[0][0]){
        for(i3=1;i3<10;i3++){
              ・
              ・
              ・
          }
        }

      }
の部分が実行されることになります。


第4話へ 第6話へ

戻る

C言語講義第1部へ
VB講義へ
VB講義基礎へ

vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)