情報学部 菅沼ホーム 目次 索引

使用方法と文法

      1. PHP の特徴とその使用方法
        1. Web ページへの埋め込み
        2. コマンドラインからの使用
      2. データ型
        1. 変数
        2. 使用可能な型
        3. 型変換
      3. 演算子
        1. 算術演算子と代入演算子
          1. [プログラム例 3.1] 簡単なプログラム
        2. 関係演算子,等値演算子,及び,論理演算子
        3. ビット演算子とシフト演算子
        4. その他
      4. 制御文
        1. 分岐
        2. 繰り返し
        3. 外部ファイルの使用
      5. 配列
        1. 1 次元配列
          1. [プログラム例 5.1] 1 次元配列(平均点以下の人数)
        2. 多次元配列
          1. [プログラム例 5.2] 2 次元配列(クラス毎の平均値)
        3. 連想配列
      6. 関数
        1. [プログラム例 6.1] 関数(様々な引数)
        2. [プログラム例 6.2] 関数(関数名)
        3. [プログラム例 6.3] 関数(可変長引数)
      7. クラス
        1. [プログラム例 7.1] クラスと継承
        2. [プログラム例 7.2] スタティックメソッドとプロパティ
        3. [プログラム例 7.3] オブジェクトの複製
      8. 変数の有効範囲(スコープ)
      9. 様々な例題
        1. 数値計算
          1. (プログラム例 A.1 ) 連立線形方程式,逆行列(ガウス・ジョルダン)
          2. (プログラム例 A.2 ) 非線形方程式(二分法)
          3. (プログラム例 A.3 ) 非線形方程式(セカント法)
          4. (プログラム例 A.4 ) 非線形方程式(ニュートン法)
          5. (プログラム例 A.5 ) 代数方程式(ベアストウ)
          6. (プログラム例 A.6 ) 行列の固有値(フレーム法+ベアストウ法)
          7. (プログラム例 A.7 ) 実対称行列の固有値・固有ベクトル(ヤコビ法)
          8. (プログラム例 A.8 ) 最大固有値と固有ベクトル(べき乗法)
          9. (プログラム例 A.9 ) 数値積分(台形則)
          10. (プログラム例 A.10 ) 数値積分(シンプソン則)
          11. (プログラム例 A.11 ) 微分方程式(ルンゲ・クッタ)
          12. (プログラム例 A.12 ) 補間法(ラグランジュ)
          13. (プログラム例 A.13 ) 補間法(スプライン)
          14. (プログラム例 A.14 ) 補間法(ベジエ曲線)
        2. 最適化
          1. (プログラム例 B.1 ) 最適化(線形計画法)
          2. (プログラム例 B.2 ) 最適化(黄金分割法)
          3. (プログラム例 B.3 ) 最適化(多項式近似法)
          4. (プログラム例 B.4 ) 最適化(最急降下法)
          5. (プログラム例 B.5 ) 最適化(共役勾配法)
          6. (プログラム例 B.6 ) 最適化( Newton 法)
          7. (プログラム例 B.7 ) 最適化(準 Newton 法)
          8. (プログラム例 B.8 ) 最適化(シンプレックス法)
          9. (プログラム例 B.9 ) 最適化(動的計画法)
          10. (プログラム例 B.10 ) 分割法( TSP )
          11. (プログラム例 B.11 ) 逐次改善法( TSP )
          12. (プログラム例 B.12 ) 遺伝的アルゴリズム( TSP,関数の最大値)
        3. 確率と統計
          1. (プログラム例 C.1 ) ガンマ関数
          2. (プログラム例 C.2 ) 二項分布
          3. (プログラム例 C.3 ) ポアソン分布
          4. (プログラム例 C.4 ) 一様分布
          5. (プログラム例 C.5 ) 指数分布
          6. (プログラム例 C.6 ) 正規分布
          7. (プログラム例 C.7 ) χ2 分布
          8. (プログラム例 C.8 ) t 分布
          9. (プログラム例 C.9 ) F 分布
          10. (プログラム例 C.10 ) 乱数の発生
        4. モンテカルロ法
          1. (プログラム例 D.1 ) 待ち行列(簡単な例)
          2. (プログラム例 D.2 ) 待ち行列(複雑な例)
        5. 多変量解析
          1. (プログラム例 E.1 ) 最小二乗法
          2. (プログラム例 E.2 ) 重回帰分析
          3. (プログラム例 E.3 ) 正準相関分析
          4. (プログラム例 E.4 ) 主成分分析
          5. (プログラム例 E.5 ) 因子分析
          6. (プログラム例 E.6 ) クラスター分析
          7. (プログラム例 E.7 ) 分散分析
        6. ニューラルネットワーク
          1. (プログラム例 F.1 ) Hopfield ネットワーク
          2. (プログラム例 F.2 ) パーセプトロン学習
          3. (プログラム例 F.3 ) Winner-Take-All
          4. (プログラム例 F.4 ) 競合学習
          5. (プログラム例 F.5 ) バックプロパゲーション
        7. その他
          1. (プログラム例 G.1 ) ファジイ推論
          2. (プログラム例 G.2 ) 伝達関数(ゲインと位相の計算)
          3. (プログラム例 G.3 ) ソートと探索

  ここでは,JavaScript の使用方法とそのに文法(言語仕様)ついて簡単に説明していきます.その文法は,C/C++ とかなり似ていますので,説明を省略することも多いかと思います.「 C/C++ 言語」の関連する箇所を示しておきますので,その箇所を参考にしながら読んでみてください.

  1. PHP の特徴とその使用方法

      PHP は,C/C++ とは異なり,「コンパイラによって,機械語に翻訳してから実行する」という作業は必要ではありません.エディタで作成したプログラムを,そのまま,インタプリータが 1 行ずつ解釈して実行していきます.従って,実行速度としては,どうしても C/C++ よりは遅くなりますが,その点をしのぐ様々な利点を持っています.

      その一つが,Web ページとの結びつきです.PHP は,C/C++のように,単独で動作させることもできますが,Web ページ( HTML ファイル)の中に埋め込んで動作させることも可能です.その点からは,JavaScript と似ていますが,Web ページへの埋め込み方法の違いだけではなく,非常に大きな違いがあります.それは,JavaScript はクライアント上で動作しますが,PHP はサーバ上で動作するといった点です.そのため,Web ページ上に埋め込まれた JavaScript のプログラムを,Web ページのソースコードを表示させることによって見ることが可能ですが,PHP の場合は,PHP によって生成された結果だけが表示され,ソースコードもその表示に対応したものになっていますので,クライアント側からは PHP のプログラムそのものを全く見ることができません.

    1. Web ページへの埋め込み

        ファイル(拡張子は,通常,php とする)内に PHP のプログラムを記述する場合は,
      <?php   // <? でも良い場合がある
      
      	ここに,PHP のプログラム
      ?>				
      のように記述します.PHP では,下の使用例(赤字の部分が PHP)に示すように,HTML 文書自体を PHP プログラムで操作(下の例では,<DD> 要素によって記述された文を繰り返している)したり,また,HTML 文書内に「 <?php echo 文字列 ?> 」の方法で,PHP 内の変数値を埋め込むことも可能です(16 行目参照).なお,PHP の設定によっては,「 <?php 」を「 <? 」,「 <?php echo 」を「 <?= 」と記述する省略形が可能ですが,基本的に避けた方が良いと思います.なお,HTML に関しては,適宜,「 HTML & CSS 」などを参照してください.
      01	<!DOCTYPE HTML>
      02	<HTML>
      03	<HEAD>
      04		<TITLE>PHPの例</TITLE>
      05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
      06		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
      07	</HEAD>
      08	<BODY CLASS="white">
      09		<H1>PHPの例</H1>
      10		<DL>
      11			<DT>嗜好品
      12	<?php
      13		$fr = array ('リンゴ', 'ミカン', 'イチゴ');
      14		for ($i = 0; $i < 3; $i++) {
      15	?>
      16			<DD>果物: <?php echo $fr[$i]."\n" ?>
      17	<?php
      18		}
      19	?>
      20		</DL>
      21	</BODY>
      22	</HTML>
      				
      12,17 行目

        PHP のプログラムが始まることを示します.

      13 行目

        後に述べる配列変数の定義です.今の段階では,変数 $fr には,3 つの値(文字列),'リンゴ', 'ミカン', 'イチゴ' が記憶されている程度に考えてください.

      14 行目

        これも,後に述べる繰り返し文( for 文)の記述です.この文によって,14 行目~ 18 行目が,3 回繰り返されます.

      15,19 行目

        PHP のプログラムが終わることを示します.

      16 行目

        「 <?php 」と「 <? 」に挟まれた変数 $fr[$i] の値(最初は,'リンゴ')と文字列 "\n" は,ピリオドによって結合され,16 行目の最後に出力されます.これが 3 回繰り返されるため,以下に示すような 3 つの文ができあがります.なお,"\n" は,改行を表す特別の文字列であり,表示はされません.
      	<DD>果物: リンゴ
      	<DD>果物: ミカン
      	<DD>果物: イチゴ					
        16 行目に対する表示結果に見るように,JavaScript とは異なり,PHP プログラムはサーバ側で実行され,その結果だけがクライアント側に表示されます(PHP のプログラム自身を見ることは出来ない).したがって,上の例の場合,クライアント側に表示されたページのソースコードは以下のようになります.
      <!DOCTYPE HTML>
      <HTML>
      <HEAD>
      	<TITLE>PHPの例</TITLE>
      	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
      	<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
      </HEAD>
      <BODY CLASS="white">
      	<H1>PHPの例</H1>
      	<DL>
      		<DT>嗜好品
      		<DD>果物: リンゴ
      		<DD>果物: ミカン
      		<DD>果物: イチゴ
      	</DL>
      </BODY>
      </HTML>
      				

    2. コマンドラインからの使用

        コマンドラインから,特定のファイルを実行したり,または,PHP コードを直接実行することが可能です.たとえば,ファイル echo.php の内容が,
      <?php
      	echo "test\n";?>				
      であった場合,コマンドラインから,
      php echo.php				
      と入力すると,echo.php の内容が実行されます.また,コマンドラインから,
      php -r "echo 'test\n';"				
      のよう入力し,PHP コードを直接実行することも可能です.

  2. データ型データ型

    1. 変数

        基本的に型宣言という考え方がありません.つまり,C/C++ や Java のように,変数や関数の戻り値の型を宣言する必要がありません.変数(変数名の最初は必ず「 $ 」でなければない)であれば,その変数に代入されたリテラルの型によって変数の型も決まってしまいます.

    2. 使用可能な型

        PHP で使用できる主要な型や特別な定数は以下に示す通りです.なお,配列やオブジェクトに関しては後ほど述べます.

      1. 数値: 10 進整数,8 進数( 0 で始まる),16 進数( 0x で始まる),浮動小数点数を使用できます.環境によって異なりますが,基本的に,整数は 4 バイト,浮動小数点数は 8 バイトで表現されます.

      2. 論理型boolean ): 値は true,または,false(大文字,小文字を区別しない)になりますが,以下のものはすべて false とみなされます(そのほかはすべて true).

        false,0,0.0,空の文字列,"0",NULL

      3. NULL: 変数が値を持たないことを表します.

      4. 文字列: 文字列は,シングルクォーテーションマーク ' 」,または,ダブルクォーテーションマーク " 」によって囲んで表現されます.以下に示すプログラム例(行番号は,説明のために付加したもの,以下同様)に見るように,シングルクォーテーションマークで囲まれた場合は,その内容がそのまま文字列の内容となりますが,ダブルクォーテーションマークで囲まれた場合はその内部のエスケープシーケンスや変数が評価されます.なお,ピリオド「 . 」によって文字列の結合が可能です.文字列を結合する演算子が + である言語が多いので気をつけてください.
        01	<?php
        02		$x = 123;
        03		echo '変数$xの値は ';  // そのまま出力
        04		echo $x."\n";
        05	//	echo "変数$xの値は ".$x."\n";  // 「$xの値は」を変数名とみなしている(エラー)
        06		echo "変数 $x の値は ".$x."\n";  // スペースで区切って変数を明確にする
        07		echo "変数 ${x} の値は ".$x."\n";  // 「{」と「}」で区切って変数を明確にする
        08		echo "変数 {$x} の値は ".$x."\n";  // 「{」と「}」で区切って変数を明確にする
        09		echo "変数 \$x の値は ".$x."\n";  // 「\」で「$」の機能を無効にする
        10	?>					
        上記のプログラムを実行すると,以下に示すような出力が得られます.echo は,文字列を出力する機能を持った文字列関数の一つです.なお,5 行目は,「$xの値は」が一つの変数とみなされ,かつ,そのような変数が定義されていないためエラーとなります.
        変数$xの値は 123
        変数 123
        変数 123 の値は 123
        変数 123 の値は 123
        変数 123 の値は 123
        変数 $x の値は 123					

          PHP のプログラムが現れましたので,上のプログラム例に基づき,簡単にプログラムの説明を行ってみます.まず,「 // 」は,注釈コメント)とみなされ,PHP によって何も処理が行われません.なお,ここでは使用されていませんが,「 /* 」と「 */ 」で挟んだ部分も注釈とみなされます(複数行に亘っても構わない).

          各文は必ずセミコロン ; 」で終わる必要があります.また,「 \n 」 は,エスケープシーケンスescape sequence )と呼ばれ,改行などの特殊な文字を文字列の中に組み込むために使用されます.9 行目の \$ もエスケープシーケンスです.エスケープシーケンスはバックスラッシュ(\)( Window の場合は円記号)と文字の組み合わせで記述することができ,以下に示すようなものが存在します.
        Seq. 説明 数値
        \n 改行 0x0A
        \r キャリッジリターン 0x0D
        \t 水平タブ 0x09
        \v 垂直タブ 0x0B
        \e エスケープ 0x1B
        \f フォームフィード 0x0C
        \\ バックスラッシュ(\)  
        \$ ドル記号($)  
        \" ダブルクオーテーション  
          文字列を表現する別の方法として,「<<<」を使用したヒアドキュメント構文があります.ヒアドキュメントは,以下の例に示すように,「<<<ヒヤドキュメント名」で始まり,文字列が入り,「ヒヤドキュメント名;」(終端 ID )で終わります.終端 ID は,その行の最初のカラムから始める必要があります.なお,ヒヤドキュメント内の文字列は,ダブルクォーテーションマークで囲まれた場合と同様,その内部のエスケープシーケンスや変数が評価されます.
        <?php
        	$y = 123;
        	$x = <<<hd_e
        	これは,ヒヤドキュメントの例です.
        	変数\$yも評価({$y})
        	されます.\n
        	hd_e;
        	echo $x;
        ?>					
        上記のプログラムによって,以下に示すような結果が得られます.
        これは,ヒヤドキュメントの例です.
        変数$yも評価(123)
        されます.					

    3. 型変換

        PHP で行える型変換キャスト演算子)は,以下に示す通りです.

      • (int), (integer) : 整数へのキャスト
      • (bool), (boolean) : 論理値へのキャスト
      • (float), (double), (real) : floatへのキャスト
      • (string) : 文字列へのキャスト
      • (array) : 配列へのキャスト
      • (object) : オブジェクトへのキャスト

  3. 演算子

        整数同士の除算であっても,C/C++ のように,小数点以下が切り捨てられないことに注意してください.また,C/C++ と同様,演算と代入を同時に行う演算子,例えば,「 x += 10; 」なども使用可能です.

    1. 算術演算子代入演算子算術演算子と代入演算子
      . : 文字列の結合
      + : 加算(配列の場合は要素の和集合,後述)
      - : 減算
      * : 乗算
      / : 除算  小数点以下が常に計算される(以下に示すいずれかの方法で小数点以下切り捨て)
                  ( floor($x / $y),intval($x / $y),(int)($x / $y),(integer)($x / $y) )
      % : 余り  被除数,除数を共に整数型に変換(小数点以下を切り捨て)してから計算
                  ( 7.3 % 2.3 は,1 )
      = : 代入
      ++ : インクリメント演算子( 1 だけ増加)
      -- : デクリメント演算子( 1 だけ減少)				

      プログラム例 3.1] 簡単なプログラム

        ここまでの学習を終えたところで,2 つのデータを与えると,乗算と除算の結果を出力するという簡単なプログラムを書いてみましょう.まず,C/C++ のプログラムによって,その構造を見てみましょう.07 行目~ 08 行目において 2 つのデータを入力し,10 行目~ 11 行目において積と商を計算し,13 行目においてその結果を出力しています.以下に示すプログラムをコンパイルした後,実行し,コマンドプロンプト上から 2 つのデータを入力すれば,コマンドプロンプト上にその結果が表示されるはずです.
      01	#include <stdio.h>
      02	
      03	int main()
      04	{
      05				// データの入力
      06		double x, y;
      07		printf("2つのデータを入力して下さい ");
      08		scanf("%lf %lf", &x, &y);
      09				// 乗算と除算
      10		double mul = x * y;
      11		double div = x / y;
      12				// 結果の出力
      13		printf("乗算=%f 除算=%f\n", mul, div);
      14	
      15		return 0;
      16	}
      				
        PHP においても,その基本は同じです.入出力の方法が,多少,異なっている程度です.なお,今後,プログラム例を示すときに,01,20 行目に対応する部分を省略することも多いかと思いますが,実行するときは必ず入れてください.
      01	<?php
      02		/****************************/
      03		/* 2つのデータの乗算と除算 */
      04		/*      coded by Y.Suganuma */
      05		/****************************/
      06				// データの入力
      07		printf("2つのデータを入力して下さい ");
      08	//	echo "2つのデータを入力して下さい ";   // echo ("2つの...") でも可,以下同様
      09	//	print "2つのデータを入力して下さい ";
      10		$str = trim(fgets(STDIN));
      11		$x   = intval(strtok($str, " "));   // 小数点以下切り捨て
      12		$y   = intval(strtok(" "));   // 小数点以下切り捨て
      13				// 乗算と除算
      14		$mul = $x * $y;
      15		$div = $x / $y;
      16				// 結果の出力
      17		printf("乗算=%d 除算=%d %.3f\n", $mul, $div, $div);
      18		echo "乗算=".$mul." 除算=".$div."\n";
      19		print "乗算=".$mul." 除算=".$div."\n";
      20	?>
      				
      01,20 行目

        PHP プログラムの開始と終了を表す記号です.HTML ファイル内に埋め込まないときにも必ず必要です.

      02 行目~ 05 行目

        プログラム全体に対する注釈コメント)です.PHP の注釈は,この例のように, /* */ と囲んで表現します(複数行にわたっても良い).また,08 行目,09 行目,13 行目,... のように, // から行末までという表現方法も可能です.

        注釈は,プログラムの該当する部分における処理内容を説明するのに使用され,人間がプログラムを読む際,理解しやすくするためのものであり,コンパイラ等によって特別な処理はされません.プログラムを実行するのはコンピュータですが,プログラムを書いたり修正したりするのは人間です.従って,プログラムを書く際に最も注意すべきことは,いかに読み易く,かつ,分かり易いプログラムを書くかという点です.できるだけ多くの注釈を入れておいて下さい.そのことにより,他の人がプログラムを理解しやすくなると共に,プログラム上のエラーも少なくなるはずです.

      07 行目,17 行目

        2 つのデータを入力するためだけであれば,10 行目~ 12 行目だけで十分ですが,その場合,何のメッセージも出力されずキーボードからの入力待ちになってしまうため,一見コンピュータが止まってしまったように感じます.また,多くの入力を要求するような場合は,どの入力を要求しているのかが分かりません.そのため,07 行目の文字列関数 printf が使用されています.また,17 行目は,結果を出力するための printf です.関数は,外部から与えられたデータに基づき,何らかの処理を行いその結果を返します.関数にデータを与える方法の一つが引数です(以下の例において,printf の後ろの括弧内に書かれた部分).なお,これらの文のように,一般的に,PHP における一つの文の終わりにはセミコロン ; 」を付ける必要があります.

        標準入出力装置(一般的には,キーボードとディスプレイ)に対して入出力を行う場合,対象とするものは文字列です.キーボードから入力する場合,たとえ数値であっても,2 進数を使用したコンピュータの内部表現ではなく,例えば 123.45 のように,我々が読むことができる文字列として入力します.しかし,数値データを,入力された文字列としてそのまま記憶したならば,演算等を行うことができません.そのため,入力された文字列をコンピュータ内部で使用する表現方法に変換して記憶してやる必要があります.例えば,123.45 という文字列を数値として扱いたければ,動小数点表現に変換して記憶しておく必要があります.また,ディスプレイに出力する場合も,メモリ(変数)に記憶されているデータを文字列に変換して出力します.さもなければ,我々は,0 と 1 の並びとして出力される結果を自分自身で解釈しなければなりません.printf を使用する場合,C++ における printf と同様,記憶されたデータを文字列に変換する操作を指定してやる必要があります.例えば,以下のようにして使用します.
      	$d_data = -12.34456;
      	$i_data = -12;
      	$c_data = "abc";
      	printf("結果は %f %10.3f %d %5d %s\n", $d_data, $d_data, $i_data, $i_data, $c_data);					
        この結果,まず,"結果は" という文字列が出力されます.printf においては,% で始まる文字列とエスケープシーケンス(後述)以外は,記述された内容がそのまま出力されます.次に,以下の順序で 5 つのデータが出力されます(各データ間には,1 つのスペースが入る).

      1. %f は 浮動小数点型のデータを固定小数点表現の文字列に変換します.なお,1.23x10-3 のような表現方法に対応する 1.23e-03 という方法-浮動小数点表現-も存在します( %e ). % と f の間に何も記述しなければ,全体の桁数や小数点以下の桁数がシステムの標準形式に従います.この場合,$d_data の内容が,システムの標準形式に従って出力されます.

      2. 最初のデータと変換方法は同じですが,この場合は,出力形式を指定しています.$d_data の内容が,小数点以下 3 桁,全体の桁数 10 桁で出力されます(例: △△△-12.345 ).桁数が 10 桁に満たない場合は,左側にスペースが挿入されます.全体の桁数を指定しない場合は,10 の部分を省略しても構いません.

      3. %d は 整数型のデータを文字列に変換します.% と d の間に何も記述しなければ,システムの標準形式に従って出力されます.この場合,$i_data の内容が,システムの標準形式に従って出力されます.

      4. 上の $i_data と変換方法は同じですが,この場合は,出力形式を指定しています.$i_data の内容が,全体の桁数 5 桁で出力されます(例: △△-12 ).桁数が 5 桁に満たない場合は,左側にスペースが挿入されます.

      5. $c_data の内容が文字列として出力されます.なお,1 文字に対する入出力には,「%c」を使用します.

        以上の説明に従うと,07 行目の printf は,入力を促すメッセージを出力するだけです.17 行目では,$mul と $div の値を出力しています.17 行目の " の中の最後の記号 \n も 1 文字を表し,そのまま出力されますが, \ の付いた記号は,エスケープシーケンスといって,特別な働きをします.例えば, \n が出力されると改行が行われます.また,14 行目,15 行目を省略し,17 行目の $mul と $div の代わりに,($x * $y),($x / $y) という式を記述することも可能です.

      08 行目~ 09 行目,18 行目~ 19 行目

        12 行目,17 行目の代わりに,これらの行のいずれかを使用することもできます.echoprint は,文字列を出力するための言語構造です(関数と同じように,括弧で囲んでも構わない).18 行目~ 19 行目においては,$mul や $div の値が自動的に文字列に変換され,それらが . 演算子によって文字列として結合され,その結果が出力されます.

      10 行目

        fgets は,ストリームから 1 行分のデータを読み込むための関数です.ストリームとして SDTIN を指定することによって,標準入力からの入力が可能になります.この行を実行することによって,標準入力装置から入力した 1 行分のデータが,文字列として変数 $str に記憶されます.

        PHP のようなインタプリタでは,C++ のような型宣言を行う必要がありません.変数にデータを代入することによって,その変数の型が決まります.変数 $str には,文字列が代入されていますので,$str の型は文字列型になります.また,この行に示すように,PHP における変数名は,必ず $ から始まります.なお,trim は,文字列の前後の空白や改行を取り除くための関数です.

        この例の場合は,
      	fscanf(STDIN, "%d %d", $x, $y);					
      のように,fscanf(STDIN, ・・・ ) を利用することも可能です.fscanf は,C++ における fscanf と似たような働きをしますので,10 ~ 12 行目のように,strtok を使用してデータを分離する必要はありません.しかし,
      	2.3 4.5 3.4 .....					
      のように,1 行内に記述された可変個のデータを,for 文などの繰り返し文を使用して,
      	for ($i1 = 0; $i1 < $n; $i1++)
      		fscanf(STDIN, "%lf", $x[$i1]);					
      のような方法で入力した場合には,期待したとおりの結果になりませんので注意してください(改行で区切れば,問題なく動作します).

      11 行目~ 12 行目

        $str には,2 つのデータが半角スペースで区切られて入っていますので,それを分離してやる必要があります.それを実行する関数が strtok です.また,intval は,整数型に変換するための関数であり,小数点以下は切り捨てられます.

      14 行目~ 15 行目

        これらの文では,見て明らかなように,乗算と除算の計算をし,結果を変数 $mul と $div に代入しています.変数 $x,及び,$y に対しては,それらの値が参照されているだけですので,11 行目~ 12 行目で記憶された値がそのまま保たれています.入力した値,または,乗算した結果が int で表現可能な値より大きくならない,さらに,2 番目( y )の値として 0 を入力しない( 0 で割ることになる)ようにしてください.

        このプログラムを実行し,8 と 3 を,
      2つのデータを入力して下さい 8 3					
      のように入力すると(下線部が入力する部分),以下のような結果が得られます.整数型同士の除算であっても,小数点以下まで計算されることに注意してください.ただし,17 行目に対応する出力(出力の 1 行目)から明らかなように,%d を使用して出力すると小数点以下が切り捨てられます.
      乗算=24 除算=2 2.667
      乗算=24 除算=2.6666666666667
      乗算=24 除算=2.6666666666667					

    2. 関係演算子等値演算子,及び,論理演算子関係演算子,等値演算子,及び,論理演算子
      >  より大きい  a > b   式 a の値が式 b の値より大きいとき真
      <  より小さい  a < b   式 a の値が式 b の値より小さいとき真
      >= 以上     a >= b  式 a の値が式 b の値以上のとき真
      <= 以下     a <= b  式 a の値が式 b の値以下のとき真
      == 等しい     a == b  式 a の値と式 b の値が等しいとき真(配列にも使用可)
      === 等しい     a === b  式 a と式 b の型と値が等しいとき真(配列にも使用可)
      !=, <> 等しくない a != b, a <> b  式 a の値と式 b の値が等しくないとき真(配列にも使用可)
      !== 等しくない   a !== b  式 a と式 b の型か値が等しくないとき真(配列にも使用可)
      ||, or 論理和    x || y, x or y  式 x が真か,または,式 y が真のとき真
      &&, and 論理積   x && y, x and y  式 x が真で,かつ,式 y が真のとき真
      xor 排他的論理和  x xor y  式 x,または,式 y のいずれか一方だけが真のとき真
      !  否定        ! x      式 x が偽のとき真				

        等値演算子(等しい,等しくない)は,C/C++ とかなり異なっていますので,簡単に説明しておきます.例えば,2 つの変数,
      $x = 10;
      $y = "10";				
      の内,$x は数値,$y は文字列です.== 演算子で $x と $y を比較すると,「等しい」という結果になります.しかし,=== 演算子を使用すると,変数の型が異なるため,「等しくない」という結果になります.

        配列に対して,C/C++ の場合,個々の要素どうしを比較しなければなりませんが,PHP の場合,例えば,配列変数,
      $a1 = array(1, 2, 3);
      $a2 = array(1, 2, 3);
      $a3 = array(0, 2, 3);				
      に対して,「 $a1 == $a2」,「 $a1 === $a2」のような比較が可能です.この例の場合,$a1 と $a2 は等しく,また,$a1 と $a3 は等しくないという結果になります.ただし,C/C++ においても,STL のコンテナに対しては同じような比較が可能です.

    3. ビット演算子シフト演算子ビット演算子とシフト演算子
      | 論理和      x | y   対応するビットのいずれかが 1 のとき真.
      & 論理積      x & y   対応するビットの双方が 1 のとき真
      ^ 排他的論理和 x ^ y   対応するビットが異なるのとき真
      ~ 1の補数     ~ x      ビット毎に 1 と 0 を反転する
      << 左にシフト   x << 3  3 ビット左にシフト.x を 23 倍することに相当.
      >> 右にシフト   x >> 3  3 ビット右にシフト.x を 23 で割ることに相当.				

    4. その他

      1. new: クラスのインスタンス(オブジェクト)を生成するために使用します(例: $obj = new Example() )

      2. + : PHP では,配列に対して,通常の変数や定数と同じようないくつかの演算子を使用できます.先に述べた等値演算子の場合は,各要素毎の比較が行われます.ここで述べる + 演算子は,例えば,「 $a + $b 」の場合,$b の 要素数が $a の要素数より多かった場合,$a に $b の $a の要素数を超えた部分を付加した配列を返します.なお,print_r は配列を見やすく出力するための関数です.
        					// 配列
        $a1 = array(10, 20, 30);
        $b1 = array(10, 50, 60, 70);
        $c1 = $a1 + $b1;
        $d1 = $b1 + $a1;
        print_r($c1);
        print_r($d1);
        					// 連想配列
        $a2 = array('x'=>100, 'y'=>200, 'z'=>300);
        $b2 = array('x'=>100, 'y'=>2000, 'z'=>3000, 'w'=>4000);
        $c2 = $a2 + $b2;
        $d2 = $b2 + $a2;
        print_r($c2);
        print_r($d2);
        					
        (出力)
        Array
        (
            [0] => 10
            [1] => 20
            [2] => 30
            [3] => 70
        )
        Array
        (
            [0] => 10
            [1] => 50
            [2] => 60
            [3] => 70
        )
        Array
        (
            [x] => 100
            [y] => 200
            [z] => 300
            [w] => 4000
        )
        Array
        (
            [x] => 100
            [y] => 2000
            [z] => 3000
            [w] => 4000
        )
        					

      3. & : リファレンス参照)とは同じ変数の内容を異なった名前で参照することを意味します.PHP では,変数名と変数の内容は異なっている(図の一番左側)ため,同じ内容を異なった複数の名前で参照することが可能になります.下の例では,変数 $a と $b は同じ内容を指しています(図の中央).図の一番右側に示すように,C/C++ のポインタに似ていますが,多少異なっていることが分かると思います(アドレス演算子と間接演算子).なお,unset は,指定した変数の割当を解除するための関数です.

        $a = 10;
        $b = &$a;
        echo "a = $a, b = $b \n";
        $b++;
        echo "a = $a, b = $b \n";
        unset($a);   // unset($b) も可能
        echo "b = $b \n";   // $a に対しては undefined error					
        (出力)
        a = 10, b = 10 
        a = 11, b = 11 
        a = , b = 11 
        a = , b = 12
        					
      4. ` (実行演算子): PHP では,実行演算子,つまり,バッククォート( `` )によってコマンドを囲むことによって,そのコマンドを実行し,その結果を返すことができます.たとえば,
        $a = `ls *`;
        echo $a;					

        というプログラムを実行すると,例えば,以下のような結果が得られます.なお,ls は,LINUX 関連のコマンドであり,カレントディレクトリにあるファイル名を出力します.
        test.cpp
        test.exe
        test.html
        test.php					

  4. 制御文

    1. 分岐分岐

      • if 文
        if (論理式) {
        	文1(複数の文も可)
        }
        else {
        	文2(複数の文も可)
        }					
          この文の実行は以下のようにして行われます.まず,論理式が評価され,その結果が真であれば,文1が実行され,次に,「・・・」以降に書かれた文が実行されます.この場合は,文2は実行されないことになります.また,偽である場合は,文1は実行されず,文2が実行された後,真の場合と同様,「・・・」以降に書かれた文が実行されます.なお,if 文において,真に対応する部分(文1)は必ず必要ですが,偽に対応する部分( else 以下)は,必ずしも必要ありません.

          また,次の例のように,文1や文2の中にも if 文を書くことができます( if 文のネストと呼びます).同様に,その内部に書かれた if 文の中にも,さらに,if 文を書くことも可能です.
        if (論理式1) {
        	・・・・・・
        	if (論理式2) {
        		・・・・・・
        	}
        	else {
        		・・・・・・
        	}
        	・・・・・・
        }
        else {
        	・・・・・・
        }
        					
          プログラムを読み易くするため,if 文内に含まれる文は,次の例のように,何列か段を下げて(字下げを行って)書くようにして下さい.字下げは,プログラムの詳細を見なくても,その構造がわかるようにするためのものです.if 文の場合,条件が満足された場合どこからどこまでが実行されるのかが,一目でわかるように行います.例えば,下の例の場合,a と b が等しい場合,2 行目から 7 行目が実行され,また,等しくない場合,10 行目と 11 行目が実行されることが一目でわかります.また,13 行目と 14 行目は,if 文に関係なく常に実行されることも明確になります.
        01	if (a == b) {
        02		max = y;
        03		min = z;
        04		if (min < 0.0) {
        05			min = 0.0;
        06			a   = b;
        07		}
        08	}
        09	else {
        10		max = s;
        11		min = g;
        12	}
        13	x = 9;
        14	y = 10;
        					
          if の後や else の後に続く文が 1 文だけである場合は,それらを囲む「{」と「}」は必要ありません(もちろん,付けても構いません).ただし,次のプログラム
        if (論理式1) {
        	if (論理式2)
        		文1;
        }
        else
        	文2;					
        を,{ } を記述せず,
        if (論理式1)
        	if (論理式2)
        		文1;
        else
        	文2;					
        のように書くと,if 文
        if (論理式) {
        	文1(複数の文も可)
        }
        else {
        	文2(複数の文も可)
        }					
        を 1 文とみなすため,
        if (論理式1)
        	if (論理式2)
        		文1;
        	else
        		文2;					
        と解釈されてしまいますので気をつけて下さい.なぜなら,コンパイラが,else に対する if は,else に最も近い if と判断するからです.このような紛らわしさを除くためには,多少余分であっても,{ } を付加した方が良いかもしれません.

      • else if 文

          複数の判断を順に実行できるように if 文を多少拡張した文です.ほとんど if 文と同じですので,説明は不要かと思います.
        if (論理式) {
        	文1(複数の文も可)
        }
        else if (論理式) {
        	文2(複数の文も可)
        }
          ・・・
        else {
        	文n(複数の文も可)
        }					

      • switch 文
        switch (式) {
        	[case 定数式1 :]
        		[文1]
        	[case 定数式2 :]
        		[文2]
        	 ・・・・・
        	[default :]
        		[文n]
        }					
          まず,式が評価されます.その値が定数式の値のいずれかに等しければ,それ以降の文が実行されます.もちろん,文 i は,複数の文でも構いません.いずれの定数式の値にも一致しない場合,もし,default キーワードの項があればそれ以降が実行され,そうでなければ,何も実行されず switch 文以降の文が実行されます.

          次のプログラムの断片は,data の値によって,対応する処理を行おうとするものです.プログラムの中に,break 文が使用されていますが,break 文はその文に至った時点で強制的に switch 文を抜け出すための文です.次に述べる繰り返し文の中でもよく使用されます.繰り返し文の中で break 文に合うと,繰り返しを中断し,現在の繰り返しの外に出ます.多重ループになっている場合,全てのループからでるわけではなく,break 文が入っているループだけから外に出ます.下に示すプログラムの断片において,data の値が 1 の場合,

        ( data の値が 1 の時の処理)

        が実行されますが,もし,break 文が全くない場合は,この処理以降がすべて実行されるため,

        ( data の値が 1 の時の処理)
        ( data の値が 2 の時の処理)
        ( data の値がいずれでもない時の処理)

        のすべての処理が実行されてしまいます.
        switch (data) {
        	case 0 :
        		( data の値が 0 の時の処理)
        		break;
        	case 1 :
        		( data の値が 1 の時の処理)
        		break;
        	case 2 :
        		( data の値が 2 の時の処理)
        		break;
        	default :
        		( data の値がいずれでもない時の処理)
        }					

    2. 繰り返し繰り返し

      • for 文
        for (初期設定; 繰り返し条件; 後処理) {
        	文(複数の文も可)
        }
          ・・・					
          for 文に入ると,まず,初期設定が実行されます.初期設定は,通常,for 文の繰り返し回数を制御するため等の初期設定を行う式であり,for 文の最初に 1 回だけ実行されます.次に,繰り返し条件(論理式)の値が評価され,もし真であれば文が実行されます.そして,後処理が実行されます.再び,繰り返し条件が評価され,その値が真である限り,文と後処理の実行が繰り返されます.繰り返し条件の値が偽になると,文と後処理は実行されず,「・・・」以下の文が実行されることになります( for 文の外に出る).for 文において,初期設定と後処理を省略することは可能(「;」は省略できない)ですが,通常,繰り返し条件を省略することはできません(省略すると,無限ループになってしまう).

          for 文と同様な機能を持つ文として,while 文や do while 文があります.while 文,及び,do-while 文の一般形式は以下の通りです.

      • while 文

        while (繰り返し条件) {
        	文(複数の文も可)
        }					

      • do while 文

        do {
        	文(複数の文も可)
        } while (繰り返し条件)					
          while 文では,式(論理式)の値が真である限り,文の実行が繰り返されることになります.while 文と do while 文の違いは,式の評価が,文を実行する最初に行われるか,または,後で行われるかの違いです.do while 文では,式の評価が後で行われるため,do while 文の開始時に式が偽であっても,文が少なくとも 1 回は実行されることになります.

          先に述べた for 文は,while 文を使用して,次のように書くこともできます.どちらの表現方法を使用するかは趣味の問題ですが,問題に応じて,理解しやすいプログラムになると思われる方を使用して下さい.
        初期設定;
        while (繰り返し条件) {
        	文(複数の文も可)
        	後処理;
        }					

          if 文と同様,for 文の中が 1 文だけの場合は,{ } を省略可能です.また,for 文の中に別の for 文を書くこともできます( for 文のネスト).

      • foreach 文

        foreach (配列変数名 as 値を入れる変数名) { 文 }
        foreach (配列変数名 as キーを入れる変数名 => 値を入れる変数名) { 文 }					

          以下の例に示すように,配列に対する反復処理を行います.上に示した書式の通り,値だけを取り出す方法とキーと値を取り出す方法があります.この機能は,C/C++ における「範囲 for 文」と似ていますが,かなり異なった動作をします.なお,foreach は配列のコピーを取り出すため,取り出した要素の値を変更しても元の配列の値は変化しません.
        		// 配列
        $x = array(1, 2, 3);
        echo "配列\n";
        foreach ($x as $value)
        	echo "   値: ".$value."\n";
        foreach ($x as $key => $value)
        	echo "   キー: ".$key.", 値: ".$value."\n";
        		// 連想配列
        echo "連想配列\n";
        $y = array('first'=>10, 'second'=>20, 'last'=>30);
        foreach ($y as $value)
        	echo "   値: ".$value."\n";
        foreach ($y as $key => $value)
        	echo "   キー: ".$key.", 値: ".$value."\n";
        					
        (出力)
        配列
           値: 1
           値: 2
           値: 3
           キー: 0, 値: 1
           キー: 1, 値: 2
           キー: 2, 値: 3
        連想配列
           値: 10
           値: 20
           値: 30
           キー: first, 値: 10
           キー: second, 値: 20
           キー: last, 値: 30
        					

    3. 外部ファイルの使用require()require_once()include()include_once() )(#include

        以下の例に示すように,C++ の「 #include 」に似た処理を行うことが可能です.require,require_once は,スクリプトの実行前に指定されたファイルを読み込み,その行をファイルの内容で置き換え,エラーがあると処理を中止します.また,include,include_once は,スクリプトの実行時に同様の処理を行い,エラーがあると警告メッセージを出力し,処理は継続します.なお,いずれにおいても,once を付加すると,既に読み込まれたファイルを再度読み込むことはしません.
      読み込むファイルの内容:
      
      	require_once('./array.def');
      	foreach ($x as $key => $value)
      		echo "キー: ".$key.", 値: ".$value."\n";
      
      読み込まれるファイル(array.def)の内容:
      
      	$x = array('first'=>1, 'second'=>2, 'last'=>3);				
      (出力)
      キー: first, 値: 1
      キー: second, 値: 2
      キー: last, 値: 3				

  5. 配列配列),(new と delete

    1. 1 次元配列配列

        いくつかのデータを記憶し,それらを個々に参照したいようなとき,全てのデータに異なる名前を付けるといった方法は,データが多くなれば,非現実的です.そのような際に利用されるのが配列です.配列は,複合データ型の一種であり,複数のデータを処理する場合に利用されます.配列を作成するには,以下に示すように,配列関数の一つである array() 関数を利用します.
      01				// 宣言だけ(要素数は 0 )
      02	$x = array();   // array(3) のように要素数を指定することも可
      03	$x[0] = 1;
      04	$x[1] = 2;
      05	$x[]  = 3;
      06	print_r($x);
      07	echo "\n";
      08				// 宣言と初期設定
      09	$y = array(1, 2.3, "abc");
      10	$y[3] = 40;
      11	print_r($y);
      12	echo "\n";
      				
      (出力) 配列を見やすく表示するための関数 print_r を使用
      Array
      (
          [0] => 1
          [1] => 2
          [2] => 3
      )
      
      Array
      (
          [0] => 1
          [1] => 2.3
          [2] => abc
          [3] => 40
      )
      				
        プログラムの 02 行目のように宣言すれば,宣言した時点における要素数は 0 ですが,03 行目~ 05 行目に示すように,利用時に適宜追加可能です.また,09 行目のように宣言すれば,3 つのデータを記憶できる領域が確保され,各要素に記憶される値が 1,2.3,"abc" で初期設定されます.この例に示すように,各要素は,必ずしも,同じデータ型である必要はありません.しかし,間違いの元になる可能性がありますので,配列は,同じデータ型だけで構成するようにした方が良いと思います.上の例に示すように,プログラムの実行時に,変数名と添え字を利用して,$x[0],$x[1],$x[2] のようにして参照・修正・追加等を行うことができると共に(添え字が,0 から始まることに注意),配列関数を利用すれば,さらに複雑な処理が可能です.

        C++ における new 演算子を使用する場合,Java,JavaScript,Python,Ruby などにおいては,配列変数は,データを記憶している領域の先頭を指すポインタとみなすことができます.従って,配列変数 u1 を 配列変数 u2 に代入した場合,u1 と u2 は同じ場所を指すことになり,u1 を介して各要素の値を変更すれば,u2 の対応する要素の値も変化します(逆も同様).しかし,PHP においては,かなり異なっています.例えば,
      $u1 = array(1, "abc", 2);
      $u2 = $u1;
      $u3 = &$u1;   // $u1 の参照				
      の最初の行で,初期設定された配列 $u1 を定義し,次の行において $u1 を $u2 に代入しています.この代入によって,$u1 のすべてのデータが $u2 にコピーされ新しい配列が作成されます.従って,$u2[1] の値を変更しても,$u1 には全く影響を与えません.しかし,3 行目のように参照リファレンス)を利用すると,$u3 は $u1 の別名となり,$u3 の値を変更すれば,対応する $u1 の値も変化します(逆も同様).

      プログラム例 5.1] 1 次元配列(平均点以下の人数) 

        何人かの試験の点数を入力し,平均点以下の人数を求めるプログラムについて考えてみます.平均点以下の人数を求めるためには,全員のデータを入力し,平均値を計算した後,それを各人の点数と比較する必要があります.そのためには,入力した各人の点数をどこかに記憶しておく必要があります.そこで,配列が必要になってきます.

      01	/****************************/
      02	/* 平均点以下の人数         */
      03	/*      coded by Y.Suganuma */
      04	/****************************/
      05			// データの入力
      06	$x = array();
      07	echo "各人の点数を半角スペースで区切って入力して下さい(最後に負のデータ) ";
      08	$str  = trim(fgets(STDIN));
      09	$x[0] = intval(strtok($str, " "));
      10	$k    = 0;
      11	while ($x[$k] >= 0) {
      12		$k++;
      13		$x[$k] = intval(strtok(" "));
      14	}
      15			// 平均点の計算
      16	$mean = 0.0;
      17	for ($i1 = 0; $i1 < $k; $i1++)
      18		$mean += $x[$i1];
      19	$mean /= $k;
      20			// 平均点以下の人数をカウント
      21	$ct = 0;
      22	for ($i1 = 0; $i1 < $k; $i1++) {
      23		if ($x[$i1] <= $mean)
      24			$ct++;
      25	}
      26			// 結果の出力
      27	printf("結果: %d 人\n", $ct);
      				
      08 行目~ 14 行目

        半角スペースで区切ったデータを読み込んだ後( gets ),半角スペースでデータを分離し( strtok ),整数に変換し( intval ),配列の各要素に代入しています( 09,13 行目).ただし,最後に必ず負のデータを入力してください.C/C++ においては,最初に配列のサイズを宣言し,そのサイズ以上のデータを受け入れることができないため,人数に対するデータの入力が必要ですが,PHP の場合は,データ数をカウントする( $k )だけで十分です.

        11 行目は,全てのデータが正であれば,最後に負のデータを入力することなく,
      	while ($x[$k]) {					
      で十分ですが,0 というデータが現れた時点で,入力を終了してしまいます.なお,12 行目に使用されているのは,インクリメント演算子であり,以下に示すいずれかの記述と同等です.
      	$k += 1;
      	$k = $k + 1;					
        全てのデータを,半角スペースではなく,改行で区切った場合は,この部分が以下のように記述できます.もちろん,両者の方法を混在させることも可能ですが,プログラムが多少面倒になります.
      	$str = trim(fgets(STDIN));
      	$k   = 0;
      	while ($str >= 0) {
      		$x[$k] = intval($str);
      		$str   = trim(fgets(STDIN));
      		$k++;
      	}					
        また,改行で区切った場合は,fscanf を使用して,以下のように記述することも可能です.
      	$k = 0;
      	fscanf(STDIN, "%d", $x[$k]);
      	while ($x[$k] >= 0) {
      		$k++;
      		fscanf(STDIN, "%d", $x[$k]);
      	}					
      16 行目~ 19 行目

        平均値を計算しています.11 行目では while 文を使用しましたが,ここでは,for 文を使用しています.いずれも,どちらの方法でも記述できますが,データ数が決まっている場合は,for 文の方が書きやすいのではないでしょうか.なお,18,19 行目は,算術演算子と代入演算子を一緒に記述した表現であり,以下の記述と同等です.
      	$mean = $mean + $x[$i1];
      	$mean = $mean / $k;					

      21 行目~ 25 行目

        平均点以下の人数をカウントしています.10,16 行目も同様ですが,21 行目の初期設定を忘れないでください.

    2. 多次元配列2 次元以上の配列とポインタ

        多次元の配列を扱うことも可能です.例えば,
      $v1 = array(2);
      $v1[0] = array(10, 20, 30);
      $v1[1] = array(40, 50, 60);				
      のように,配列の要素を,さらに配列として定義すれば,2 次元の配列を定義できます.この例では,2 行 3 列の配列になります.2 次元配列 $v1 の i 行 j 列の要素を参照するためには,$v1[i][j] ( i : 0 ~ 1,j : 0 ~ 2 )のように記述します.

        また,1 次元配列の場合と同様,次に示す 1 行目のような記述によって,$v2 も,$v1 と同じ 2 行 3 列の配列になります.さらに,2 行目のように,2 次元配列 $v1 の各行を 1 次元配列として扱うことも可能です.いずれの場合も,1 次元配列の場合と同様,$v2 や $v3 は,$v1 の全体,または,1 行目のすべての値をコピーした全く新しい配列となり,$v2 や $v3 の値を変更しても,$v1 は全く影響を受けません.しかし,3,4 行目のように参照リファレンス)を利用すると,$v4,$v5 は $v1,$v1[0] の別名となり,$v4,$v5 の値を変更すれば,対応する $v1 の値も変化します(逆も同様).
      $v2 = $v1;
      $v3 = $v1[0];
      $v4 = &$v1;
      $v5 = &$v1[0];				

      プログラム例 5.2] 2 次元配列(複数クラスの試験) 

        複数のクラスに対して試験を行ったとします.全体の平均を求めた後,各クラス毎に平均点以下の人数を出力するプログラムです.例えば,2 クラスの場合において,クラス 1 の人数が 3 人,クラス 2 の人数が 2 人の場合,以下に示すような入力を行えば実行できます.
      50 30 100 -1
      20 80 -1
      // 改行だけを入力				

      01	/****************************/
      02	/* 平均点以下の人数         */
      03	/*      coded by Y.Suganuma */
      04	/****************************/
      05			// データの入力と全体平均の計算
      06	echo "クラス毎に,半角スペースで区切り各人の点数を入力してください(最後に負のデータ)\n";
      07	$x    = array();   // データを入れる 2 次元配列
      08	$m    = array();   // 各クラスの人数を入れる 1 次元配列
      09	$str  = trim(fgets(STDIN));   // クラス 1 に対するデータの読み込み
      10	$mm   = 0;   // 全体の人数
      11	$mean = 0;   // 全体の平均
      12	$k1   = 0;   // 行番号
      13	while ($str) {
      14		$k2          = 0;   // 列番号
      15		$x[$k1]      = array();   // $x[$k1] を配列として定義(2 次元配列)
      16		$y           = intval(strtok($str, " "));
      17		$x[$k1][$k2] = $y;
      18		$mean       += $x[$k1][$k2];
      19		while ($y >= 0) {
      20			$k2++;
      21			$y = intval(strtok(" "));
      22			if ($y >= 0) {
      23				$mean       += $y;
      24				$x[$k1][$k2] = $y;
      25			}
      26		}
      27		$m[$k1] = $k2;
      28		$mm    += $k2;
      29		$k1++;
      30		$str = trim(fgets(STDIN));
      31	}
      32	$mean /= $mm;
      33			// 各クラスの平均点以下の人数
      34	for ($i1 = 0; $i1 < $k1; $i1++) {
      35		$ct = 0;
      36		for ($i2 = 0; $i2 < $m[$i1]; $i2++) {
      37			if ($x[$i1][$i2] <= $mean)
      38				$ct++;
      39		}
      40		printf("クラス%d における平均点以下の人数: %d 人\n", ($i1+1), $ct);
      41	}
      				
      07,08 行目

        $x,及び,$m を,配列として定義しています.この時点では,いずれも,1 次元配列となります.

      09 行目

        最初のクラスに対するデータを,文字列として読み込んでいます.次のクラス以降のデータは,13 行目の while 文によって,繰り返し読み込まれます( 13 行目~ 31 行目).

      15 行目

        配列 $x の 要素 $x[$k1] が,配列として定義されます.その結果,2 次元配列が定義されます.

      16 行目~ 26 行目

        変数 $str に記憶されている各人の点数データを,半角スペースで分離し,2 次元配列の要素 $x[$k1][$k2] に記憶しています.

      27 行目

        クラスの人数を保存しています.

      29,30 行目

        次の行に対するデータを読み込んでいます.

    3. 連想配列map クラス

        連想配列を使用することも可能です.連想配列は,以下の例に示すように,キーと値のペアで構成されます.この例,及び,繰り返しの中の foreach 文に対する例からも明らかなように,PHP においては,通常の配列と連想配列に大きな差は無いようです.つまり,通常配列における $x[0],$x[1] などは,キーが 0,1 である連想配列として処理されているようです.
      $z = array(600, 'first'=>100, 'second'=>200, 400);
      $z[]       = 500;
      $z['last'] = 300;
      print_r($z);
      $z[1]       = 4000;
      $z['first'] = 1000;
      print_r($z);				
      (出力)
      Array
      (
          [0] => 600
          [first] => 100
          [second] => 200
          [1] => 400
          [2] => 500
          [last] => 300
      )
      Array
      (
          [0] => 600
          [first] => 1000
          [second] => 200
          [1] => 4000
          [2] => 500
          [last] => 300
      )
      				

  6. 関数簡単な関数),(配列),(参照渡し

      関数は,何らかの処理を行い,その結果を返しますが,処理を行うためには外部からの情報を必要とする場合があります.ここで,引数とは,関数を呼び出した側と関数との間で,情報の受け渡しに使用される変数や定数のことです.また,関数は,計算した結果を関数を呼び出した側に戻したい場合がありますが,その際は,以下にあげるプログラム例に示すように,return 文を使用します.関数に対する一般的記述方法は,以下のようになります.

    function 関数名 (引数, ・・・) {
    	処理
    }			

      関数の引数としては,以下の例に示すように,参照渡しデフォルト引数を使用することも可能です.さらに,可変長引数もサポートしています.

      配列を引数とする場合には注意が必要です,C/C++,Java,JavaScript,Python,Ruby などにおいては,配列変数はポインタとみなされますので,配列を関数の引数とした場合,ポインタがコピーされて渡されるため,関数内で配列の要素を変更すれば,関数を呼んだ側の対応する要素の値も変化します.しかし,PHP の場合は,配列に含まれる要素全体がコピーされて渡されるため,関数内において配列の要素の値を変更しても,関数を呼んだ側の配列はその影響を受けません.関数の呼んだ側における配列の値も変更したい場合は,参照渡しをする必要があります.ただし,次の節で述べるクラスのオブジェクトの場合は,そのアドレスが渡されるとみなされますので,関数内における変更が関数を呼んだ側に反映される点に注意してください.

    プログラム例 6.1] 関数(様々な引数) 

      このプログラムでは,3 つの値(一つはデフォルト引数),配列,及び,クラスのオブジェクトを引数として渡しています.クラスに関しては,次章を参照してください.

    01	/****************************/
    02	/* 関数(様々な引数)       */
    03	/*      coded by Y.Suganuma */
    04	/****************************/
    05				// クラス Complex
    06	class Complex
    07	{
    08		public $x;
    09		public $y;
    10		function __construct($x1, $y1) {   // コンストラクタ
    11			$this->x = $x1;
    12			$this->y = $y1;
    13		}
    14	}
    15				// 関数 func
    16	function func($x1, &$x2, $y1, &$y2, $z1, $x3 = 10)
    17	{
    18		$x1   += 10;
    19		$x2   += 10;
    20		$y1[0] = 100;
    21		$y2[0] = 100;
    22		$z1->x = 1000;
    23		return ($x1 + $x2 + $x3);
    24	}
    25	
    26	$a1 = 1;
    27	$a2 = 2;
    28	$b1 = array(10, 20);
    29	$b2 = array(10, 20);
    30	$c1 = new Complex(1, 2);
    31	
    32	print "関数を呼ぶ前\n";
    33	printf("\$a1 %d \$a2 %d \$c1 %d\n", $a1, $a2, $c1->x);
    34	print_r($b1);
    35	print_r($b2);
    36	
    37	$d = func($a1, $a2, $b1, $b2, $c1);
    38	
    39	print "関数を呼んだ後\n";
    40	printf("\$a1 %d \$a2 %d \$c1 %d \$d %d\n", $a1, $a2, $c1->x, $d);
    41	print_r($b1);
    42	print_r($b2);
    			
    06 行目~ 14 行目

      クラス Complex の定義です.

    16 行目~ 24 行目

      $x1(整数,26 行目の a1 に対応), $x2(整数の参照渡し,27 行目の a2 に対応), $x3(デフォルト値を設定した整数,37 行目で引数を省略),$y1(配列,28 行目の b1 に対応), $y2(配列の参照渡し,29 行目の b2 に対応), $z1( Complex クラスのオブジェクト,30 行目の c1 に対応)を引数とした関数 func の定義です.18 行目では $x1 の値,19 行目では $x2 の値,20 行目では配列 $y1 の値,21 行目では配列 $y2 の値,また,22 行目では Complex クラスのオブジェクト z1 の値を変更しています.

    28,29 行目

      配列変数 $b1,$b2 を定義しています( 10 と 20 で初期設定).

    30 行目

      Complex クラスのオブジェクト $c1 を生成しています( 1 と 2 で初期設定).

    32 行目~ 35 行目

      関数 func を呼ぶ前の変数 $a1, $a2, $c1,$b1,$b2 を出力しています.設定したとおりの値が出力されています.

    37 行目

      5 つの変数を引数として,関数 func を呼んでいます.6 番目の変数は省略しています.

    39 行目~ 42 行目

      関数 func を呼んだ後の変数 $a1, $a2, $c1,$b1,$b2,及び,計算結果 $r を出力しています.関数を呼ぶ際,引数は,その値がコピーされて関数に渡されます.上の例では,37 行目において,各変数の値がコピーされ,16 行目の各変数に渡されます.従って,関数内において,$a1 や $b1 の値を変更( 18,20 行目)しても各変数の値は変化しません.しかし,$a2 や $b2 のように,参照渡しをすることで,関数内での変更が反映されます.しかし,変数 $c1 に関しては,参照渡しをしていないにもかかわらず,その値が変化しています.これは,C/C++ におけるアドレスを引数とした場合に相当し,関数内においてオブジェクトの値を変更すれば,関数を呼んだ側におけるオブジェクトの値も変化します.PHP は,なぜ,クラスのオブジェクトに限ってこのような仕様にしたのでしょうか.
    (出力)
    関数を呼ぶ前
    $a1 1 $a2 2 $c1 1
    Array
    (
        [0] => 10
        [1] => 20
    )
    Array
    (
        [0] => 10
        [1] => 20
    )
    関数を呼んだ後
    $a1 1 $a2 12 $c1 1000 $d 33
    Array
    (
        [0] => 10
        [1] => 20
    )
    Array
    (
        [0] => 100
        [1] => 20
    )
    			

    プログラム例 6.2] 関数(関数名) 

      関数名を文字列として他の変数に代入すれば,その変数を関数として使用可能です.同様に,関数名を文字列として,関数の引数とすることも可能です.

    01	/****************************/
    02	/* 関数(関数名)           */
    03	/*      coded by Y.Suganuma */
    04	/****************************/
    05	
    06	function add($s1, $s2) {
    07		$s = $s1 + $s2;
    08		return $s;
    09	}
    10	
    11	function sub($s1, $s2) {
    12		$s = $s1 - $s2;
    13		return $s;
    14	}
    15	
    16	function add_sub($fun, $s1, $s2) {
    17		$s = $fun($s1, $s2);
    18		return $s;
    19	}
    20	
    21	printf("%d\n", add(2, 3));   // 出力: 5
    22	$kasan = "add";   // シングルクォーテーションマークでも可,以下同様
    23	printf("%d\n", $kasan(2, 3));   // 出力: 5
    24	printf("%d\n", add_sub("add", 2, 3));   // 出力: 5
    25	printf("%d\n", add_sub("sub", 2, 3));   // 出力: -1
    			
    06 行目~ 09 行目

      2 つの引数の和を計算して返す関数です.

    11 行目~ 14 行目

      2 つの引数の差を計算して返す関数です.

    16 行目~ 19 行目

      引数として渡された関数 $fun を呼び,その結果を返す関数です.

    21 行目

      関数 add を呼んでいます.

    22,23 行目

      関数名 add を,文字列として変数 $kasan に代入し,この変数を利用して関数 add を呼んでいます.このように,変数 $kasan は,関数 add と同様の働きをします.

    24,25 行目

      関数 add_sub の引数として,"add" または "sub" を渡して,いずれかの計算結果を得ています.

    プログラム例 6.3] 関数(可変長引数) 

      可変長の引数を扱うことができます.その実体は,引数を配列に入れているようです.なお,可変長引数は,最後の引数である必要があります.

    01	/****************************/
    02	/* 関数(可変長引数)       */
    03	/*      coded by Y.Suganuma */
    04	/****************************/
    05	
    06	function plus($kind, ...$str) {
    07		if ($kind == 0) {
    08					// 文字列
    09			$s = '';
    10			while (count($str) > 0)
    11				$s .= array_shift($str);
    12		}
    13		else {
    14					// 数値
    15			$s = 0;
    16			foreach ($str as $value)
    17				$s += $value;
    18		}
    19		return $s;
    20	}
    21	
    22	$str = plus(0, 'abc', 'def', 'ghi');
    23	printf("結合結果 : %s\n", $str);
    24	$sum = plus(1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    25	printf("合計 : %d\n", $sum);
    			
    06 行目~ 20 行目

      可変長の引数を持った関数 plus の定義です.$kind が 0 の場合は文字列の結合,それ以外は,数値の加算が結果になります.

    09 行目~ 11 行目

      配列 $str の要素数が正である場合,11 行目が繰り返され,引数として渡された文字列が結合されていきます.ここでは,while 文を使用していますが,16 行目のように foreach 文でも構いません.なお,count は,要素数を返す関数,また,array_shift は,配列の最初の要素を取り出す関数(取り出した後は要素数が 1 だけ減る)です.いずれも,配列関数の一つです.

    15 行目~ 17 行目

      渡された要素の和を計算しています.勿論,10 行目のように,while 文でも可能です.

    22 行目

      結合する文字列を引数として,関数 plus を読んでいます.

    24 行目

      和を計算する数値を引数として,関数 plus を読んでいます.
    (出力)
    結合結果 : abcdefghi
    合計 : 55			

  7. クラスクラス),(派生クラス

      大きなプログラムの場合,その部分的な機能の修正のため,他の機能に対応する部分も理解し,かつ,場合によってはそれらの一部も修正するなど,プログラム全体にわたって理解し,かつ,修正をしなければならないとしたら,大変なことになります.そこで,プログラムのモジュール化が非常に重要になります.各機能毎にモジュール化し,

    1. そのモジュール内部における詳細な処理を知らなくても,適当なインターフェースを介してデータを渡し,また,インターフェースを介して希望する結果が得られる.

    2. モジュールとのやりとりは,インターフェースを介してのみ可能であり,モジュールの外部から,そのモジュール内の処理を直接コントロールすることはできないし,また,コントロールする必要がない.

    ようにしておけば,各モジュールは他のモジュールの影響を受けにくくなり,対応する機能の修正はそのモジュールの修正だけで済みます.ある意味では,各モジュールをブラックボックス化するわけです.

      このモジュール化の一つの実現方法が関数です.引数を付けて関数を呼ぶというインターフェースによって,関数内部の処理の詳細を知らなくても結果を得ることができます.また,ローカル変数の存在により,関数外部から関数内部の処理を直接コントロールすることは基本的に不可能です.

      このように,関数もモジュール化の強力な手段ですが,それは,アルゴリズムに重点を置いたブラックボックス化です.しかし,場合によっては,データに重点を置いたブラックボックス化が必要になる場合があります.それが,まさに,クラスです.クラスでは,データとそれを扱う関数を一つにまとめ,特定のインターフェース(クラス内で宣言された関数)を介してのみ,その内部にアクセスできるようにすることが可能です.このような処理をデータの抽象化と呼び,抽象データ型の変数(つまり,あるクラス型として宣言された変数)をオブジェクト(データとそれを操作する手続き-関数-をひとまとめにしたもの,object )と呼びます.

      クラスは,その定義の方法から見て,ユーザーが新たに定義する変数の型と考えても良いと思います.新しい変数の型を定義すれば,その型の操作方法も必要になります.例えば,実部と虚部という 2 つのデータからなる複素数に対応する型をクラスによって定義したとします.すると,単純な加算ですら,既存の方法,つまり,整数や浮動小数点数と同じような方法を使用することができません.従って,定義した変数の加算をどのようにして実行するかについても定義してやる必要が出てきます.そこで,クラスの定義には,単にデータだけでなく,そのデータを取り扱う方法を記述した関数(クラス内で定義された関数をメソッドと呼ぶ)が必要になってくるわけです.

      PHP におけるクラスの使用方法に関しては,以下に示すいくつかの例によって説明していきます.

    プログラム例 7.1] クラスと継承 

    01	/****************************/
    02	/* クラスと継承             */
    03	/*      coded by Y.Suganuma */
    04	/****************************/
    05	class Number
    06	{
    07		public $name;   // var $name;
    08		protected $feat;   // var $feat;
    09		function __construct($str = "数")   // コンストラクタ
    10	//	function Number($str = "数")   // コンストラクタ
    11		{
    12			$this->name = $str;
    13			$this->feat = "数とは,・・・";
    14		}
    15		function out()
    16		{
    17			echo "Number クラスの定義です\n";
    18		}
    19	}
    20	
    21	class Complex extends Number
    22	{
    23		private $r_part;   // var $r_part;
    24		private $i_part;   // var $i_part;
    25		function __construct($x, $y, $str = "複素数")   // コンストラクタ
    26	//	function Complex($x, $y, $str = "複素数")   // コンストラクタ
    27		{
    28			parent::__construct($str);   // 親のコンストラクタ
    29	//		parent::Number($str);   // 親のコンストラクタ
    30			$this->r_part = $x;
    31			$this->i_part = $y;
    32		}
    33		function out()
    34		{
    35			echo $this->feat."\n";
    36			echo "($this->r_part, $this->i_part)\n";
    37		}
    38	}
    39	
    40	$y = new Number();
    41	echo $y->name."\n";
    42	//echo $y->feat."\n";   参照できない
    43	
    44	$x = new Complex(1.0, 2.0);
    45	echo $x->name."\n";
    46	$x->out();
    47	//echo $y->r_part."\n";   参照できない
    			
    05 行目~ 19 行目

      クラス Number の定義です.

    07,08 行目

      クラス Number のプロパティ( C/C++ におけるメンバー変数に相当)の定義です.publicprotected は,参照制限を設定するためのキーワードです.23,24 行目の private も同様です.これらのキーワードは,メソッド(クラス内の関数,C/C++ のメンバー関数に相当)にも付加することができます.public を付加されたメソッドやプロパティは,他のクラス,クラスの外,など,どこからでも参照可能です.private を付加すると,そのプロパティやメソッドが定義されているクラス内だけから参照できるようになります.なお,コメントにあるように,var キーワードを使用すると,public と同様,どこからでも参照可能となります.

      Windows のプログラムを書くような場合について考えてみてください.多くの Windows アプリケーションが存在しますが,その基本的なレイアウトや機能はほとんど同じです.それらのすべてを一から記述するとすれば大変な作業になります.しかし,Windows の基本機能を実現したプログラムがすでに存在し,そのプログラムを利用しながら必要な箇所の修正,追加を行うことによって可能であるとすれば,作業量は非常に少なくなります.これを実現したのが継承です.

      あるクラスに宣言されているプロパティやメソッドをすべて受け継ぎ(継承),受け継いだメソッドを修正,さらには,それに新たなプロパティやメソッドを付加して新しいクラスを宣言することができます.このとき,基になったクラスを親クラス,また,派生したクラスを子クラスと呼びます.

      プロパティやメソッドに対して protected 指定を行うと,そのプロパティやメソッドが定義されているクラス,及び,そのクラスの親クラス,そのクラスを継承したサブクラスだけから参照可能になります.

    09 行目~ 14 行目

      コンストラクタの定義です.コンストラクタは,そのクラスのオブジェクトが定義されたとき( 40,44 行目),最初に呼ばれるメソッドであり,初期設定等を行います.このコンストラクタの場合,デフォルト引数が設定されていますので,40 行目のように,引数 $str に対応する引数を記述しなくても,このコンストラクタが呼ばれます.なお,コンストラクタは,クラス名と同じ名前のメソッドを使用して,10 行目のようにも記述できます.

    12,13 行目

      クラスのプロパティに値を設定しています.一般に,クラスのプロパティやメソッドを参照する際は,「オブジェクト名->メソッド名」,「オブジェクト名->プロパティ名」という形で行います.ここで使用されている this は,自分自身を表すキーワードです.

    15 行目~ 18 行目

      クラス Number に所属するメソッド out( C/C++ におけるメンバー関数に相当)の定義です.

    21 行目~ 38 行目

      クラス Number を継承した クラス Complex の定義です.このように,あるクラスを継承するには,キーワード extends を使用します.

    28 行目

      あるクラスを継承しても,そのコンストラクタは継承されません.親クラスのコンストラクタで行うべき作業がある場合は,この例のように,親クラス( parent )のコンストラクタを呼んでやる必要があります.なお,親クラスのコンストラクタが,10 行目のような形で記述されている場合は,29 行目のような形で記述することも可能です.ここで,スコープ演算子( :: )は,クラス定数,スタティックプロパティ,スタティックメソッド(後述)にアクセスする際に用いられます.

    33 行目~ 37 行目

      クラス Complex に所属するメソッド out の定義です.クラス Complex のプロパティが,23,24 行目のように,private になっているため,このメソッドを使用してそれらの値を出力せざるを得ません.継承する際に,メソッドも継承されますが,15 行目~ 18 行目のままでは,ここでは役に立ちません.そこで,継承したメソッド out をオーバーライド(書き直し)しています.なお,15 行目のメソッド out の定義において,以下に示すような final 設定を行えば,サブクラスでそのメソッドをオーバーライドできなくなります.なお,プロパティに対して final 指定を行うことはできません.
    	final function out()				

    40,45 行目

      new 演算子を使用して,Number クラス,及び,Complex クラスのオブジェクトを生成しています.
    (出力)
    数
    Number クラスの定義です
    複素数
    数とは,・・・
    (1, 2)			

    プログラム例 7.2] スタティックメソッドとプロパティ

    01	/************************************/
    02	/* スタティックメソッドとプロパティ */
    03	/*      coded by Y.Suganuma         */
    04	/************************************/
    05	class Knot {
    06		const KT = 1852;
    07		public static $m_s = 0.5144;   // 値の変更可
    08		public static function to_km($x) {
    09			return $x * self::KT;
    10		}
    11	
    12		function out() {
    13			echo "1 knot : ".self::KT." km/h\n";
    14			echo "1 knot : ".self::$m_s." m/s\n";
    15			echo "50 knot : ".self::to_km(50)." km/h\n";
    16		}
    17	}
    18	
    19	echo Knot::KT."\n";
    20	echo Knot::$m_s."\n";
    21	echo Knot::to_km(10)."\n";
    22	echo Knot::out();   // OK
    23	
    24	echo "\n";
    25	$x = new Knot();
    26	//echo $x->KT."\n";   // error
    27	//echo $x->m_s."\n";   // error
    28	echo $x->to_km(10)."\n";   // OK
    29	echo $x->out();
    			
    06 行目

      クラス定数の定義です.オブジェクトを生成しなくても,スコープ演算子を使用して,「クラス名::定数名」の形で参照できます.「オブジェクト名->定数名」の記述は許されません.

    07 行目

      プロパティに対して static 宣言をしています(スタティック変数).参照方法に関しては,クラス定数と同じですが,値の変更が許されます.

    08 行目~ 10 行目

      static 宣言されたメソッドです(スタティックメソッド).クラス定数などと同様,スコープ演算子を使用して,「クラス名::メソッド名」の形で参照できます.しかし,クラスのオブジェクトが生成されたときは,「オブジェクト名->メソッド名」の記述も許されます( 21,28 行目).ただし,09 行目に示すように,プロパティを参照する際,「 this->プロパティ名」ではなく,self とスコープ演算子を使用して「self::プロパティ名」のような記述をする必要があります.なお,スタティックメソッドから参照できる変数は,スタティック変数だけとなります.

    12 行目~ 16 行目

      一般的なメソッドです.しかし,13 行目~ 15 行目に示すように,参照方法が異なる点に注意してください.static 宣言されたメソッドと同様,「クラス名::メソッド名」,「オブジェクト名->メソッド名」,いずれの方法も許されます( 22,29 行目).
    (出力)
    1852
    0.5144
    18520
    1 knot : 1852 km/h
    1 knot : 0.5144 m/s
    50 knot : 92600 km/h
    
    18520
    1 knot : 1852 km/h
    1 knot : 0.5144 m/s
    50 knot : 92600 km/h
    			

    プログラム例 7.3] オブジェクトの複製 

    01	/****************************/
    02	/* オブジェクトの複製       */
    03	/*      coded by Y.Suganuma */
    04	/****************************/
    05	class Complex {
    06		public $r_part;
    07		public $i_part;
    08		function __construct($x, $y)
    09		{
    10			$this->r_part = $x;
    11			$this->i_part = $y;
    12		}
    13	}
    14	
    15	class Example {
    16		public $x;
    17		public $y;
    18		public $c;
    19		function __construct($x, $y)
    20		{
    21			$this->x = $x;
    22			$this->y = $y;
    23			$this->c = new Complex($this->x, $this->y);
    24		}
    25	}
    26				// 基本オブジェクト
    27	echo "    基本オブジェクト\n";
    28	$e1 = new Example(1, 2);
    29	echo '$x '.$e1->x.' $y '.$e1->y."\n";
    30	echo '$c ('.($e1->c)->r_part.', '.($e1->c)->i_part.")\n";
    31				// $e1 を $e2 に代入後,$e2->y を 20,($e2->c)->r_part を 100 に変更
    32	echo '    $e1 を $e2 に代入後,'."\n";
    33	echo '    $e2->y を 20,($e2->c)->r_part を 200 に変更'."\n";
    34	$e2 = $e1;
    35	$e2->y = 20;
    36	($e2->c)->r_part = 200;
    37	echo '$x '.$e1->x.' $y '.$e1->y."\n";
    38	echo '$c ('.($e1->c)->r_part.', '.($e1->c)->i_part.")\n";
    39				// $e1 のクローン $e3 を作成後,$e3->y を 30,($e3->c)->r_part を 300 に変更
    40	echo '    $e1 のクローン $e3 を作成後,'."\n";
    41	echo '    $e3->y を 30,($e3->c)->r_part を 300 に変更'."\n";
    42	$e3 = clone $e1;
    43	$e3->y = 30;
    44	($e3->c)->r_part = 300;
    45	echo '$x '.$e1->x.' $y '.$e1->y."\n";
    46	echo '$c ('.($e1->c)->r_part.', '.($e1->c)->i_part.")\n";
    			
    05 行目~ 13 行目

      クラス Complex の定義です.

    15 行目~ 25 行目

      クラス Example の定義です.プロパティとして,Complex クラスのオブジェクトを所有しています.

    27 行目~ 30 行目

      クラス Example のオブジェクト $e1 を生成し,その各プロパティの値を出力しています.

    32 行目~ 38 行目

      $e1 を $e2 に代入した後,$e2 のプロパティ $y の値を 20,$c のプロパティ $r_part の値を 200 に変更した後,$e1 の各プロパティの値を出力しています.その出力結果を見てください,変更したのは $e2 関係のプロパティの値にもかかわらず,$e1 の関連するプロパティの値も変化しています.通常の変数であれば,
    	$a = $b;
    	$b = 10;				
    のように,$b の値を変更しても,$a の値はその影響を受けないはずです.それは,$b の値のコピーが $a に代入されるからです.しかし,28 行目のように,new 演算子を使用してオブジェクトを生成した場合,C/C++ 風に述べれば,$e1 には,生成されたオブジェクトのアドレスが記憶されることになります.従って,34 行目の代入文によって,$a に記憶されているアドレスがコピーされて $b に代入されることになります.その結果,$a と $b は,同じオブジェクトを指すことになり,$b 内の値を変更すれば,対応する $a の値も変化することになります(逆も同様).

    40 行目~ 46 行目

      これを避ける一つの方法が,42 行目に示すように,clone を使用して,$e1 の複製クローン)を $e3 に代入することです.clone を使用すると,通常の変数の場合と同様,代入元の値がコピーされて代入先に代入されます.その結果,$e3 内の値を変更しても,$e1 はその影響を受けなくなります.しかし,出力結果の最後を見てください.Complex クラスのプロパティ $r_part の値は変化しています.これは,23 行目の操作によって,Example クラスのプロパティ $c には,Complex クラスのオブジェクトのアドレスが記憶されており,clone によってそのアドレスがコピーされて $e3 に代入されます.その結果,$e1 と $e3 は,同じ Complex クラスのオブジェクトを指すことになるからです.
    (出力)
        基本オブジェクト
    $x 1 $y 2
    $c (1, 2)
        $e1 を $e2 に代入後,
        $e2->y を 20,($e2->c)->r_part を 200 に変更
    $x 1 $y 20
    $c (200, 2)
        $e1 のクローン $e3 を作成後,
        $e3->y を 30,($e3->c)->r_part を 300 に変更
    $x 1 $y 20
    $c (300, 2)
    			

  8. 変数の有効範囲(スコープ) 

    01	<?php
    02	
    03		/****************************/
    04		/* 変数の有効範囲(スコープ) */
    05		/*      coded by Y.Suganuma */
    06		/****************************/
    07		
    08		/*******************/
    09		/* クラス Example1 */
    10		/*******************/
    11		class Example1 {
    12			private $pri;
    13			protected $pro;
    14			public $pub;
    15	
    16			function Example1() {
    17				$this->pub = 1000;
    18				$this->pri = 2000;
    19				$this->pro = 3000;
    20			}
    21	
    22			function sub1() {
    23				printf("sub1 pub %d pri %d pro %d\n", $this->pub, $this->pri, $this->pro);
    24			}
    25		}
    26	
    27		/*******************/
    28		/* クラス Example2 */
    29		/*******************/
    30		class Example2 extends Example1 {
    31			function sub2() {
    32				printf("sub2 pub %d pro %d\n", $this->pub, $this->pro);
    33	//			printf("sub2 pri %d\n", $this->pri);   // 許されない
    34			}
    35		}
    36	
    37		/****************/
    38		/* main program */
    39		/****************/
    40				// ブロック
    41		$x = 10;
    42		$z = 30;
    43		if ($x > 5) {
    44			printf("block x %d\n", $x);
    45			$x = 15;
    46			$y = 20;
    47			printf("block x %d\n", $x);
    48			printf("block y %d\n", $y);
    49		}
    50		else {
    51			printf("block x %d\n", $x);
    52			$x = -15;
    53			printf("block x %d\n", $x);
    54		}
    55		sub();
    56		printf("x %d\n", $x);
    57		printf("y %d\n", $y);   // 最初の x が 1 の時は,y が未定義のためエラー
    58				// クラス
    59		$ex = new Example2();
    60		$ex->sub1();
    61		$ex->sub2();
    62		printf("public member( pub ) %d\n", $ex->pub);
    63	
    64		/************/
    65		/* 関数 sub */
    66		/************/
    67		function sub()
    68		{
    69			$x = 40;
    70			printf("   sub x %d\n", $x);
    71			global $z;
    72			printf("   sub z %d\n", $z);
    73		}
    74	
    75	?>
    			
      まず,41 行目において,変数 $x が定義され(変数 $x に値が代入され),10 で初期設定されています.この変数 $x は,この位置から main プログラムが終わる 62 行目まで有効になります.43 ~ 49 行目の if ブロック内の 44 行目において,変数 $x の値が出力されていますが,当然,その結果は,41 行目で宣言されたときの値になります.しかし,45 行目において,再び,変数 $x が宣言されていますが,PHP の場合は,C++ の場合とは異なり,41 行目で宣言された変数 $x に置き換わることになります.従って,ここで宣言された変数 $x の有効範囲は,main プログラムの終わりである 62 行目までになります.実際,56 行目における出力文では,45 行目において宣言された変数 $x の値が出力されます.同様に,46 行目で宣言された変数 $y の有効範囲も 62 行目までとなります.この例では,問題がありませんが,41 行目における変数 $x の初期値を 5 以下に設定すると,50 ~ 54 行目が実行されることになります.そのブロック内では,変数 $y が使用されていませんので,57 行目の出力文はエラーになってしまいます.変数が定義されているか否か(変数に値が代入されているか否か)の見極めが困難である場合も多いと思いますので,十分注意してください.

      55 行目において関数 sub を呼んでいます.69 行目では,変数 $x を宣言し,70 行目において,その値を出力しています.当然,69 行目の宣言を行わなければ,エラーになってしまいますし,また,69 行目の宣言によって,45 行目で宣言された $x の値が影響を受けることはありません( 56 行目に対応する出力結果参照).しかし,変数 $z は,関数 sub 内に宣言されておらず,42 行目において宣言されています.上で述べた変数 $x と同様,関数内において,main プログラムや他の関数内の変数を参照することはできません.しかし,71 行目の記述( global )によって,main プログラム内の変数を参照可能になります.このように,関数の外側で宣言された変数を関数内から参照可能にした変数をグローバル変数と呼びます.逆に,変数 $x や $y のように,あるブロック(関数を含む)内だけで有効な変数を,ローカル変数と呼びます.以上,41 ~ 57 行目内の出力文(関数 sub 内の出力文を含む)によって,以下に示すような出力が得られます.
    block x 10
    block x 15
    block y 20
       sub x 40
       sub z 30
    x 15
    y 20				
      次に,クラスに付いて考えてみます.11 ~ 25 行目においてクラス Example1 が定義され,30 ~ 35 行目では,クラス Example1 を継承する形で,クラス Example2 が定義されています.PHP においては,クラス Example の各変数や関数のアクセス権は,そのままクラス Example2 に引き継がれます.

      59 行目において,Example2 のインスタンス $ex を生成し,60 行目では,クラス Example1 から継承した関数 sub1 を通して,3 つの変数を出力しています.このときは,3 つの変数の値がそのまま出力されます.しかし,61 行目では,クラス Example2 に追加された関数 sub2 を通して各変数を出力しています.ただし,この場合は,親クラス Example1 の private メンバー変数 $pri を参照することができない点に注意してください.また,62 行目のようなクラスの外側からの参照においては,pubulic メンバー変数 $pub だけを参照可能です.なお,private 指定は,同じクラス内の関数だけから,protected 指定は,同じクラス,親クラス,及び,そのクラスを継承したクラスだけから,また,public 指定は,どこからでも参照可能なことを意味します.以上,59 ~ 62 行目内の出力文によって,以下に示すような出力が得られます.
    sub1 pub 1000 pri 2000 pro 3000
    sub2 pub 1000 pro 3000
    public member( pub ) 1000				

  9. 様々な例題

    1. 数値計算

        この章では,主として科学技術計算に使用される様々なプログラム例を与えます.可能な限り,各関数(クラス)は一般的に使用できるように書いたつもりです.プログラムの具体的使用法に関しては,各手法の説明の箇所も参照してください.また,画面上でそのまま実行できるように,ほとんどの例に対して JavaScript による記述も併記しています.

      1. (プログラム例 A.1 ) 連立線形方程式,逆行列(ガウス・ジョルダン) 

          プログラムは,連立線形方程式の解(逆行列)をガウスの消去法によって求めた例です. JavaScript 版では,任意のデータに対して,連立方程式の解,逆行列,行列の乗算,及び,行列式の値を画面上で計算することが可能になっています.

      2. (プログラム例 A.2 ) 非線形方程式(二分法) 

          プログラムは,f(x) = exp(x) - 3x = 0 の根を二分法で求めた例です.JavaScript 版では,JavaScript の仕様に適合した形で解を求めたい式を入力することによって,任意の非線形方程式の解を画面上で求めることができます.

      3. (プログラム例 A.3 ) 非線形方程式(セカント法) 

          プログラムは,f(x) = exp(x) - 3x = 0 の根をセカント法で求めた例です.JavaScript 版では,JavaScript の仕様に適合した形で解を求めたい式を入力することによって,任意の非線形方程式の解を画面上で求めることができます.

      4. (プログラム例 A.4 ) 非線形方程式(ニュートン法) , (多次元:  )

          プログラムは,f(x) = exp(x) - 3x = 0 の根をニュートン法で求めた例です.多次元の場合に対するプログラムは,3 点 (0.5,1.0),(0.0,1.5),(0.5,2.0) を通る円の中心座標と半径を多次元のニュートン法で求めた例です.JavaScript 版(多次元の場合に対する JavaScript 版)では,JavaScript の仕様に適合した形で解を求めたい式を入力することによって,任意の非線形方程式の解を画面上で求めることができます.

      5. (プログラム例 A.5 ) 代数方程式(ベアストウ) 

          プログラムは,実係数代数方程式 (x + 1)(x - 2)(x - 3)(x2 + x + 1) = 0 の解を,ベアストウ法で求めた例です.JavaScript 版では,任意のデータに対して画面上で解を得ることができます.

      6. (プログラム例 A.6 ) 行列の固有値(フレーム法+ベアストウ法) 

          プログラムは,行列の固有値をフレーム法とベアストウ法によって求めるためのものです.JavaScript 版では,任意のデータに対して画面上で解を得ることができます.

      7. (プログラム例 A.7 ) 実対称行列の固有値・固有ベクトル(ヤコビ法) 

          プログラムは,実対称行列の固有値及び固有ベクトルを,ヤコビ法で求めるためのものです.JavaScript 版では,任意のデータに対して画面上で解を得ることができます.

      8. (プログラム例 A.8 ) 最大固有値と固有ベクトル(べき乗法) 

          プログラムは,行列の固有値と固有ベクトルを,固有値の絶対値が最大のものから順に求めていく方法(べき乗法)です.JavaScript 版では,任意のデータに対して画面上で解を得ることができます.

      9. (プログラム例 A.9 ) 数値積分(台形則) 

          プログラムは,台形則により sin(x) を 0 から π/2 までの積分するプログラム例です.シンプソン則による方法と比較してみてください.JavaScript 版では,JavaScript の仕様に適合した形で積分したい式を入力することによって,任意の関数の積分を画面上で求めることができます.

      10. (プログラム例 A.10 ) 数値積分(シンプソン則) 

          プログラムは,シンプソン則により sin(x) を 0 から π/2 までの積分するプログラム例です.JavaScript 版では,JavaScript の仕様に適合した形で積分したい式を入力することによって,任意の関数の積分を画面上で求めることができます.

      11. (プログラム例 A.11 ) 微分方程式(ルンゲ・クッタ) 

          プログラムは,以下の微分方程式をルンゲ・クッタ法によって,0 から 1 秒まで解いた例です.JavaScript 版では,JavaScript の仕様に適合した形で微分方程式を入力することによって,任意の微分方程式の解を画面上で求めることができます.

          d2y/dt2 + 3dy/dt + 2y = 1  初期条件はすべて0
          (x[0] = y, x[1] = dy/dt)

      12. (プログラム例 A.12 ) 補間法(ラグランジュ) 

          プログラムは,ラグランジュ補間法のプログラムです.JavaScript 版では,n 次補間多項式による計算結果を画面上で求めることができます.

      13. (プログラム例 A.13 ) 補間法(スプライン) 

          プログラムは,3次スプライン関数によってスプライン補間するためのものです.JavaScript 版では,任意のデータに対して,スプライン補間法による計算結果を画面上で求めることができます.

      14. (プログラム例 A.14 ) 補間法(ベジエ曲線) 

          プログラムは,ベジエ多角形を B0 = (1 1),B1 = (2 3),B2 = (4 3),B3 = (3 1) としたとき,対応するベジエ曲線を描くためのものです.JavaScript 版では,任意のデータに対して,ベジエ曲線上の座標を画面上に出力することができます.

    2. 最適化

      1. (プログラム例 B.1 ) 最適化(線形計画法) 

          プログラムは,線形計画法を実行するための例です.なお,実行に関しては,使用方法を参考にしてください.JavaScript 版では,画面上で実行することができます.

      2. (プログラム例 B.2 ) 最適化(黄金分割法) 

          プログラムは,f(x) = x4 + 3x3 + 2x2 + 1 の最小値を黄金分割法で求めた例です.JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい式を入力することによって,任意の関数の最小値を画面上で求めることができます.

      3. (プログラム例 B.3 ) 最適化(多項式近似法) 

          プログラムは,f(x) = x4 + 3x3 + 2x2 + 1 の最小値を多項式近似法で求めた例です.JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい式を入力することによって,任意の関数の最小値を画面上で求めることができます.

      4. (プログラム例 B.4 ) 最適化(最急降下法) 

          プログラムは,最急降下法を使用して,非線形関数の最小値を求めるためのものです(「使用方法」参照).JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい式を入力することによって,任意の関数の最小値を画面上で求めることができます.

      5. (プログラム例 B.5 ) 最適化(共役勾配法) 

          プログラムは,共役勾配法を使用して,非線形関数の最小値を求めるためのものです(「使用方法」参照).JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい関数を入力することによって,任意の関数の最小値を画面上で求めることができます.

      6. (プログラム例 B.6 ) 最適化(Newton 法) 

          プログラムは,Newton 法を使用して,非線形関数の最小値を求めるためのものです(「使用方法」参照).JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい関数を入力することによって,任意の関数の最小値を画面上で求めることができます.

      7. (プログラム例 B.7 ) 最適化(準 Newton 法) 

          プログラムは,準 Newton 法を使用して,非線形関数の最小値を求めるためのものです(「使用方法」参照).JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい関数を入力することによって,任意の関数の最小値を画面上で求めることができます.

      8. (プログラム例 B.8 ) 最適化(シンプレックス法) 

          プログラムは,シンプレックス法を使用して,非線形関数の最小値を求めるためのものです(「使用方法」参照).JavaScript 版では,JavaScript の仕様に適合した形で最小値を求めたい関数を入力することによって,任意の関数の最小値を画面上で求めることができます.

      9. (プログラム例 B.9 ) 最適化(動的計画法) 

          プログラムは,動的計画法を使用して,資源配分問題,0-1 ナップザック問題,及び,グラフ上の最短経路問題を解くためのものです.JavaScript 版では,画面上で実行することが可能です.

      10. (プログラム例 B.10 ) 巡回セールスマン問題(分割法) 

          プログラムは,巡回セールスマン問題( TSP )を分割法によって解くためのものです.実行に関しては,使用方法を参照してください.

      11. (プログラム例 B.11 ) 巡回セールスマン問題(逐次改善法) 

          プログラムは,巡回セールスマン問題( TSP )を逐次改善法によって解くためのものです.実行に関しては,使用方法を参照してください.

      12. (プログラム例 B.12 ) 遺伝的アルゴリズム( TSP,関数の最大値への応用) 実行に関しては,いずれも,使用方法を参照してください.

          [巡回セールスマン問題] 

            添付したプログラムは,巡回セールスマン問題( TSP )を遺伝的アルゴリズムによって解くためのものです.

          [関数の最大値] 

            遺伝的アルゴリズムの基本事項を定義したクラス Species は,巡回セールスマン問題だけに適用できるわけではありません.後一つの例として,関数,

          f(x) = sin(3*x) + 0.5 * sin(9*x) + sin(15*x+50)

          の [0, 1] 区間における最大値を求めるためのプログラムを添付しておきます.

    3. 確率と統計

      1. (プログラム例 C.1 ) ガンマ関数 

          プログラムは,ガンマ関数の値を計算するためのものです.JavaScript 版では,任意のデータに対するガンマ関数の値を画面上で求めることができます.

      2. (プログラム例 C.2 ) 二項分布 

          プログラムにおいて,グラフ出力を指定すると,ベルヌーイ試行を n 回行い,0 ~ n 回成功する場合に対する二項分布の密度関数および分布関数の値をファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      3. (プログラム例 C.3 ) ポアソン分布 

          プログラムにおいて,グラフ出力を指定するとポアソン分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      4. (プログラム例 C.4 ) 一様分布 

          プログラムにおいて,グラフ出力を指定すると一様分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      5. (プログラム例 C.5 ) 指数分布 

          プログラムにおいて,グラフ出力を指定すると指数分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      6. (プログラム例 C.6) 正規分布 

          プログラムにおいて,グラフ出力を指定すると正規分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      7. (プログラム例 C.7 ) χ2 分布 

          プログラムにおいて,グラフ出力を指定すると χ2 分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      8. (プログラム例 C.8 ) t 分布 

          プログラムにおいて,グラフ出力を指定すると t 分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      9. (プログラム例 C.9 ) F 分布 

          プログラムにおいて,グラフ出力を指定すると F 分布の密度関数および分布関数の値を指定した範囲だけファイルに出力します.また,グラフ出力を指定しないと,指定された値における密度関数および分布関数の値,または,%値を出力します.JavaScript 版では,同様の処理を画面上で実行することが可能であり,結果はテキストエリアに出力されると共に,「確率(複数点)」を選択すればグラフも表示されます.

      10. (プログラム例 C.10 ) 乱数の発生 

          プログラムは,一様乱数,指数乱数,および,正規乱数の発生するためのものです.JavaScript 版では,結果を画面上で見ることができます.

    4. モンテカルロ法

      1. (プログラム例 D.1 ) 待ち行列(簡単な例) 

          プログラムは,待ち行列が 1 つで,かつ,サービス窓口の数が s (任意)であるような非常に簡単な待ち行列モデル

        をシミュレーションするためのものです.客の到着やサービスの分布は,すべて指数分布となっています(修正は,非常に簡単だと思います).また,JavaScript 版では,画面上でシミュレーションを実行し,結果を得ることができます.なお,実行結果のカッコ内の値は,対応する項目に対する理論値です.

      2. (プログラム例 D.2 ) 待ち行列(複雑な例) 

          プログラムは,プログラム例 D.1 より複雑な待ち行列モデル

        をシミュレーションするためのものです.入力データによって,様々な構造のモデルに対するシミュレーションも可能です.また,到着時間に関しては,(指数分布,一定時間間隔,客の人数と到着時間の指定)の中から,また,サービス時間に関しては,(指数分布,一定時間)の中から選択可能です.プログラムの最後に,上の図に示したモデルをシミュレーションするための入力例,及び,最初に示した簡単な例に対する入力例が与えてあります.

          JavaScript 版では,画面上でシミュレーションを実行し,結果を得ることができます.初期設定の状態は,上の図に示したモデルをシミュレーションするためのものです.入り口,待ち行列,窓口の数などを変えれば(変更して,その位置に対するフォーカスを外せば),対応した状態が表示されます.なお,入り口,待ち行列,及び,窓口数の最大値は 10 に設定してありますが,ファイル complex.htm の 11 ~ 13 行目を修正することによって,容易に変更可能です.

    5. 多変量解析

      1. (プログラム例 E.1 ) 最小二乗法(多項式近似) 

          プログラムは,最小二乗法(多項式近似)を実行するためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      2. (プログラム例 E.2 ) 重回帰分析 

          プログラムは,重回帰分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      3. (プログラム例 E.3 ) 正準相関分析 

          プログラムは,正準相関分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      4. (プログラム例 E.4 ) 主成分分析 

          プログラムは,主成分分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      5. (プログラム例 E.5 ) 因子分析 

          プログラムは,因子分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      6. (プログラム例 E.6 ) クラスター分析 

          プログラムは,クラスター分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

      7. (プログラム例 E.7 ) 分散分析 

          プログラムは,分散分析を行うためのものです.データの入力方法に関しては,プログラムの最後に提示してある入力例に対する説明を参考にして下さい.JavaScript 版では,任意のデータに対して画面上で実行することができます.

    6. ニューラルネットワーク

      1. (プログラム例 F.1 ) ニューラルネットワーク( Hopfield ネットワーク)

          プログラムC/C++ の場合)は,Hopfield ネットワークを使用して,連想記憶を扱った例です.また,プログラムC/C++ の場合)は,Hopfield ネットワークを使用して,4 都市に対する巡回セールスマン問題( TSP )を扱った例です.JavaScript 版(連想記録,および,TSP)では,画面上で実行可能です.

      2. (プログラム例 F.2 ) パーセプトロン学習 

          プログラムは,p 個の入力ユニットと 1 個の出力ユニットからなるニューラルネットワークに対してパーセプトロン学習を行います.データの入力方法に関しては,使用方法を参照して下さい.JavaScript 版では,画面上で実行可能です.

      3. (プログラム例 F.3 ) Winner - Take - All 

          プログラムは,p 個の入力ユニットと o 個の出力ユニットからなる Winner-Take-All ニューラルネットワークに対する学習を行います.Winner-Take-All ニューラルネットワークとは,出力ユニットの内,最大の出力を持つユニットだけが発火することによって,与えられたデータを分類しようとするものです.データの入力方法に関しては,使用方法を参照して下さい.JavaScript 版では,画面上で実行可能です.

      4. (プログラム例 F.4 ) 競合学習 

          プログラムは,与えられた n 個のパターンを競合学習という教師無しの方法で分類するためのものです(入力ユニット数: p,出力ユニット数: o ).データの入力方法に関しては,使用方法を参照して下さい.JavaScript 版では,画面上で実行可能です.

      5. (プログラム例 11.50 ) バックプロパゲーション 

          プログラムは,任意の構造のネットワークをバックプロパゲーション法によって学習するためのものです.データの入力方法に関しては,使用方法を参照して下さい.JavaScript 版では,画面上で実行可能です.

    7. その他

      1. (プログラム例 G.1 ) ファジイ推論 

          プログラムは,以下に示すような m 個の変数を使用した n 個の規則を基にしてファジイ推論を行うものです.データの入力方法に関しては,使用方法を参照して下さい.JavaScript 版では,画面上で実行することが可能です.テキストエリア内のデータの意味に関しては,C++ によるプログラムに対する説明を参照してください.

        if x1 = A11, x2 = A12, ・・・ ,xm=A1m then y = B1
        if x1 = A21, x2 = A22, ・・・ ,xm=A2m then y = B2
            ・・・・・・・・・・・・・
        if x1 = An1, x2 = An2, ・・・ ,xm=Anm then y = Bn

      2. (プログラム例 G.2 ) 伝達関数(ゲインと位相の計算) 

          プログラムは,伝達関数からボード線図を作成するのに必要なゲインと位相を計算するためのものです.データの入力方法に関しては,使用方法を参照して下さい.なお,JavaScript 版では,グラフを表示し,グラフの色や線の太さを変更することが可能です.JavaScript 版では,式の数(グラフの数)や次数に制限をかけていますが(最大の式の数:5,最大次数:10 ),プログラム内の変数 max_g や max_order の値を変えることによって容易に変更できます.

      3. (プログラム例 G.3 ) ソートと探索 

          プログラムでは,まず,1 次元配列に,ランダムに生成した 1,000,000 個のデータを記憶し,その後,配列を扱う sort 関数によってソートし,in_array によって探索しています.探索するデータは,最初に生成したデータの 10 個毎のデータです( 100,000 個).また,二分探索を行う関数を作成し,その結果とも比較しています.データを記憶するのにかかった時間,ソートにかかった時間,及び,探索にかかった時間を出力しています.

          最後は,文字列の探索です.ランダムに生成した長さ 1,000,200 の文字列 str に対して,5,000 個の長さ 200 の文字列を探索しています.5,000 個の文字列は,str の部分文字列であり,その内,半分には,文字列 str に含まれない文字が 1 文字含まれています.そのため,半分の文字列に対しては,探索しても見つからないことになります.データを記憶するのにかかった時間,及び,探索にかかった時間を出力しています.

          JavaScript 版では,表示された画面の「実行」ボタンをクリックすると,画面上で結果を見ることができます.なお,実行時間,データ数を多くするとブラウザが不安定になる,等の問題から,対象とするデータ数を減らしています.しかし,かなり時間がかかります.

情報学部 菅沼ホーム 目次 索引