第16講 魔方陣汎用的生成プログラムへの挑戦
第5話 魔方陣汎用的自動生成プログラム解説その1
コード再掲
import java.io.*;
class x{
public static int[] x=new int[100];
public static int[] y=new int[100];
public static int[][] m=new int[20][20];
public static int n,cn;
public static void main(String args[]) throws IOException {
BufferedReader a = new BufferedReader(new InputStreamReader(System.in));
System.out.println("何次魔方陣を生成させますか。");
System.out.print ("n=");
n=Integer.parseInt(a.readLine());
cn=0;
z();
f(0);
}
public static void z(){
int i;
for(i=0;i<n*n;i++){
x[i]=i%n;
y[i]=i/n;
}
}
本日の解説部分
まず、
public static int[] x=new int[100];
public static int[] y=new int[100];
public static int[][] m=new int[20][20];
public static int n,cn;
は、クラスメンバー配列とクラスメンバー変数を定義しています。
すべてstaticで修飾されていますので、自クラス内ではグローバルに使えます。
つまり、クラス内のメソッド(関数)から共有して使うことができます。
第15講第7話で説明しましたように、
staticがない場合は自クラス内のメソッド(関数)であっても使う場合は、
インスタンス化(オブジェクト化=実体化=設計図からものへ=雛形から文書へ)が必要です。
staticで修飾されていないときは、変数ないしは配列そのものではなくそれらの雛形です。
つまり、肉体のない魂です。ですから、使う場合には魂を肉化(実体化)してから使う必要があるわけです。
それに対してstaticがついている場合は、自クラス内においては初めから肉体をもった変数または配列そのものです。
自クラス内においては、C++・C言語・VB・VBAのおけるグローバル変数のように使えるのです。
すべてpublicがついていますので、もちろん他クラスの各メソッドからも使うこともできます。
しかし、staticがついている変数(配列)は自クラスから参照する場合は、肉をもった実体ですが、
他クラスから見た場合は、それは肉体のない魂または幽霊ですから、インスタンス化して肉体を与えないと使えません。
class xにおけるstatic変数x
(クラス名とたまたま同じですが、まったく関係がなく変数名です。Javaでは、クラス名と変数名が重なっても問題ありません。)
と他クラスのメソッド(関数)でインスタンス化した変数p.xは出自が同じでも異なる変数です。
適応範囲が、static変数xの場合class xであり、インスタンス変数p.xの場合は他クラスのメソッド内ですから当然です。
public static int[] x=new int[100];
public static int[] y=new int[100];
public static int[][] m=new int[20][20];
public static int n,cn;
はもちろんクラスメンバー変数とクラスメンバー配列にする必要はありません。
main上で定義してインスタンス変数にしてもよいのですが、するとf(0);の形が複雑になりプログラムの構造が見えにくくなりますので、
今回は、クラス変数とクラス配列にしました。
mainのインスタンス変数(各メソッドから定義される変数)にしても、mainはプログラムが走っている間メモリーに常駐していて、
結局はmainのインスタンス変数は、メモリーに常駐するのでメモリーの節約にはなりませんので、
クラスメンバー配列とクラスメンバー変数にしても何の問題もありません。
import java.io.*;
class x{
public static int[] x=new int[100];
public static int[] y=new int[100];
public static int[][] m=new int[20][20];
public static int n,cn;
public static void main(String args[]) throws IOException {
BufferedReader a = new BufferedReader(new InputStreamReader(System.in));
System.out.println("何次魔方陣を生成させますか。");
System.out.print ("n=");
n=Integer.parseInt(a.readLine());
ピンクの部分は、キーボードから値を特込むときに必要でした。
第5講 for文を理解しよう
第3話 キーボードから値を取得する
でも説明してありますが、BufferedReader a = new BufferedReader(new InputStreamReader(System.in));
はコマンドプロンプトの現在の行(Line)にaという名前をつけたという意味です。
ですからa.readLine()はaというライン上にある内容を読み込んで取り入れろという意味になります。
Integer.parseInt()がついている理由は、Javaはコマンドプロンプトのライン上の内容をString型として受け取るので、
それをint型へ変換しているのです。
もし、nがString型の変数であれば必要ないわけですが、nは
public static int n,cn;
int型でした。
本話の最後の解説は、
z();
f(0);
}
public static void z(){
int i;
for(i=0;i<n*n;i++){
x[i]=i%n;
y[i]=i/n;
}
}
の部分です。
ここは第2話 2次元に並んでいるセルに1次元セル番号を割り振る
0 | 1 | 2 | |
0 | 0 | 1 | 2 |
1 | 3 | 4 | 5 |
2 | 6 | 7 | 8 |
で解説したとおり、セル番号に(y、x)座標を割り振っています。
皆さん、頭の中または紙上で再度トレースしてうまく割り振られている様子を確認してください。
トレースがとても重要ですよ。
粘り強くトレースしましょう。
第4話へ 第6話へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第2部
初心者のための
VC++による C言語 入門 C++ 入門 基礎から応用まで第3部