Category: Develop

3.配列

3章 配列
1.配列とは
 例えば100個のデータが合った場合、これを変数a1,a1,a3・・・a100と設定したのでは大変だから、メモリー上に100個の連続した領域を確保し、何件ものデータを総括的に扱うことのできる方法を配列という。
 配列の添え字は、0からはじまるプログラム言語と、1から始まるプログラムがある。Javaは0からはじまる。COBOLは1。Javaは、配列を入れるための変数を宣言し配列の領域を確保し、確保した領域を宣言した変数に入れるという操作をしなければならない。領域を確保する際はどのくらいの大きさの配列かを指定しなければならないが、配列を入れるための変数を宣言する際にはどのくらいの大きさかは宣言しなくても構わない。
 
2.配列の宣言と初期化
Javaでは、配列を使用する場合に配列の最後を越えてアクセスしていないかどうかをチェックしています。つまり10個の要素しかない配列の11番目にアクセスすることはできない。(例外をスローする)
import  java.io.*;

class Test{
    public static void main(String args[ ]){
        
int a[ ] ;
         a =
new int [10];

         // 要素数が10の配列の11番目にアクセスしようとした 
    // 添え字が0から始まるので、11番目は10になる
    System.out.println(a[10]);
     }
}

C:\java>javac Test.java                                       ← コンパイルは正常 

C:\java>java Test
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at Test.main(Test.java:9)
                                                                       ↑ 実行時にエラーが出る
C:\java>

配列の領域を確保するのと同時に、初期化を行うこともできる。
  int raikyaku[ ] = { 1,2,3,4,5 } ;

この場合、配列の大きさは、初期化の際の要素数になる。つまり、上記の例では要素数が5つの配列になる。

実際の配列領域を入れるための変数があるという事は、配列領域を別の変数に代入することもできる。
import java.io.*; 

class Test{
    
public static void main (String args[ ]){
         
int a[ ] = {  1,2,3,4,5 } ;
          int b[ ] ;

          b = a ;

          System.out.println(b[3]);

          a[3] = 100;

          System.out.println(b[3]);
    }
}

C:\java>javac Test.java

C:\java>java Test
4
100

C:\java>

Javaでは変数を用いて配列の領域確保を行うことができる。すなわち、動的に配列のサイズを変化させることができる。
import java.io.*;

class Test{
    public static void main(String args[ ]) {
         int i = 200;
         int a[ ] = new int [i];
    }
}

 
3.配列の使用法 
 配列は添え字を用いることで、その要素の読み書きをする。添え字は変数であっても構わない。
 「int型」の要素数10個の配列を作り、これに1から10の数字を代入する例
// 添え字に変数を使わない例
import  java.io.*;

class Test{
      public static void main (String args[ ]) {
           int a[ ] = new int [10];

           a[0] = 1;
           a[0] = 2;
           a[0] = 3;
           a[0] = 4;
           a[0] = 5;
           a[0] = 6;
           a[0] = 7;
           a[0] = 8;
           a[0] = 9;
           a[0] = 10;
     }
}

// 添え字に変数を使った例
import  java.io.*; 
 
class Test{ 
    public static void main(String args[ ]){
        int a[ ] = new int [10];
       int i;         // 添え字
 
   for( i = 0 ; i < 10 ; i++ )
           a[i] = i+1;
  }
}

  
[配列の変数.length]とすることで、配列の大きさを取得できる。
import  java.io.*; 
 
class Test{ 
    public static void main(String args[ ]) {
        int a[ ] = new int [10];
       int i;         // 添え字
 
   for( i = 0 ; i < a.length ; i++ )
           a[i] = i+1;
  }
}

  
配列のコピー
import  java.io.*; 
 
class Test{ 
    public static void main(String args[ ]){
        int a[ ] = { 5,4,3,2,1 };
        int b[ ] = { 1,2,3,4,5 };

         // 配列の表示
    showArray(a);
    showArray(b);

         // 配列のコピー
         // 配列aの10番目からa.length個(すべて)を配列bの0番目へとコピーする
    System.arraycopy(a, 0, b, 0, a.length); 
 
         // 配列の表示 
    showArray(a);
    showArray(b);
   }
 
