1.演算子の概要
演算子は、算術演算子に代表されるように、変数やリテラルなどの値に対して演算を行うための記号です。
演算子の中でも有名なのが、加算演算子や減算演算子などの算術演算子です。
Perl の組み込み演算子は、演算の対象となる値、『オペランド』の個数によって単数演算子、二項演算子、三項演算子に分類することができます。また、間値演算子か前置演算子か、数値、文字列、ファイルなど捜査対象によっても分類できます。ただし、これらの分類はプログラミングする上であまり重要ではなく、一つ一つの演算子を理解するためのものです。
用語
- オペランド
- 演算の対象となる値。演算内容をあらわす記号は演算子と呼びます。例えば 10+X
という式では、10 と X がオペランドで、+ がオペレータです。
演算子の優先順位
演算子には結合性と優先順位があります。
演算子の一覧
演算子 | 結合性 | 解説 |
---|---|---|
項とリスト演算子 | 左 | 下段参照 |
-> | 左 | メソッド読み出し、デリファレンス |
++ -- | しない | インクリメント デクリメント |
** | 右 | 指数演算子 |
! ~ \ 単項+ 単項- | 右 | 論理not ビットごとのnot リファレンス演算子 単項のプラス、単項のマイナス |
=~ !~ | 左 | マッチする、マッチしない |
* / % x | 左 | 乗算 除算 剰余 文字列繰り返し |
+ - . | 左 | 加算 減算 文字列結合 |
<< >> | 左 | 左ビットシフト 右ビットシフト |
名前付き単項演算子とファイルテスト演算子 | しない | |
< > <= >= lt gt le ge | しない | 小さい 大きい 小さいか等しい 大きいか等しい。以下、文字列について同様の比較 |
== != <=> eq ne cmp | しない | 等しい 等しくない 符号付比較。以下、文字列について同様の比較 |
& | 左 | ビットごとの AND |
| ^ | 左 | ビットごとの OR ビットごとの XOR |
&& | 左 | 論理AND |
|| | 左 | 論理OR |
.. ... | しない | 範囲演算子 |
?: | 右 | 条件演算子 |
= += -= *= など | 右 | 代入演算子 |
, => | 左 | カンマ カンマの働きをする矢印 |
リスト演算子 | しない | |
not | 右 | 論理NOT |
and | 左 | 論理AND |
or xor | 左 | 論理OR 論理XOR |
結合性
結合性とは、左右どちらかに配置された変数や定数を演算の対象にするかということです。たとえば、and やorなどの論理演算子は左側にある値を対象とします。代入演算子などは右側にある値を対象とします。たとえば、次の式は、加算演算子が左側にある値に対して、右側の値を加算し、代入演算子が右側にある値を左側にある変数に代入しています。
# 10 に $x を加算する $val = 10 + $x;
演算子と優先順位
優先順位は利便性を考慮して付けられているので、あまり気にしなくても正常に扱えます。もし不安な時は、カッコをつかって順番をはっきりさせましょう。
$x = (10 + 10) * 2;
演算子の中で、項が最も高い優先順位を持っています。項には、変数、クォート、クォート風の演算子、カッコで囲んだ式、引数をカッコで囲んだ関数が含まれます。
単項演算子は、引数として1個のスカラを受け取るもので、リスト演算子より低い優先順位になっています。演算子を挟んで右と左に値が必要な二項演算子、右側、もしくは左側だけが必要な単項演算子です。
2.算術演算子
算術演算子は、数値に対して数学関数を実行します。
算術演算子の使用方法
算術演算子の一覧
演算子 | 説明 | 例題 |
---|---|---|
+ | 加算 | $x = 10+2 # $x の値は 12 |
- | 減算 | $x = 10-2 # $x の値は 8 |
* | 乗算(×) | $x = 10*2 # $x の値は 20 |
/ | 除算(÷) | $x = 10/2 # $x の値は 5 |
% | 剰余 | $x = 10%2 # $x の値は 0 |
** | 累乗 | $x = 10** # $x の値は 100 |
++ | インクリメント | $x++ # 元々の $x の値が 10 であれば 11 になる |
-- | デクリメント | $x-- # 元々の $x の値が 10 であれば 9 になる |
プログラム言語のほとんどは、算術式を左から順に記述します。2分の1という式をプログラミング言語のルールに従うと、1/2 となります。
カッコの使い方は代数学の場合と同じです。たとえば、 b+c に a を掛けるには次のようにします。
(b + c) * a
演算子の順番では、乗算、除算、剰余演算子の次に加算、減算が計算されます。同一の優先順位にある演算子が複数並ぶときは、左から順に計算されます。ただし、カッコ内にある演算子は、最初に計算されます。計算式が複雑になるときはカッコを使って見やすくしましょう。
単項のマイナス( - )
単項演算子のマイナス( - )符号は少し特殊な働きがあります。-は対象の値が数値であれば、算術否定を行ない、対象の値が文字列であれば、マイナス記号にその文字列をつなげた文字列が返されます。
$x = -10; $val = -$x; # $xの値が数値なので、算術否定が行われ、$valの値は 10 $x = 'test'; $val = -$x; # $xの値がリテラルなので、文字列結合が行われ、$valの値は'-test'
足し算/引き算/掛け算/割り算
足し算、引き算、掛け算、割り算は違和感なく使うことができると思います。
$x = 10 + 2; # $x の値は 12 $x = 10 - 2; # $x の値は 8 $x = 10 * 2; # $x の値は 20 $x = 10 / 2; # $x の値は 5
※ 割る数が 0だとオーバーフローが発生します。割る数が変数ならチェックしてから割り算を実行してください。
剰余
剰余は割ったあまりを返します。
$x = 10 % 4; # 割り切れなかった2が返され、$x の値は 2 $x = 10 % 2; # 2 * 5で割り切れるから $x の値は 0
累乗
ダブルアスタリスク( ** )は指数演算子で、左側の数値を右側の数値で乗算します。この演算子は、単項のマイナスよりも結合が強い演算子で、-2**4は (-2)**4 ではなく、-(2**4) と解釈されます。
print 2 ** 4; > 16 print -2 ** 4; > -16 print ((-2) ** 4); > 16
インクリメント/デクリメント
++ 演算子と -- 演算子は、引数に1を加える、もしくは1を引きます。
$x = 5; $y = 5; $x++; # $x は加算されて6 $y--; # $y は減算されて4
これらの演算子は、引数の前にある場合は値を返す前に値を増減し、引数の後ろにある場合は値を返してから増減します。引数の前に置く場合はプリインクリメント/プリデクリメント、引数の後に置く場合はポストインクリメント/ポストデクリメントといいます。
$x = 5; $y = 5; $z = $x++; # $x の値を $z に代入してから、$x の値を増加($z の値は 5) $z = ++$y; # $y を増加させてからその値を $z に代入($z の値は 6)
インクリメント演算子には、マジカルインクリメントと呼ばれる機能があります(デクリメント演算子にはありません)。インクリメント演算子の対象となる変数の値が文字列としてだけ扱われてきた英数字であれば、個々の文字の範囲を保ちながら桁あげします。
print ++($foo = '99'); > 100 print ++($foo = 'A'); > B print ++($foo = 'zz'); # z の次は a で、桁が繰り上がる > aaa print ++($foo = 'a0'); > a1
3.比較演算子
予測できない複数の値を比較したいときは、『比較演算子』を使います。比較演算子は数値用と文字列用の2種類が用意されています。
比較演算子の使用方法
比較演算子は左引数と右引数を比較し、その結果を論理値で返します。Perlには数値用と文字列用の比較演算子がありますが、どちらの比較演算子も結果を論理値で返します。
数値比較演算子と文字列比較演算子の早見表
比較 | 数値 | 文字列 | 戻り値 |
---|---|---|---|
等しい | == | eq | 左引数と右引数が等しければ真を返す。 |
等しくない | != | ne | 左引数と右引数が等しくなければ真を返す。 |
小さい | < | lt | 左引数が右引数より小さければ真を返す。 |
大きい | > | gt | 左引数が右引数より大きければ真を返す。 |
以下 | <= | le | 左引数が右引数と同じか小さければ真を返す。 |
以上 | >= | ge | 左引数が右引数と同じか大きければ真を返す。 |
比較 | <=> | cmp | 等しければ0、大きければ1、右引数が大きければ-1を返す。 |
数値用の演算子でも、文字列を比較することができます。数値として比較する == は、前もって数値に変換してから比較を行います。
1 == '1'; # 等しい 'alpha' == 'beta' # 数値としてはどちらも 0で等しい
数値と違い、文字列の比較は厳密に行われ、比較する前に値を文字列に変換するようなことはありません。
1 eq '1' # 等しくない
数値や文字も真偽値が必要なところでは真偽を解釈されます。
# 0 は偽りなのでブロックを実行しない if (0) { ... } # 1 は真なのでブロックを実行 if (1) { ... } # 空の文字列は偽なのでブロックを実行しない if ("") { ... } # 通常の文字列なら真なのでブロックを実行する if ("a") { ... }
4.論理演算子
&& や || は『論理演算子』と呼ばれています。「AとBがTRUEならば・・・」、「A、もしくはBのどちらかがTRUEならば・・・」など、式の真偽値を左から順に解釈していきます。
論理演算子の使用方法
論理演算子の一覧1
名前 | 例 | 結果 |
---|---|---|
論理積 | $a && $b | $a と $b が真ならTRUEを返す |
論理和 | $a || $b | $a もしくは $b が真ならTRUEを返す |
否定 | ! $a | $aが真でなければTRUEを返す |
用語
- 論理積
- && と and は、左側の演算子が真であれば、右側の演算子も評価します。左側の演算子が偽であれば、右側の演算子を評価せずに結果を返します。
- 論理和
- || と or は、左側の演算子が真であれば、右側の演算子を評価せずに結果を返します。左側の演算子が偽りであれば、右側の演算子も評価します。
たとえば、ファイルを開く処理として以下のような方法がよく使われています。
open( FH, "file.txt") || die "Cannot open file: $!\n";
この場合、まず open 関数を評価して、ファイルを開く(TRUE)ことができれば、die関数を評価せずに次の行に処理を移します。
&&、|| 演算子と同義語として and、or、not演算子が用意されています。特に理由がなければ、and、or、not演算子を使うようにしましょう。処理は同じですが、優先順位が低く設定されているので、引数にカッコを使っていないリスト演算子のあとに続けて使う場合にも、安心して使うことができます。
unlink "alpha", "beta", "gamma" or gripe(), next LINE;
論理演算子の一覧2
名前 | 例 | 結果 |
---|---|---|
論理積 | $a and $b | $a と $b が真ならTRUEを返す |
論理和 | $a or $b | $a もしくは $b が真ならTRUEを返す |
否定 | not $a | $aが真でなければTRUEを返す |
条件演算子
?: は、『条件演算子』です。? の前の引数が TRUE であれば、: の前の引数が返されますが、FALSE であれば、: の後の引数が返されます。
$x = $a > $b ? $a : 0;
上記の例は、$a が $b より大きい値であれば $a の値を返し、それ以外は 0 を返します。
5.文字列演算子
文字列演算子は、値を文字列リテラルと解釈して演算処理を行います。
文字列を連結する演算子
. 演算子は文字列の連結を行います。
$x = "filename"; $x .= ".txt"; print $x; > filename.txt
繰り返し演算子
x は繰り返し演算子です。スカラコンテキストでは、x演算子の左側の値をその右側の値の示す数だけ繰り返した文字列を返します。リストコンテキストでは、左側の値がリストであれば、リストを繰り返します。
# - を10個表示 print '-' x 10; > ---------- # $x を10回繰り返したものを$xに代入 $x = '-'; $x x= 10; print $x" > ---------- # 10個の(1, 1, ......, 1)と同様 @ones = (1) x 10;
6.ビット演算子
ビット演算子は、ビットを対象として処理する演算子です。
論理積
& は、両被演算子のビットごとに論理積をとって、その結果を返します。
print sprintf("%04lo", 0011 & 0101), "\n"; > 0001
論理和
| は、両被演算子のビットごとに論理和をとって、その結果を返します。
print sprintf("%04lo", 0011 | 0101), "\n"; > 0111
排他的論理和
^ は、両被演算子のビットごとに排他論理和をとって、その結果を返します。
print sprintf("%04lo", 0011 ^ 0101 ), "\n"; > 0110
シフト演算子
<<演算子は、左引数の値を右引数で示すビット数だけ、左にシフトした値を返します。引数は整数でなければなりません。
>>
演算子は、左引数の値を右引数で示すビット数だけ、右にシフトした値を返します。引数は整数でなければなりません。
printf( "%d\n", 10 >> 1 ); printf( "%d\n", 10 << 1 ); > 5 > 20
7.代入演算子
=は代入演算子で、算術演算子、論理演算子、文字列演算子、繰り返し演算子、ビット演算子などと組み合わせて使うことができます。
代入演算子の使用方法
最もよく使われる代入演算子は、次のような単純代入です。
# $x に 10 を代入 $x = 10; # $x に $x の値掛ける2の値を代入 $x = $x * 2;
上記の最後の行のように、左辺値の値を元にした計算は1つの行で済ませることができます。たとえば、以下の2つの式は同じ意味になります。
# $x に 2 を加算 $x = $x + 2; # 上記の式と同様に、$x に 2 を加算 $x += 2;
代入演算子の一覧
演算子 | 説明 |
---|---|
**= | 累乗して代入
$x = 10; print $x **= 2; > 100 |
+= | 加算して代入
$x = 10; print $x += 2; > 12 |
*= | 乗算して代入
$x = 10;< print $x *= 2; > 20 |
-= | 減算して代入
$x = 10; print $x -= 2; > 8 |
/= | 除算して代入
$x = 10; print $x /= 2; > 5 |
%= | 剰余して代入
$x = 10; print $x %= 3; > 1 |
&&= | 左辺値の値が TRUE であれば右辺値を代入(論理積) $x = 0; print $x &&= 2; > $x = 1; print $x &&= 2; > 2 |
||= | 左辺値の値が FALSE であれば右辺値を代入(論理和) $x = 0; print $x ||= 2; > 2 $x = 1; print $x ||= 2; > 1 |
.= | 右辺値を左辺値の文末に追加
$x = "filename"; print $x .= ".txt"; > filename.txt |
x= | 繰り返し演算
$x = 10; print $x x= 2; > 1010 |
&= | |
<<= | |
|= | |
>>= | |
^= |
代入演算子は通常なら2行になる式を1行にまとめるのに便利ですが、次のように $xの値を $y に代入し、$y の値を置換するという式も1行で済ませることができます。
$x = "rhythm"; ($y = $x) =~ tr/[a-z]/[A-Z]/; print "x=$x\n", "y=$y"; > x=rhythm > y=RHYTHM
8.範囲演算子
..は範囲演算子です。リストコンテキストでは、左の値から右の値まで数えあげた値からなる配列を返します。これは、for(1..10) のようなループを書くときや、配列のスライス演算を行なうときに便利です。
# 大文字すべての配列を得る @alphabet = ('A' .. 'Z'); # 16 進の数字が得られます $hexdigit = (0 .. 9, 'a' .. 'f')[$num & 15]; # 0 付きの日付が得られます @z2 = ('01' .. '31');
→ 配列
9.アロー演算子
-> は中置の被参照演算子です。右側が [...] か {...}の形の添字であれば、左側は配列かハッシュへのリファレンスです。左辺値であればハードリファレンスを保持できる場所である必要があります。また、右側はメソッド名かメソッド名を持ったスカラ変数で、左側はオブジェクトかクラス名になります。
# ハッシュへのリファレンス $ref = \%hash; print $ref->{name}, "\n"; # オブジェクトの参照 $ref = new Obj; print $ref->getName();
覚えておくと便利な計算式
切り上げ/切り捨て
切り捨ては int関数を使います。切り上げの場合は、+1してから切り捨てればいいのですが、一桁が0の場合は+1してはいけません。
$a = 100.6; # 切捨て:$a を切り捨て、$floor の値は100 $floor = int( $a ); # 切り上げ:$a を切り上げて、$ceilの値は101 $ceil = ( $a == int($a) ? $a : int($a + 1) );
浮動小数点での切捨て/切り上げは少し応用が必要です。たとえば少数点以下第1位で切り捨てにする場合、10倍してから上記のように切り捨てし、それから10で割ります。小数点以下第2位は(10の2乗で)100倍してから切り捨てし、100で割ります。それ以降も同様に扱えます。
$a = 100.6789; # 小数点第1位で切り捨て、$x の値は 100.6 $x = int($a * 10) / 10; # 小数点第2位で切り捨て、$x の値は 100.67 $x = int($a * 100) / 100;
四捨五入
少数点以下を四捨五入したければ 0.5 を足して切り捨てます。
$a = 100.6789; # $a を少数点以下で四捨五入し、 $x の値は 101 $x = int( $a + 0.5 );
小数点以下の有効桁数
浮動小数点の変数を任意の有効桁数を設定して表示したいときは、sprintf
関数が役に立ちます。
$a = 100.6789; $x = sprintf "%3.4f", $a; # $x の値は「100.6789」 $x = sprintf "%3.2f", $a; # $x の値は「100.68」