0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

11: 演算子

Last updated at Posted at 2022-03-01

演算子

演算子(Operator:オペレーター)とは、与えられた変数やリテラルに対して、あらかじめ決められた処理を行うための記号。

右辺の値を左辺の変数に代入するための「=」演算子や、乗算を行うための「*」演算子など。

演算子によって処理される変数/リテラルのことをオペランド(Operand:被演算子)と呼ぶ。

$x=5+4
青: オペランド(被演算子)
赤: オペレーター(演算子)

PHPでは変数/リテラルの比較や文字列/配列の結合、コンピュータ独自のビット処理など、さまざまな処理が用意されている。

PHPで利用可能な演算子は

①代数演算子

②代入演算子

③比較演算子

④論理演算子

⑤ビット演算子

⑥その他の演算子

に分類される。

①代数演算子

算術演算子とも言う。
四則演算をはじめ、日常的な数学で利用する演算子を提供する。

主な代数演算子

演算子 概要
+ 数値の和 5+4 →9
- 数値の差 6-3 →3
* 数値の積 3*4 →12
/ 数値の商 15/3 →5
% 数値の剰余(割った余り) 13%3 →1
** 数値の累乗 2**3 →8
++ 前置加算(代入前に加算) $x=3; $y=++$x; →$yは4
++ 後置加算(代入後に加算) $x=3; $y=$x++; →$yは3
-- 前置減算(代入前に減算) $x=3; $y=—-$x; →$yは2
-- 後置減算(代入後に減算) $x=3; $y=$x—-; →$yは3

代数演算子は見た目にも最もわかりやすく、直感的に利用できるものがほとんどだが、利用に際して注意点もある。

文字列混在の演算

代数演算子では、数値だけでなく文字列も演算可能。
なお、文字列混在の演算ルールについてPHP8で大きく変化したので、まずはPHP7.4までの結果から。

<?php
print ‘108’ + ‘15’;
①//結果: 123

print ‘108’ + ‘1.5XYZ’;
②//結果: 109.5

print ‘108’ + ‘XYZ10’;
③//結果: 108

print ‘108’ + ‘1.5XYZ10’;
④//結果: 109.5

print ‘108’ + ‘1.5E1’;
⑤//結果: 123

print ‘108’ + ‘0b11’;
⑥//結果: 108

print ‘108’ + ‘010’;
⑦//結果: 118

print ‘108’ + ‘0x1A’;
⑧//結果: 108

①はリテラルがクォート文字で囲まれているので、オペランドの108と15はいずれも文字列型の値。
しかし代数演算子はこれを暗黙的に数値リテラルとみなして演算する。

これは文字列と数値とが混在している場合も同様(②〜④)。

まず数値が先頭にくる②のケースでは、後続の不要な文字列を無視して演算する。

つまり108+1.5で結果は109.5となる。

ただし③のように文字列が先頭にくる場合、PHPはこれを認識できない。

後ろに数値文字列があったとしても同様。

‘XYZ10’はそのままゼロとみなされ、演算の結果も108+0で108となる。

④の場合も同様。
‘1.5XYZ10’は文字列の先頭と末尾に数値文字列が含まれるが、認識されるのは先頭の1.5だけ。
末尾の10は無視される。

⑤は数値/文字列混在のケースですが、指数表現とみなせるケース。
この場合指数表現は数値と認識され、108+15で123という結果が得られる。(108+1.5ではない!1.5E1=15)

もっとも、この変換は例外と考えるべき。

⑥〜⑧のように2/8/16進数文字列を渡した場合には、10進数には変換されず、②〜④と同様のルールで演算される。

8進数の’010’も8ではなく、そのまま10と認識されている点に注目。

ここでは加算演算子(+)の例だけを挙げているが、文字列リテラルに対する演算の考え方は、加減乗除いずれの場合も同様。

PHP8での挙動

PHP8でも、先頭が数値で始まる文字列(②、④、⑥、⑧)は数値としてみなされるが、より厳しく
「A non-numeric value encountered」
のような警告が発生する。(PHP7.4以前ではNotice)。

一般的に文字列混じりの数値を演算することは誤りであるはずなので、よりあるべき挙動になったといえる。

なお、③のように先頭が数値でない文字列については
「Unsupported operand types: string + string」
のようなエラーとなる。

文字列を無理に0と解釈する、これまでの挙動は大概バグの原因にしかならないはずなので、これも開発者にとっては望ましい変化である。

加算子(++)/減算子(—-)

「++」と「--」は、与えられたオペランドに対して1を加算/減算するための演算子。

それぞれ加算子(インクリメント演算子)減算子(デクリメント演算子)という。

たとえば次の先はいずれも同じ意味。

$x ++;  ↔︎  $x = $x + 1;
$x —-;  ↔︎  $x = $x - 1;

加算子/減算子をオペランドの前後いずれに置くかによって、代入の結果が変わる。

<?php
①
$x = 10;
$y = ++$x;

print $x; //結果: 11
print $y; //結果: 11


②
$i = 10;
$j = $i++;

print $i; //結果: 11
print $j; //結果: 10

加算子をオペランドの前方に置くことを前置演算
後方に置くことを後置演算という。

①のように前置演算を行った場合、加算子は変数$xへの加算を行ったあとで$yへの代入を行う。

一方、

②のような後置演算では、加算子は変数 $jへの代入を行った後、$iへの加算処理を行う。

前置演算と後置演算をきちんと区別しておかないと、思わぬ演算結果に悩まされることになる。

マジカルインクリメント

加算子には面白い機能がある。
それがマジカルインクリメント。

<?php
$i = ‘Z’;

print ++$i; //結果: AA
print ++$i; //結果: AB


$j = ‘T8’;

print ++$j; //結果: T9
print ++$j; //結果: U0

このように、アルファベットと数値が混在した文字列に対して加算子を適用すると、末尾がアルファベットであれば次の文字へ、数値であれば1を加算するという特殊な処理を行う。

末尾の文字がZ(z)または9であった場合には、1つ前の文字に対して、いわゆる桁の繰上げを行う。

英数字混在の連番コードを生成する場合などに便利な機能。

ちなみに、減算子を用いた、いわゆるマジカルデクリメントのような機能はない。

12は浮動小数点数の演算の注意点から

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?