   // 配列を表示するメソッド 
    public static void showArray(  int a[ ] ){
    for( int i = 0 ; i < a.length ; i++ ) 
        System.out.print(i+":"+a[i]+"\t");
   System.out.println("");
   }
}

  

C:\java>javac Test.java

C:\java>java Test
0:5     1:4     2:3     3:2      4:1  ←コピー前のa
0:1     1:2     2:3     3:4      4:5  ←コピー前のb
0:5     1:4     2:3     3:2      4:1  ←コピー前のa
0:5     1:4     2:3     3:2      4:1  ←コピー前のb(コピーされている)

C:\java>

 
5.2次元配列と多次元配列
 2次元配列とは、配列の配列である。イメージ的には表。1次元配列と同様に、配列を入れるための変数を宣言し、配列領域を確保して変数に代入するとういう手続きが必要になる。
  int a[ ][ ];                           // 2次元配列をいれるための変数
  a = new int[3][4];                // 3行4列の2次元配列領域を確保

  a[0][0] = 10;
  a[0][1] = 20;
  a[1][2] = 30;
  a[2][3] = 40;

  int a[ ][ ] = new int[3][4];     // 変数宣言と領域確保を同時にしてもよい

  a[0][0] = 10;
  a[0][1] = 20;
  a[1][2] = 30;
  a[2][3] = 40;
 

10 20 ? ?  
? ? 30 ?
? ? ? 40
    int a[ ][ ] = { { 0, 1, 2, 3 } , { 4, 5, 6, 7 } , { 8, 9, 10, 11 }  };
    int b[ ][ ] = { { 0            } , { 4, 5,       } , { 8, 9, 10, 11 }  };
    int c[ ][ ] = { { 0, 1, 2, 3 } , { 4, 5, 6, 7 } , {                  }  };
 
配列a(3行4列)   配列b(3行)   配列c(3行)  
0 1 2 3 0 X X X 0 1 2 3 X = 存在しない領域
4 5 6 7 4 5 X X 4 5 6 7
8 9 10 11 8 9 10 11 X X X X
 

4.クラスの基礎

4章 クラスの基礎
1.クラスとは
 クラスとは、プログラムをある実世界のモノとして考え、それに必要なデータと働き(メソッド)をひとまとめにしたものである。
 クラスは、「System」クラスと「String」クラスがある。Systemクラスはディスプレイに文字を表示させるための標準出力、標準エラー出力に表示させるために用いてきた。「String」クラスは、文字列を担うクラスである。そのでーた(クラス変数)として文字列そのものを持ち、メソッドとして検索したり、つなげたり、部分文字列を抽出したりといったメソッドが定義されている。
 このように、データとそれらを扱うメソッドを作成したクラスは、そのクラスの内部がどのようになっているのか知らなくても、部品のように使用することができる。つまり、SystemクラスやStringクラスの中身を知らなくても(ソースコードを見なくても)、そのクラスを使って、プログラムを作ることができる。さらに、その部品(クラス)は他のプログラムを作成するときにも使いまわしができる。
 
2.クラスの作成
 ここでは、Mypoingクラスを作ってみる。Mypointクラスは座標を担うクラスで、メンバー変数として、X座標とY座標を持つ。メソッドとしては、2点間の座標を求めるメソッドと、ディスプレイに表示するためにString型に変換するメソッドを持つ。
 クラスを作成する場合、基本的に1ファイルに1クラスでファイル名はクラス名と同じにする必要がある。
MyPoint.java

class MyPoint{
    double m_x;
    double m_y;

    // 文字列に変換する
    public String toString(){
         return "X:"+m_x+"  Y:"+m_y;
    }

    // 距離を計算する
    public double calcDistance(MyPoint pnt){
          // Mathクラスは数学関係を担うクラス
          // Math.pow累乗を計算するメソッド
          // Math.sqrtはルートを計算するメソッド
     return Math.sqrt(Math.pow((m_x – pnt.m_x), 2) + Math.pow((m_y – pnt.m_y), 2));
    }
}

 

Test.java

import  java.io.*;
   
