perlの論理演算子「and」と「&&」の違いとは?

このQ&Aのポイント
  • perlの論理演算子の「and」と「&&」の違いは、「弱い結合」と「強い結合」とかで説明されているのを見かけますが、これは、「短絡評価」と「短絡評価でない」と同じ意味になりますか。
  • サブルーチンxとyがある場合、if文で(1) if(&x==1 and &y==1)と(2) if(&x==1 && &y==1)を実行した場合、(1)ではサブルーチンyは実行されず、(2)では実行されるという理解で正しいでしょうか。
回答を見る
  • ベストアンサー

perlの論理演算子の「and」と「&&」の違い

perlの論理演算子の「and」と「&&」の違いは、 「弱い結合」と「強い結合」とかで説明されている のを見かけますが、これは、 「短絡評価」(左側が偽だと右側が実行されない)と 「短絡評価でない」(左側の真偽に関係なく右側が実行される) のと同じ意味になるのでしょうか。 例えば、 sub x {  print "sub x\n";  return 0; } sub y {  print "sub y\n";  return 1; } の2つのサブルーチンがある場合に、 (1) if(&x==1 and &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } (2) if(&x==1 && &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } を、実行した場合、サブルーチンyは、 (1)では実行されず、(2)では実行される という理解で正しいでしょうか。 (実際にはどちらも実行されていないようなのですが)

  • Perl
  • 回答数3
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.3

> (5) if( not (&x==1) && (&y==1)){ >    print '真',"\n"; >   } else { >    print '偽',"\n"; >   } > を実行すると(4)とは結果が異なっています。 > ((4)はyが実行されないが(5)はyが実行される) このような記述をした場合、 関数呼び出しと同様に、notを優先度最大の括弧付きで呼び出した扱いになります。 Perl#名前付き単項演算子 - - perldoc.jp http://perldoc.jp/docs/perl/5.6.1/perlop.pod#Named32Unary32Operators より引用 | リスト演算子 (print() など) や単項演算子 (chdir() など) は、 | すべて次のトークンとして開き括弧が続くと、その演算子と括弧内の引数は、 | 通常の関数呼び出しのようにもっとも高い優先順位として扱われます。

yam2012
質問者

お礼

( )の中の部分の優先順位だけでなく ( )の前の演算子の優先順位も変わる ということには気が付きませんでした。 ありがとうございました。

その他の回答 (2)

  • f272
  • ベストアンサー率46% (8010/17118)
回答No.2

#1です。 > 短絡評価の時(and)と短絡評価でない時(&&) だれもそんなことは言っていないはずですが... andだろうが&&だろうが,どちらも短絡評価をします。

yam2012
質問者

お礼

andも&&も短絡評価ということですね。 ありがとうございました。 (4) if( not &x==1 && &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } を調べていてもう1つ分からないことがあるのですが ==はnotや&&よりも優先度が高いので &x==1を( )で囲っても優先順位は変わらず 実行結果も同じになるはすですが (5) if( not (&x==1) && (&y==1)){    print '真',"\n";   } else {    print '偽',"\n";   } を実行すると(4)とは結果が異なっています。 ((4)はyが実行されないが(5)はyが実行される) not (&x==1) && (&y==1)にしても notよりも&&の方が優先度が高いので (&x==1) && (&y==1)が実行されてから notが実行されると思われますが 実行結果を見るとnot (&x==1)の方が 先に実行されているようなのですが これは正しい挙動でしょうか。 よろしくお願いします。

yam2012
質問者

補足

下記のお礼コメントの訂正です。 「これは正しい挙動でしょうか。」 の部分ですを 「(4)と(5)で実行結果がなぜ違うのでしょうか。」 に訂正をお願いします。

  • f272
  • ベストアンサー率46% (8010/17118)
回答No.1

演算子の優先順位が違うということです。 (3) if( not &x==1 and &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } (4) if( not &x==1 && &y==1){    print '真',"\n";   } else {    print '偽',"\n";   } を比較してください。

yam2012
質問者

お礼

andの時は、(not &x==1)が先に評価されてからandが評価されて、 &&の時は、(&x==1 && &y==1)が先に評価されてからnotが評価される ということは分かりましたが、notがない時の 短絡評価の時(and)と非短絡評価でない時(&&)の違いが まだ、よく分からないのですが、notがないと、 短絡評価の時(and)と短絡評価でない時(&&)とで 違いがないということなのでしょうか。

