« ドラッグ&ドロップsample | メイン | 線で塗り絵sample »

2.5 演算子

■オペランドとオペレータ
ある値に対して演算を行い、新しい値を作る記号を演算子といいます。簡単なものでは加算の記号の+があります。演算の対象となる値や変数のことをオペランド(operand)と呼びます。1+2ならば1と2がオペランドです。演算子はオペレータ(operator)です。また、オペランドの個数によって単項演算子、二項演算子、三項演算子という呼び方もします。

■代入演算子
代入演算子は変数に値を入力したり、プロパティに値を設定する場合に使います。演算結果を代入するものを複合演算子と呼ぶこともあります。複合演算子については各分類で取り上げます。

演算子		機能
=			代入・設定

算数の計算式の「1 + 2 = 3」の=は等号ですが、ActionScriptの=は「ans = 1 + 2」のように式を書いて、=の右項の値を左項の変数やプロパティに代入あるいは設定します。ActionScriptの等号は==または===です。
また、「a = 1 * 2 + 3」のように演算子を結合して式を作れるのと同様に=も連結できます。このとき、式が右側から実行されていく点に注意してください。

例:
var a:int, b:int, c:int;
a = 10;// aに10を代入
b = c  = 10 + 1;// bとcに11を代入
trace(a, b, c);
//出力:10 11 11

例:
var d:int, e:int, f:int;
d = e = (f = 3 + 4) * 2;
trace(d, e, f);
//出力:14 14 7

次のサンプルはムービークリップのインスタンスのbox_mcとball_mcのプロパティの値を設定しています。

[:sample:] operator-1.fla

例:
box_mc.scaleX = box_mc.scaleY = 2.5;
ball_mc.scaleX = ball_mc.scaleY = 3;
box_mc.alpha = ball_mc.alpha = 0.5;

fig02-04-01 box_mcとball_mcの伸縮率とアルファを設定しています。

■算術演算子
算術演算子は数値の演算を行います。+-*/は一般的な加減乗除の計算と同じです。/の除算では、0での割り算を行ってもエラーにはならず値はInfinity(正の無限大)または-Infinity(負の無限大)になります。なお、+と-は数値の前に付けて正負を示す符号としても機能します。

演算子		機能
+			足し算(加算)、正の符号
-			引き算(減算)、負の符号
*			掛け算(乗算)
/			割り算(除算)
%			割り算の余り(剰余)
++			1足す(インクリメント)
--			1引く(デクリメント)
+=			加算して代入
-=			減算して代入
*=			乗算して代入
/=			除算して代入
%=			剰余を代入

例:
trace(50 / 4);
//出力:12.5
trace(50 % 4);
//出力:2

+=や*=といった演算と代入を組み合わせたものを複合演算子と呼びます。値が代入される変数はあらかじめ初期化されている必要があります。たとえば、「a += 3」の式は「a = a + 3」と結果が同じです。


例:
var a:int = 10;
a += 3;
trace(a);
//出力:13

++と--はオペランドに1を加算または減算する演算子ですが、演算子をオペランドの前に置くか後ろに置くかで演算と代入の順が違います。++aのようにオペランドの前に演算子を置いたものをプリインクリメントと呼び、先に変数aに1を加算してから残りのステートメントを実行します。一方、a++ようにオペランドの後ろに演算子を置いたものをポストインクリメントと呼び、ステートメントを実行した後から変数aに1を加算します。--a、a--も同様でそれぞれプリディクレメント、ポストデクリメントと呼びます。
次の2つの例を見るとプリインクリメントとポストインクリメントとの結果の違いがわかります。最初の例はプリインクリメントの例です。bの値はaに1を加算した後で代入されるので、a、bともに6になります。

[:sample:] increment.fla

例:プリインクリメント
var a:int, b:int;
a = 5;
b = ++a;
trace(a, b);
//出力:6 6


一方、次の例ではdの値はcに1が加算される前に代入されるので5になります。cへの加算はdへの代入の後から行われます。

例:ポストインクリメント
var c:int, d:int;
c = 5;
d = c++;
trace(c, d);
//出力:6 5


