マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第4章 if文(もしもボックス))
第12話 データ交換プログラム

(
データ交換プログラム
a = 2 b = 8
データ交換
a = 8 b = 2
)
を実現するコード例
#include<iostream>//インクルードファイルiostreamの読み込み
#include<conio.h>//while(!_kbhit());を使うためのお呪い
#include<string> //文字列変数を使えるようにするために組み込む
#include <iomanip> //setprecisionを使えるように組み込む
#include <cmath>//powなどを使うときに必要
#include <ctime>//time()(←現時刻発生する関数)を使うために必要
using namespace std;//coutを使うときに必要なお呪い
void データ交換();//二つのデータを交換する
int main() {//私は社長だ。
cout << "データ交換プログラム" << endl;
データ交換();//二つのデータを交換する
while (!_kbhit());//待機させるための命令
return(0);//int main()終わるためのお呪い
}
void データ交換() {
//二つのデータを交換する
int a, b;//整数型の変数を二つ用意
a = 1 + rand() % 10;
b = 1 + rand() % 10;
cout << "a = " << a << " b = "
<< b << endl;
cout << "データ交換" << endl;
int 受け皿;//データの一つを一時預かる変数
受け皿 = a;
a = b;
b = 受け皿;
cout << "a = " << a << " b = "
<< b << endl;
}
おそらく
int 受け皿;//データの一つを一時預かる変数
受け皿 = a;
a = b;
b = 受け皿;
の部分を
a = b;
b = a;
とやってしまった方が多いのではないでしょうか。
でもこれでは

(
データ交換プログラム
a = 2 b = 8
データ交換
a = 8 b = 8
)
となってしまいます。
a = b;
は等式ではないと前に説明しました。
左辺の a はデータを入れる箱そのものでした。
右辺の b は変数名が b という箱を意味しません。
ではなんですか。
答えは箱 b に入っている値です。

をみれば 8 であることがわかります。
つまり、
a = b;
は
a = 8;
と同じです。
この時点で a のデータは b のデータに置き換わっています。
すると次の行の
b = a;
は何を意味しますか。
同じ a であっても右辺のときは箱そのものではなく箱に入っている値です。
ですから
b = a;
は
b = 8;
と同じです。
a = b;
をやった瞬間に箱 a の中身は 8 に置き換わります。
ということはデータ 2 が 8 によって上書きされてしまい、
データ 2 は消滅してしてしまうのです。
それで、a の値を一時的に受け取る 受け皿 という変数が必要になるわけです。
int 受け皿;//データの一つを一時預かる変数
受け皿 = a;
a = b;
b = 受け皿;
をトレースすると
受け皿 = a;
箱 a のデータが 受け皿 という変数に aに入っている値 8 が一時的に預けられます。
次の
a = b;
によって a という箱には 8 が入ります。
最後
b = 受け皿;
によって箱 b に 2 が入りデータの交換が無事終了するわけです。
ですから、データ交換プログラムは初心者には難問であるといえます。
さて、ではいよいよ

(
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
)
という課題に取り組んでいただきます。
2次元配列を使えばこの4次魔方陣の作成という課題は簡単にできますが、
物事は順番にしか説明できません。
2次元配列は初心者には難関なのです。
配列を学ぶには1つの章を設ける必要があります。
そして、配列は次章で学ぶことになっていますから、
ここでは2次元配列を使わないでプログラミングをしていただきます。
でも、初心者にいきなり魔方陣の作成プログラムを組めは、
いくらなんでも無理な課題です。
そこで、ヒントを書いておきます。
まず、次の16個の変数を用意していただきます。
int a00, a01, a02, a03;//1行目の行列の数字を収納する変数
int a10, a11, a12, a13;//2行目の行列の数字を収納する変数
int a20, a21, a22, a23;//3行目の行列の数字を収納する変数
int a30, a31, a32, a33;//4行目の行列の数字を収納する変数
2次元配列であれば
int a[4][4];
[]内の数字をfor文の制御変数(for (int i = 0; i < 4; i++) {であれば i が制御変数)で操れますが、
今用意していただいた a00 などは aij とはできません。
a00ただの名前にすぎませんし、
名前を勝手に変更することはできません。
因みに2次元配列であればa[i][j]とできて、制御変数で操れるわけですが、
2次元配列は初心者には難しい項目の1つですから、
とりあえず導入して後で詳しく説明できる代物ではありません。
そこで、a00を使うときには
if (i == 0 && j == 0)a00 = 4 * i + j + 1;
といった工夫が必要になります。
これと同じことを後15行が必要となります。
以上のヒントを与えても初心者には大変難度の高い取り組みになりますが、
どんな困難にも負けない不屈の精神が必要であることは、
何度申し上げてきました。
特に位置調整に相当苦労されると思いますが、
試行錯誤によって難問を乗り越えてください。
第4章第11話へ 第4章第13話へ
本講義トップへ