マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第8章 ポインタの学習

第7話 緑部分のa[i][j]から1次元ポインタへの変換
 

void g(int a[n][n]) {

  //緑の部分の第1列から第4列までの上下交換開始
  for (int i = 0; i < n / 2; i++) {

    int x = a[i][(2 + i) % (n / 2)];

    int y = a[n - i - 1][(2 + i) % (n / 2)];

    交換係社員(&x, &y);

    a[i][(2 + i) % (n / 2)] = x;

    a[n - i - 1][(2 + i) % (n / 2)] = y;

  }
  //緑の部分の第1列から第4列までの上下交換

  //緑の部分の第5列から第8列までの上下交換開始
  for (int i = 0; i < n / 2; i++) {

    int x = a[i][n - 1 - (2 + i) % (n / 2)];

    int y = a[n - i - 1][n - 1 - (2 + i) % (n / 2)];

    交換係社員(&x, &y);

    a[i][n - 1 - (2 + i) % (n / 2)] = x;

    a[n - i - 1][n - 1 - (2 + i) % (n / 2)] = y;

  }
  //緑の部分の第5列から第8列までの上下交換

}

今話は緑の交換部分です。

アドレス計算は重要です。

この後2次元ポインタで8次魔方陣の作成をやりますが、

1次元でも最後までやり通してほしいのです。

データが横に8個並ぶので

    
a[i][j] → *(a + n * i + j)

です。

文字を数字に具体化する!

具体的な数字を文字に置き換えて抽象化する!

いずれも重要です。

そして、なぜそうなのか考えること、つまり意味を考えることも極めて重要です。

これらを重要視してその上で以下の図による説明を聞いて、

結果を心から心底から理解することが大切なのです。

では、1つ1つ見ていきます。


              a[i][(2 + i) % (n / 2)]

大事なことを繰り返します。塊ごと代入です。

             a[i][(2 + i) % (n / 2)] → *(a + n * i + (2 + i) % (n / 2))

注意事項は+-より×÷が優先され、さらに×÷より % が優先され、()はすべてに優先されるので、

             a[i][(2 + i) % (n / 2)] → *(a + n * i +
((2 + i) % (n / 2)))

と書かなくても大丈夫ですが、事象が正しいということより自分がわかりやすいということが大事ですので、

わかりやすい方を選んでください。

次の対象は

        a[n - i - 1][(2 + i) % (n / 2)]

です。

        a[n - i - 1][(2 + i) % (n / 2)] → *(a + n * (n - i - 1) + (2 + i) % (n / 2))

または
        a[n - i - 1][(2 + i) % (n / 2)] → *(a + n * (n - i - 1) +
((2 + i) % (n / 2)))


次は

        a[i][n - 1 - (2 + i) % (n / 2)]

です。

        a[i][n - 1 - (2 + i) % (n / 2)] → *(a + n * i + n -1 - (2 + i) % (n / 2))

または

        a[i][n - 1 - (2 + i) % (n / 2)] → *(a + n * i + n -1 -
((2 + i) % (n / 2)))

これで緑の変換が終わりました。

明るい紫の変換は次話とします。

第8章第6話へ 第8章第8話へ

本講義トップへ