class  Test{
    public static void main(String args[ ] ){
         int n;
         MyPoint pnt1 = new MyPoint( );                 // (1)
         MyPoint pnt2 = new MyPoint( );                 // (1)

         pnt1.m_x = 10;
         pnt1.m_y = 20;

         pnt2.m_x = 50;
         pnt2.m_y = -20;

    System.out.println("pnt1 " + pnt1.toString( ));
    System.out.println("pnt1 " + pnt1.toString( ));
    System.out.println("距離:" + pnt1.calcDistance(pnt2));
    }
}
 

C:\java>javac Test.java

C:\java>javac Test
pnt1 X:10.0   Y:20.0
pnt2 X:50.0   Y:-20.0

距離:56.568542494923804

C:\java>

 クラスを定義した(MyPoint.javaを作成しただけ)では、クラスを使えるようにはならない。
Test.javaのように「new」をしてはじめてクラスを使えるようになる。このnewをインスタンスを作るまたはオブジェクトを作ると言う。
newを何個も行うことで、インスタンスをたくさん作ることができる。これらのインスタンスは別のものであるが、変数の値もインスタンスが異なれば違う値を保持する。この場合、pnt1のメンバー変数のm_xとpnt2のm_xは違う値を保持している。それはこのためである。
 
      __pnt1__    __pnt2__   
    |_____m_x = 10  |    |   m_x = 50   |
       |     m_y = 20  |    |   m_y = -20 |
        ↑          ↑

        |          |
        |          |

両者は違うメモリーに格納される。このため、別のものとなる。

 
3.コンストラクタ
 クラスには、インスタンスが作られた時に一度だけ実行される「コンストラクタ」というものがある。一般にコンストラクタにはそのクラスインスタンスを初期化するために使用される。
MyPoint.java

class  MyPoint{
    double m_x;
    double m_y;

    // コンストラクタ
    public Mypoint( ){
         System.out.println("コンストラクタ1が呼ばれました");
         m_x = 10;
         m_y = 20;
   }

    // コンストラクタ2
    public Mypoint(double x, double y ){
         System.out.println("コンストラクタ2が呼ばれました");
         m_x = x;
         m_y = y;
   }
 
    // 文字列に変換する
    public double clacDistance(MyPoint pnt ){
       // Matchクラスは数字関係を担うクラス
       // Match.pow累乗を計算するメソッド
       // Match.sqrtはルートを計算するメソッド
       return Math.sqrt(Math.pow((m_x – pnt.m_x),2) + Math.pow((m_y – pnt.m_y), 2));
   }
}
 

Test.java

import  java.io.*;

    public static void main(String args[ ] ) {
    int n;
         MyPoint pnt1 = new MyPoint();
         MyPoint pnt2 = new MyPoint(50, -20);

//     pnt1.m_x = 10;
//     pnt1.m_y = 20;

//     pnt2.m_x = 50;
//     pnt2.m_y = -20;

         System.out.println("pnt1 " + pnt1.toString());
         System.out.println("pnt2 " + pnt2.toString());
         System.out.println("距離:" + pnt1.calcDistance(pnt2));
   }
}
 

C:\java>javac Test.java

C:\java>javac Test
コンストラクタ1が呼ばれました
コンストラクタ2が呼ばれました

pnt1 X:10.0   Y:20.0
pnt2 X:50.0   Y:-20.0
距離:56.5685424923804

C:\java>

 

5.演算子

5章 演算子
1.演算子の種類
 ●演算子
   ○算術演算子
    ・四則演算子         +,-,*,/,%
    ・符号変換           -
   ○比較演算子
    ・大小比較           <,>,<=,>=
    ・等価、非等価         ==,!=
   ○論理演算子
    ・論理否定           !
    ・論理積            &&
    ・論理和            ∥
   ○インクリメント演算子     ++
   ○デクリメント演算子      –
   ○ビット演算子
    ・論理積            &
    ・論理和            |
    ・排他的論理和        ^
    ・論理否定(1の補数)    ~
   ○シフト演算子
    ・左シフト            <<
    ・右シフト            >>
   ○代入演算子
    ・代入              =
    ・四則演算           +=,-=,*=,/=,%=
    ・シフト演算           <<=,>>=,>>>=
    ・ビット演算           &=,|=,^=
   ○cast演算子           (型) 例えば、(int),(char)など
   ○順次演算子            ,
   ○条件演算子(三項演算子)   ? : 
   ○instanceof演算子       instanceof
 