関連するQ&A

  • perl 条件演算子 範囲演算子についてです

    演算子 条件演算子 条件演算子 ?: は条件式の値により、2者のうちのどちらかを選択します。 $a=($x<10)?10:20; 変数$aの値が$x<10という条件において、真であれば:左側の10を選び、偽であれば:右側の20を選ぶ。 $a=10; 変数$aに10を代入する。 $a==5?print "5です。\n":print "5ではありません。\n"; 条件式でaが5であれば:左側の print "5です。\n"を表示します。 条件式でaが5でなければ:右側の print "5ではありません。\n"を表示します。 $a==10?print "10です。\n":print "10ではありません。\n"; 条件式でaが10であれば:左側の "10です。\n" を表示します。 条件式でaが10でなければ:右側の "10ではありません。\n" を表示します。 範囲演算子 範囲演算子 .. は、左側の値から右側の値まで、1つずつ増やした値の集まりです。 値には、半角英数字の数値または文字列が指定できる。 print 3..5; 3 4 5 と表示する。 一応、訳を下に書いたのですが合っていますでしょうか。

  • 論理演算について

    Cを勉強中の者です。論理演算についてよくわからいことがあります。 以下のソースコードを実行し結果が真なら0001、偽なら0000が出力されるプログラムを作りました。 #include <stdio.h> int main(void) { unsigned short a = 0x1234; unsigned short b = 0xfafc; unsigned short c = 0xcdef; unsigned short x, y; x = a && b; y = b && c; printf("x=%04x\n", x); printf("y=%04x\n", y); return 0; } 結果はx=0001, y=0001となります。y=0001はbとcの文字列がそれぞれfとcをを持っているので演算による結果は納得できますが、x=0001はaとbの文字列には共通するものがないのになぜx=0000ではないのでしょうか? また0xが頭に付く表現は16進数だと強調するためにあるのですか? 説明に不足があればまた足しますのでよろしくお願いします。

  • $a++と++$aの違いについて

    $a=0; if($a++){ print "真です\n"; }else{ print "偽です\n"; } は、結果が「偽です」として出力されます。 $a=0; if(++$a){ print "真です\n"; }else{ print "偽です\n"; } は結果が「真です」と表示されます。 この上記二つの違いは、++が前につくか、後ろにつくかの違いのようなのですが、そもそも、 if($a++)とif(++$a)とは何を意味しているのでしょうか。 $aはゼロですが、$a++は何なんでしょう? まったくイメージできなくて、さっぱりといった感じで悩んでいます。 宜しくお願いします。

    • ベストアンサー
    • CGI
  • 記号論理学

    論理式∀x∃y((x<y)⊃(x+1>y+1))の真か偽かをを求めよという問題で 求め方がまったくわかりません。 ((x<y)⊃(x+1>y+1))の部分が成り立たないと思うのですがそれで偽ということになるのでしょうか? もしご存知の方が居れば教えていただければ幸いです。 宜しくお願いいたします。

  • 論理式について

    変数の範囲を自然数とし,p(x,y)を「xはyの約数」とする.このとき,次の論理式のそれぞれについて,その意味と真偽の組み合わせで最も適切なものを選択肢から選びなさい. ∀x∃y p(x,y) ∀y∃x p(x,y) ∃x∀y p(x,y) ∃y∀x p(x,y) 【選択肢】 (1)任意の自然数を割り切る数がある.           真 (2)任意の自然数を割り切る数がある.           偽 (3)すべての自然数には少なくとも1つの倍数がある.  真 (4)すべての自然数には少なくとも1つの倍数がある.  偽 (5)任意の自然数には約数が存在する.          真 (6)任意の自然数には約数が存在する.          偽 (7)すべての自然数で割り切られる数がある.       真 (8)すべての自然数で割り切られる数がある.       偽 自分でやってみて、上から順に(8)(3)(5)(1)となったのですが、どうでしょうか?

  • ショートカット演算(短絡演算)について

    ショートカット演算(短絡演算) 以下の❶❷は意味的に等価です。 ◉リスト2-31 logical2.js if (x === 1) { console.log('こんにちは'); } ← ❶ x ===1 && console.log('こんにちは'); ← ❷ 上記は おそらく左がx=1ではないという仮定なので、左側がfalseになりこの時点で右側は実行されないので下記の二つは同じということだと思いますか?

  • perlでサブルーチンへの複数の配列渡し

    perlでサブルーチンに配列を渡しているのですが、 引数としている配列が1個の場合は問題ないのですが、 複数渡すと、第2引数以降が渡りません。 どの様にすれば上手くできますか。 例1 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; &test(@x1); sub test { my (@arg1) = @_; print "sub : @arg1 \n"; } 結果 main : 14 11 5 12 8 15 sub : 14 11 5 12 8 15 例2 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; print "main : @x2 \n"; &test(@x1, @x2); sub test { my (@arg1, @arg2) = @_; print "sub : @arg1 \n"; print "sub : @arg2 \n"; } 結果 main : 14 11 5 12 8 15 main : 12 10 8 9 sub : 14 11 5 12 8 15 12 10 8 9 sub : 引数1に全てが設定されて、引数2に設定されていない。

    • ベストアンサー
    • Perl
  • Perlスクリプトx.plを使って新たに

    y.plを作って y.plの途中に入れたいのですがどうすればいいのでしょうか? 例えば x.pl: $x="Hello World\n"; print $x; $x="Hello Japan\n"; としたときに y.pl: $x="こんにちは世界\n"; print $x; $x="こんにちは日本\n"; print $x;       (ここでx.plを実行したい) $x="こんにちは世界\n"; print $x; $x="こんにちは日本\n"; print $x; といったものです y.plの中でx.plを使いたいのです 質問のためx.pやy.plは実際より大幅に単純化してます

    • ベストアンサー
    • Perl
  • リファレンスを使った方法を教えて下さい。

    以下例1.例2のサブルーチンの部分についてリファレンスを使った書きかたを教えて下さい。よろしくお願いします。 例1. @array1 = ('111x111', '22y2'); $str1 = 'x'; print "find '$str1': ",sagasu($str1,@array1), "\n"; @array2 = ('333x333', '44y4', '555'); $str2 = 'y'; print "find '$str2': ",sagasu($str2,@array2), "\n"; @array3 = ('666x666', '77y7'); $str3 = 'z'; print "find '$str3': ",sagasu($str3,@array3), "\n"; sub sagasu { my ($what,@area) = @_; foreach my $idx (0..$#area) { if ($area[$idx] =~ /$what/) { return $idx } } return -1; } 例2.参照(perlの引数が不安定になります。http://okwave.jp/qa1958086.html) @array1 = ('111x111', '22y2'); $str1 = 'x'; print "find '$str1': ",sagasu(@array1,$str1), "\n"; @array2 = ('333x333', '44y4', '555'); $str2 = 'y'; print "find '$str2': ",sagasu(@array2,$str2), "\n"; @array3 = ('666x666', '77y7'); $str3 = 'z'; print "find '$str3': ",sagasu(@array3,$str3), "\n"; sub sagasu { (@area, $what); (@area[0..($#_ - 1)], $what) = @_; foreach my $idx (0..$#area) { if ($area[$idx] =~ /$what/) { return $idx } } return -1;

    • ベストアンサー
    • Perl
  • 論理演算子について

    ◎1----------------------------- int main(void) { int a=10,b=20; while(1){ if(a= =12 && b= =25){ break; } ++a; ++b; } return 0; } -------------------------------- ◎2------------------------------------------------------- #include<stdio.h> #include<ctype.h> int main(void) { char ss[256]="10%%'%shin(no((100!w**a'16&'shi&%$#n~|=~de)&64"; int dt,i=0; printf("右の文字列には言葉が隠れています: "); printf("%s\n",ss); puts(""); printf("1を入力すると言葉が分かります: "); scanf("%d",&dt); puts(""); while(dt!=1 && ss[i] !='\0'){ if( !isalnum(ss[i]) ){ ss[i]=' '; } ++i; } printf("%s\n",ss); puts(""); return 0; } ------------------------------------------------------------ 以上2つのプログラムにおいて疑問があります。 まず◎1のプログラムで、aが12、bが25になるという2つの条件を満たしたら、プログラムを終了させようと思ったのですが、条件を満たしても、ずっとデクリメントし続け終了しません。 「if(a= =12 && b= =25)」の部分を「if(a= =12 || b= =25)」とすれば、aが12になった時点で終了しました。 ◎1では「if(a= =12 && b= =25)」という条件が何故適用されないかという疑問があります。 次に、◎2ではdtが1になり、配列ssに格納されている文字列が、'\0'になるという2つの条件を満たしたら終了させようとしたのですが、1を入力すると、「ss[i]!='\0'」の条件が偽にもかかわらず、while文が一度も実行されませんでした。 そこで、1以外を入力すると、while文は実行されましたが、dtの条件が真になる事はないのに、ちゃんと終了しました。 プログラム◎1、◎2について何故こうのようになってしまうのか、教えていただければ嬉しいです。

専門家に質問してみよう