■ストリング演算子
+は加算の演算子ですが、オペランドの一方がストリング(String、文字列)のとき、ストリングの連結を行う演算子になります。"と'はどちらも対で使い、"test"や'test'のようにストリングを囲みます。ストリングと数値を連結すると数値はストリングに変換されて連結されます。

演算子		機能
+			ストリングの連結
+=			ストリングを連結して代入
" "			ストリングを囲む
' '			ストリングを囲む

[:sample:] concatenation.fla


例:
var usr:String = "鈴木";
var age:int = 25;
var msg:String = usr + "さんは" + age + "歳です。";
trace(msg);
//出力:鈴木さんは25歳です。

なお、次のように"と'を入れ子で使うとそれぞれが記号のまま書き出されます。

例:
var msg:String = "これは'test1'です";
trace(msg);
//出力:これは'test1'です

var msg2:String = 'これは"test2"です';
trace(msg2);
//出力:これは"test2"です


■比較演算子
比較演算子は、左右のオペランドの大きさまたは同じものかどうかを比較します。結果は、条件を満たすときにtrue、満たさない場合にはfalseの論理値になります。比較演算子は、if、while、forといった条件によって制御を判断するステートメントの条件式を作る際に主に利用します。

演算子		機能
==			等しい(等価)
!=			等しくない(不等価)
>			より大きい
>=			以上
<			より小さい
<=			以下
===			厳密な等価(値もデータ型も等しい)
!==			厳密な不透過(値もデータ型も等しくない)
例:
var point:int = 75;
if (point >= 75) {
	trace("合格です");
} else {
	trace("やり直しです");
}
//出力:合格です


■論理演算子
論理演算子は、trueまたはfalseの論理値をオペランドとして扱う演算子です。否定の!演算子は!theStateのように右項のオペランドだけを指定します。

演算子		機能
&&			論理積(両方がtrueのときtrue。そうでなければfalse)
||			論理和(どちらか一方でもtrueならばtrue。そうでなければfalse)
!			否定(trueのときfalse、falseのときtrue)

例:
var a:Boolean = true;
var b:Boolean = false;
trace(a && b);
//出力:false
trace(a || b);
//出力:true
trace(!a);
//出力:false;

次の例はボタンをクリックする度にインスタンスが表示と非表示を行うスクリプトです。インスタンスのvisibleプロパティの値を否定の!演算子を使ってtrueとfalseを反転させています。

[:sample:] showhide.fla

例:表示と非表示をトグルする
test_btn.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(event:MouseEvent):void {
	ball_mc.visible = !(ball_mc.visible);
}

fig02-04-02 ボタンをクリックするとインスタンスの表示と非表示が切り替わります。


■ビット単位演算子
ビット演算子とは、値を2進数に換算して計算を行うものです。各桁(ビット)ごとに値を比較したり、桁をシフトする演算を行います。ビット単位の論理演算ではがtrue、0がfalseとして論理演算を行います。

演算子		機能
|			ビット単位の論理和 
&			ビット単位の論理積
~			ビット単位の否定
<<			ビット単位の左へシフト
>>			ビット単位の右へシフト
>>>			ビット単位の符号なし右シフト
^			ビット単位の排他的論理和
|=			ビット単位の論理和をして代入
&=			ビット単位の論理積をして代入
~=			ビット単位で否定して代入
<<=			ビット単位で左へシフトして代入
>>=			ビット単位で右へシフトして代入
>>>=		単位の符号なし右シフトをして代入
^=			ビット単位の排他的論理和をして代入

ビット単位の論理和では値を2進数に換算して各ビットごとに比較し、どちらかが1ならば1にします。たとえば、6(2進数で110)と5(2進数で101)のビット単位の論理和は7(111)になります。同様にビット単位の論理積では両方が1のときに1にし一方が0ならば0にします。6と5のビット単位の論理積は4(100)になります。
2進数における桁のシフトは2のn階乗で変化します。次のサンプルで使われているrgbToHex()はRGBの各色の値から0xFFFFFFの形式の16進数に変換する関数です。