2.インクリメント演算子、デクリメント演算子
   int i;
       for( i = 0 ; i < 10 ; i = i +1 )
             System.out.println(i);
上記の例のように、今まで変数を1増やす場合「 i = i + 1 」と書いてきた。しかし「変数を1増やす」という作業は頻繁に行われるため、特別の演算子が用意されている。上の例は、その演算子を使用すると下記のようになる。
   int i;
       for( i = 0 ; i < 10 ; i++ )
             System.out.println(i);
この「++」がインクリメント演算子である。逆に「変数の値を1減らす」演算子はデクリメント演算子といい「――」である。
この演算子は「i++」のように変数の後に書くことも、「++i」のように変数の前に書くこともできる。しかし「j=i++」のように式の中に組み込むと、変数の前に書いた場合と、変数の後に書いた場合の動作が異なる。変数の前に書いた場合は、式を評価する前にインクリメントする。逆に変数の後に書いた場合は、式を評価した後にインクリメントする。
import java.io.*;

    public static void main( String args[ ] ){
        int a,b;
        a = 3;
        b = ++a;

        System.out.println("a=" + a + " b=" + b);
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a, b;
        a = 3;
        b = a++;

        System.out.println("a=" + a + " b=" + b);
    }
}

D:\java>javac Test.java

D:\java>java Test

a=4 b=4

D:\java>

D:\java>javac Test.java

D:\java>java Test

a=4 b=4

D:\java>

 一つの式の中に同じ変数に対するインクリメント演算子が複数あってはならないということである。もちろんデクリメント演算子も同じ注意がある。
例えば、「b=a++ +a++」というのはダメ。予期しない結果になることが多く、バグを招き兼ねない。「printf("%d %d\n",++a,++a);」というのもダメ。
import java.io.*;

class Test{
    public static void main(String args[ ] ){
       int a, b;
       a = 0;
       b = ++a + ++a;

        System.out.println("a=" + a + " b=" + b);
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a, b;
        a = 0;
        b = a++ + a++;

        System.out.println("a=" + a + " b=" + b);
    }
}

D:\java>javac Test.java

D:\java>java Test

a=2 b=3

D:\java>

D:\java>javac Test.java

D:\java>java Test

a=2 b=1

D:\java>

 
3.複合代入演算子
 複合代入演算子とは、演算と代入を一つの演算子にまとめたものである。インクリメント演算子やデクリメント演算子も複合代入演算子の一種ということができる。
複合代入演算子 使用例 意味 普通の演算子
+= a+=b; aにbを加えた値をaに代入する a-a+b
-= a-=b; aからbを引いた値をaに代入する a=a-b
*= a*-b; aとbを乗じた値をaに代入する a=a*b
/= a/=b; a÷bをaに代入する a=a/b
%= a%=b; a÷bの余りをaに代入する a=a%b
>>>= a>>>=b; aをbビット右にシフトした値をaに代入する(符号なし整数、ビット列) a-a>>b
>>= a>>=b; aをbビット右にシフトした値をaに代入する(符号付き整数) a=a>>b
<<= a<<=b; aをbビット左にシフトした値をaに代入する a=a<<b
&= a&=b; aとbの論理積をaに代入する a=a&b
|= a|=b; aとbの論理和をaに代入する a=a|b
^= a^=b; aとbの排他的論理和をaに代入する a=a^b
         
