「PHP/入門/関数とは」の版間の差分
削除された内容 追加された内容
→変数のスコープ: マークアップ修正 タグ: 2017年版ソースエディター |
→再帰的呼出し: 関数は、自分の定義の中に自分を含めることができます。 タグ: 2017年版ソースエディター |
||
69 行
:<syntaxhighlight lang=php>
<?php
function f(){▼
return 1;▼
}▼
$a = f();
echo $a;
▲function f(){
▲ return 1;
▲}
?>
</syntaxhighlight>
84 ⟶ 85行目:
;解説
: 上記コードを実行すると、まずf()が呼び出され、f()から1が返され、その値が
: PHPの代入演算子は右結合かつ右辺の値を返すので、<code>$a = $b = 0;</code> は、<code>$a = ( $b = 0 );</code>と解され、<code>$a = 0; $b = 0;</code>と同じ結果となります。
;参考
103 ⟶ 102行目:
<code>pi()</code> は、円周率の数値を返す関数である。
=== 関数の引数と戻値 ===
176 ⟶ 174行目:
strict_types を 1 にセットすると、型宣言漏れをエラーにできます。
;例:<syntaxhighlight lang=php line highlight=6>
<?php
declare(strict_types=1);
418 ⟶ 416行目:
::このようキャプチャーを行う性質から、無名関数は、しばしまクロージャーと呼ばれます。
::: 無名関数の中で __FUNCTION__ を参照すると、<code>{closure}</code> となります。
=== 再帰的呼出し ===
関数は、自分の定義の中に自分を含めることができます。
;例:<syntaxhighlight lang=php line highlight=6 line highlight="9,17,22">
<?php
declare(strict_types=1);
function ipow(int $x, int $y) : int {
if ($y == 0)
return 1;
if ($y == 1)
return $x;
return $x * ipow($x, $y - 1);
}
echo 'ipow(2, 3) --> ', ipow(2, 3), PHP_EOL;
echo 'ipow(10, 9) --> ', ipow(10, 9), PHP_EOL;
function comma3(int $n) {
if ($n < 0) {
return "-" . comma3(-$n);
}
$num = intdiv($n, 1000);
$rem = $n % 1000;
if ($num) {
return comma3($num) . sprintf(",%03d", $rem);
}
return sprintf("%d", $rem);
}
echo 'comma3(ipow(10, 9)) --> ', comma3(ipow(10, 9)), PHP_EOL;
echo 'comma3(ipow(2, 32)) --> ', comma3(ipow(2, 32)), PHP_EOL;
?>
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
ipow(2, 3) --> 8
ipow(10, 9) --> 1000000000
comma3(ipow(10, 9)) --> 1,000,000,000
comma3(ipow(2, 32)) --> 4,294,967,296
</syntaxhighlight>
:整数の累乗を求める関数 <code>ipow()</code> と、整数を3桁ごとに ',' で区切ってた文字列を返す関数 <code>comma3()</code> を定義しました。
:2つの関数とも定義が再帰的なので、再帰的呼び出しで実装しています。
:再帰的呼出しは、終了条件を間違えると「無限再帰」に陥ってしまい、資源(この場合はスタック)を喰いつくすまで帰ってきません。
:アルゴリズムが再帰的な場合、再帰的呼出しを行う関数として実装するとコードは短くなりますが、PHPの処理系はtailrecのような最適化は行わないので、関数呼出しのオーバーヘッドが再帰の他に課金され、資源にも優しくないので、再帰で実装したあと回帰テストを書き、ループで実装しテストを通ることを確認するのがベターでしょう。
[[Category:PHP|にゆうもん かんすうとは]]
|