[:sample:] rgbToHex.fla

例:RGBを16進数に変換する
var r:int = 128;
var g:int = 255;
var b:int = 32;
var rgbHex:uint = rgbToHex(r,g,b);

//RGBを16進数のRRGGBBの形式に変換する
function rgbToHex(r:int, g:int, b:int):uint {
	var rgb:uint;
	var rgbHex:uint;
	rgb = (r << 16)+(g << 8)+b;
	rgbHex = Number("0x"+rgb.toString(16));
	return rgbHex;
}

//スプライトを作る
var circle:Sprite = new Sprite();
circle.graphics.beginFill(rgbHex);
circle.graphics.drawCircle(100, 80, 250);
addChild(circle);

fig02-05-01 RGBの各色を0〜255で個別に指定して色を決めたスプライトを作ります。


■XML演算子
XMLタグを定義したり、XMLまたはXMLListのオブジェクトの値へのアクセスや評価などを行う演算子です。

演算子		機能
@			XMLまたはXMLListのアトリビュートにアクセスする
{ }			XMLまたはXMLListの式で変数を囲む
[ ]			XMLまたはXMLListのプロパティ(ノード)にアクセスする
+			XMLまたはXMLListの値の連結
+=			XMLまたはXMLListの値を連結して代入
..			XMLまたはXMLListのプロパティ名、アトリビュート名での検索抽出
.			XMLまたはXMLListの子エレメントまたはアトリビュートにアクセスする
( )			XMLまたはXMLListの構造内の式を評価・実行
< >			XMLタグを定義する
delete		XMLエレメントまたはアトリビュートを削除する

次のスクリプトはgoodsXmlを作り、1番目のcapのXMLオブジェクトを取り出して値を調べるサンプルです。top-colorタグには-が含まれていてドットではアクセスできないためにmyCap["top-color"]のようにアクセスします。

[:sample:] xml-1.fla

例:
var goodsXml:XML = 
<goods>
	<cap id="t102">
		<size>S</size>
		<top-color>red</top-color>
	</cap>
	<cap id="t105">
		<size>M</size>
		<top-color>blue</top-color>
	</cap>
</goods>;

var myCap:XML = goodsXml.cap[0]
trace(myCap.@id);
//出力:t102
trace(myCap.size);
//出力:S
trace(myCap["top-color"]);
//出力:red

次のスクリプトは{}を使ってXMLオブジェクトのタグ名、アトリビュート名、アトリビュートの値、ノードの値のそれぞれを変数で設定している例です。

[:sample:] xml-2.fla

例:
var tagname:String = "data"; 
var attributename:String = "id"; 
var attributevalue:String = "x586"; 
var content:String = "詳細入門ノート"; 
var dataXml:XML = <{tagname} {attributename}={attributevalue}>{content}; 
trace(dataXml.toXMLString());
//出力:詳細入門ノート

■その他の演算子
その他の演算子としては次に上げるものがあります。データ型を指定する:やコメント文を指定する//も演算子の一部です。

演算子		機能
,			評価式を列挙する。主にforループステートメントで使用する
.			オブジェクトのメンバーにアクセスするための区切り
:			データ型の指定
?:			評価式がtrueかfalseかによって値を選ぶ
::			名前空間を識別する
[ ]			配列の初期化、配列内のエレメントへのアクセス
{ }			プロパティ名と値をもったオブジェクトを作る
( )			式のグループ化
/			文字の前後を囲み正規表現(RegExp)を行う
/* */		コメントブロックの範囲を示す
//			コメント行の先頭を示す
as			データ型を評価する
delete		オブジェクトのプロパティを破棄する
in			指定オブジェクトのプロパティかどうか調べる。配列のインデックス番号かどうかチェックする
instanceof		インスタンスかどうか調べる
is			指定のデータ型またはインターフェイスと互換性があるかを評価する
new			インスタンスを作る
typeof		データ型を表すストリングを返す
void		式を評価した後、その値を破棄してundefinedを返す