4.ビット演算子
演算子 意味 使用法
& ビット積(AND) a=b&c; bとcの各ビット毎の論理積をとり、その結果をaに代入する
| ビット和(OR) a=b|c; bとcの各ビット毎の論理和をとり、その結果をaに代入する
^ ビット排他的論理和(XOR) a=b^c; bとcの各ビット毎の排他的論理和をとり、その結果をaに代入する
~ ビット否定(NOT) a=~b; bの各ビットを反転しその結果をaに代入する
AND      
b c 結果(a)  
0 0 0  
0 1 0  
1 0 0  
1 1 1  
AND演算はビットを0でマスクするのに使用する。マスクとはあるビットを0もしくは1に変えること。例えば、奇数か偶数かを調べるためには、最下位を残して0でマスクする。その値が1なら奇数、0なら偶数ということになる。
import java.io.*;

class Test{
     public static void main(String args[ ]) {
         int i = readNumber( );

         if ( i = & 1 == 1 ) {
              System.out.pringtln("奇数です");
    }
         else{
              System.out.println("偶数です");
    }
  }

    // キーボードから数字を入力するメソッド
  public static int readNumber( ){
        byte b[ ] = byte [100];

        try{
              System.out.println.in.read(b);
            return Integer.parseInt((new String( (b).trim( ) ).trim( ) );
        }catch(Exception e) {
                return 0;  
          }
     }
}

OR      
b c 結果(a)  
0 0 0  
0 1 1  
1 0 1  
1 1 1  
OR演算はビットを1でマスクするのに使用する。
XOR      
b c 結果(a)  
0 0 0  
0 1 1  
1 0 1  
1 1 0  
XOR演算はビットを必要な部分だけ反転させるのに使用する。
NOT      
b 結果(a)    
0 1    
1 0    
NOT演算は1の補数を表す。1の補数とはすべてのビットを反転する。
 
5.シフト演算子
 シフト演算とは論理演算と同じようにビットを操作する命令である。具体的には、2進数の各ビットをずらすことである。右にずらすか左にずらすか、符号なしか、符号付きかによって3種類の演算子が用意されている。
演算子  意味 使用法
<< 左にシフト a = b << c bを左にcビットずらす
>>  右にシフト a = b >> c bを右にcビットずらす(符号付き)
>>> 右にシフト a = b >> c bを右にcビットずらす(符号なし)
0000 0001 = 1        1111 1111 = -1
   ↓                         ↓
0000 0010 = 2        1111 1110 = -2
       ↓            ↓
0000 0100 = 4           1111 1100 = -4

      整数          負数
このように左にずらすと、その値は2倍になる。
 
6.キャスト演算子
 キャストとは「型変換」のこと。下の例のように代入元と代入先の変数の型が異なる場合、型変換を行う必要がある。一般に「byte」型から「int」型への変換など、小さい入れ物から大きな入れ物へは自動的にキャストされる。これを「暗黙の型変換」という。
   int    i = 100;
   byte b = 100;

  i = b;            // 暗黙の型変換

 
 逆に大きな入れ物から小さな入れ物へのキャストは、データが失われる可能性があるため、暗黙の型変換は行われずえにエラーが出てしまう。このような場合、コンパイラに「データが失われるかもしれないのは、わかっているよ」と教えなければならない。これを「明示的な型変換」という。
   int    i = 100;
   byte b = 100;

  b = i;            // エラー
  b = (byte)i;  // 明示的なキャスト

 
また、整数と小数(実数)の関係も場合によっては明示的な型変換が必要になる。下の左の例では、明示的な型変換はしていない。右の例では明示的な型変換をしている。キャストしなければ割り算の結果は整数になってしまう。
import java.io.*;

class Test{
    public static void main(String args[ ] ){
       int a = 300;
       float f = a / 7;
 
       System.out.println( f );
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a = 300;
        float f = (float)a /7;

        System.out.println( f );
    }
}

D:\java>javac Test.java

D:\java>java Test
42.0

D:\java>

D:\java>javac Test.java

D:\java>java Test
42.857143

D:\java>

 
7.順次演算子
 カンマで区切られたいくつかの式を左から順に実行する。このカンマのことを順次演算子という。
import java.io.*;

class Test{
      public static void main(String args[ ]){
      int i;
      int j;

      for ( i = 0, j = 10 ; i < 10 ; i++, j– )
            System.out.println(i*j);
      }
}

 

C:\java>javac Test.java

C:\java>java Test
0
9
16
21
24
25
24
21
16
9

C:\java>java