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

第4話 2次元配列を関数に送る!

説明するより実例を見せた方が早いと思いますので、

コードをお見せしますので、コピペ下ください

コード用コード

#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()(←現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

const int n = 8;//具体的な数字を使うのではなく、 n を使うと汎用性のあるプログラムになる!

//fの任務は各対角線部分を点対称移動させることである
void f(int a[n][n]);

int main() {//私は社長だ。

int a[n][n];//2次元配列を定義(用意)した。

  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      a[i][j] = n * i + j + 1;//自然配列を2次元配列に収納

    }

  }

  //自然配列を体裁を整えてコンソール画面に表示する
  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      if (a[i][j] < 10)cout << " ";

      cout << a[i][j] << " ";

    }

    cout << endl;

  }

  f(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  for (int i = 0; i < n; i++) {

    for (int j = 0; j < n; j++) {

      if (a[i][j] < 10)cout << " ";

      cout << a[i][j] << " ";

    }

    cout << endl;

  }

  while (!_kbhit());//待機させるための命令

  return 0;//int main() を終わるためのお呪い

}

//fの任務は対角線部分を点対称移動させることである
void f(int a[n][n]) {

//対角線点対称移動
for (int i = 0; i < n / 2; i++) {

  int u;//交換のための受け皿

  //対角線部分を点対称移動する作業を始める
  u = a[i][i];
  //a[i][i]のデータがa[n - i][n - i]のデータに上書きされる前に
  //uにa[i][i]のデータを保存

  a[i][i] = a[n - 1 - i][n - 1 - i];
  //a[i][i]のデータをa[n - 1 - i][n - 1 - i]のデータで上書き

  a[n - 1 - i][n - 1 - i] = u;
  //a[i][i]の元データでa[n - 1 - i][n - 1 - i]のデータを上書き
  //対角線部分を点対称移動する作業を終了


  //逆対角線部分を点対称移動する作業を始める
  u = a[i][n - 1 - i];
  //a[i][n - 1 - i]のデータがa[n - 1 - i][i]のデータに上書きされる前に
  //uにa[i][n - 1 - i]のデータを保存

  a[i][n - 1 - i] = a[n - 1 - i][i];
  //a[i][n - 1 - i]のデータをa[n - 1 - i][i]のデータで上書き

  a[n - 1 - i][i] = u;
  //a[i][i]の元データでa[n - 1 - i][n - 1 - i]のデータを上書き
  //対角線部分を点対称移動する作業を終了

  }

}

実行画面


1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64

64 2 3 4 5 6 7 57
9 55 11 12 13 14 50 16
17 18 46 20 21 43 23 24
25 26 27 37 36 30 31 32
33 34 35 29 28 38 39 40
41 42 22 44 45 19 47 48
49 15 51 52 53 54 10 56
8 58 59 60 61 62 63 1


解説

2次元配列を送るときには、

  f(x);//2次元配列を各対角線交換関数に送る

とします。

私も最初

  f(x[n][n]);//2次元配列を各対角線交換関数に送る

としてしまいましたが、

送っているのはあくまで金庫の位置情報

すなわち、配列のアドレスの先頭部分です。

  f(x);//2次元配列を各対角線交換関数に送る

のxがアドレスの先頭部分です。

どうしてと思います。

ですが、これは文法で定められたことなので、

そういうものだと受け取ってください。

int型で定義され[n][n]の配列になっていますから、

アドレスの先頭部分だけ知らせれば、

どこからどこまでがa[0][0]の収納場所かがわかります。

同様にしてa[0][1]の収納場所もわかるわけです。

では第5話課題です。

緑の部分を左右に線対称させる任務を持つ

//gの任務は緑部分を上下線対称移動させることである。
void g(int x[n][n]);

を関数を作り緑の部分の上下線対称移動を実現してください。


1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64

64 2 3 4 5 6 7 57
9 55 11 12 13 14 50 16
17 18 46 20 21 43 23 24
25 26 27 37 36 30 31 32
33 34 35 29 28 38 39 40
41 42 22 44 45 19 47 48
49 15 51 52 53 54 10 56
8 58 59 60 61 62 63 1

64 2 59 4 5 62 7 57
9 55 11 52 53 14 50 16
41 18 46 20 21 43 23 48
25 34 27 37 36 30 39 32
33 26 35 29 28 38 31 40
17 42 22 44 45 19 47 24
49 15 51 12 13 54 10 56
8 58 3 60 61 6 63 1







第7章第3話へ 第7章第5話へ

本講義トップへ