?:は「条件式 ? 値1 : 値2;」の3つのオペランドをもった演算子なので三項演算子と呼ばれます。条件式がtrueならば値1、条件式がfalseならば値2を返します。次の例はusrがnullの場合は「名無しさん」を入れるスクリプトです。?:の用法については条件分岐の節でも説明します(→P.??)

例:
var usr:String;
usr = (usr != null) ? usr : "名無しさん";
trace(usr);

::はnamespaceで定義した名前空間を識別するための演算子です。名前空間はクラス定義スクリプトで使い、フレームアクションでは利用できません。(名前空間→P.??)
[]は[値1, 値2, 値3, ...]のように配列を作る機能とインデックス番号を指定して値を取り出す機能をもった演算子です。[]で作った値のデータ型はArrayになります。

[:sample:] operator-2.fla

例:
var ranger:Array = ["red", "blue", "green", "yellow","pink"];
trace( ranger[0],  ranger[2],  ranger[4]);
出力→ red green pink

[]はオブジェクトのプロパティにアクセスする場合にも利用します。次の例ではObjectクラスのインスタンスにプロパティを設定しています。

例:
var myObj:Object = new Object();
myObj["id"] = "jet";
myObj["speed"] = 350;
trace(myObj.id, myObj.speed);
出力→ jet 350

{}は{名前1:値1, 名前2:値2, 名前3:値3, ...}のようにプロパティ名と値をもった配列オブジェクトを作る演算子です。配列オブジェクトのデータ型はObjectになります。[]と{}の用法については配列の節でも説明します(p.??)。

var boxObj:Object = {"id":"xpt", "size":28};
trace(boxObj.id, boxObj.size);
出力→ xpt 28


■演算子の優先順位と結合性
1つのステートメントに複数の演算子が使われているとき、演算の実行の順番は、演算子の優先順位と結合性によって決まります。 同一ステートメントで複数の演算子を使っている場合、演算子の優先順位によって演算の順番が決まります。わかりやすい例としては次のような加減乗除の演算子を使った式があげられます。

例:
a = 8 + 2 * 3 - 10 / 5;

このステートメントでは*と/の優先順位が+と-より高いので、*と/の演算が先に実行されます。これはカッコを使った次の式と同様になります。多くの場合はカッコを使うことで演算の順番をわかりやすく示すことができます。

例:
a = 8 + (2 * 3) - (10 / 5);

演算子の結合性とは、「a/b/c」のように同一の演算子がオペランドをはさんでつながっているときに、右から左へ実行(←)するか、左から右へ実行する(→)かを示すものです。
たとえば、「a/b/c」では/の結合性が「左から右へ」なので、a/bの値をcで割ります。すなわち「(a/b)/c」を実行することになります。 これに対して「a=b=c」では=の結合性は「右から左へ」なので、まずbにcの値を代入し、次にaにbの値を代入します。結果として、a、b、cは同じ値になります。すなわち「a=(b=c)」のように実行することになります。

例:
var a:int, b:int, c:int;
a = 1;
b = 2;
c = 3;
a = b = c;
trace(a,b,c);
//出力:3 3 3

演算子を優先順位が高い順から並べると次のようになります。同じ行にあるもの同士の優先順位は同じです。その場合は結合性に従った順番で実行されます。
演算子の結合性は、代入演算子(=や+=など)を除くすべての二項演算子は左結合となります。つまり、左にある演算子が右にある演算子よりも先に処理されます。代入演算子と三項演算子(?:)は右結合です。つまり、右にある演算子が左にある演算子よりも先に処理されます。

演算子の優先順位(優先順位が高い順)
[] {x:y} () f(x) new x.y x[y] <> @ :: ..
x++ x--
++x --x + - ~ ! delete typeof void
* / %
+ -
<< >> >>>
< > <= >= as in instanceof is
== != === !==
&
^
|
&&
||
?:
= *= /= %= += -= <<= >>= >>>= &= ^= |=
,

About

2007年5月18日 14:44に投稿されたエントリーのページです。

ひとつ前の投稿は「ドラッグ&ドロップsample」です。

次の投稿は「線で塗り絵sample」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。