12

表題のようにプログラム中で

if(a!=b)

if(a=!b)

と誤って記述した所、コンパイルはできるのですがそこでプログラムが停滞していました。
コンパイルができるということはこの記述にも意味があるのでしょうか?

どのような意味なのでしょうか?


追記

for(i=0;i<n;i++){
    printf("check1");
    if(a=!b){
        実行コード
    }
}
printf("check2");

とした時に実行中でcheck2が出力されず、プログラムが停滞しました。

if(a!=b)

としたら正常に動作しました。

NLP Lover
  • 697
  • 3
  • 8
  • 24
  • 3
    追記されたコードはコンパイルできない(ifが完結していないため)と思います。 – BLUEPIXY Feb 03 '15 at 10:38
  • 6
    +1 C言語の闇が露呈した良い質問だと思いました:P – yohjp Feb 03 '15 at 12:02
  • gccを使ってコンパイルしています。他のコンパイラを使っていないのでなんとも言えませんが、もしかしたらコンパイラに問題があるのかもしれませんね。 – NLP Lover Feb 04 '15 at 06:29
  • gcc の場合なら、if(a=!b) と記述した時に

    suggest parentheses around assignment used as truth value

    とか文句言われたりしませんか? 環境やオプションにもよるのかもしれません。

    – Shirone Feb 04 '15 at 07:47
  • @ILoveNLP if(a=!b)という記述は"正しい"C言語のコードになっていますよ。あらゆるC言語コンパイラはこのコードを受け付ける必要があります/エラーにしてはダメ。ただし、プログラマの意図通りでない可能性もあるので、Shironeさんが指摘されるように、親切なコンパイラならば警告(warning)を出すかもしれません。例:Clangの例 – yohjp Feb 04 '15 at 08:18
  • gcc なら常に -Wall を付けておくと良いかもしれません。 –  Feb 04 '15 at 09:29
  • コンパイラがコンパイルするのが問題ではなく、if文の中でプログラムが停滞し、その先に進まなないことが問題だと思います。 – NLP Lover Feb 05 '15 at 01:24
  • @ILoveNLP これ以外の部分や"実行コード"と書かれている部分の具体的な処理が分からないと、何も言えませんね。別の質問投稿をされた方が良いかと思います。 – yohjp Feb 05 '15 at 01:58
  • 1
    if文の中にループがあって、a や b の値を終了条件に使っている、ということでしょうか? –  Feb 05 '15 at 01:58

3 Answers3

17

b の否定結果を a に代入していると思います。
分けて考えると以下のようになります。

if( a = (!b) )

このため、if( a ) という比較式になります。
つまり、a が 0 以外の場合は常に真として扱います。

Shirone
  • 1,418
  • 9
  • 19
9
if(a!=b) -> if (a != b)  // A
if(a=!b) -> if (a = !b)  // B

上記Aのコードはaとbが違うならTRUE同じならFALSEで条件分岐するという意味です。
Bのコードはaにbの否定(もしbがTRUEならFALSE、FALSEならTRUE)を代入し、aの値を評価してTRUEかFALSEで条件分岐するという意味です。

M.I.A
  • 438
  • 3
  • 13
9

正しい正解が出ているので今更ですが、昔同僚が書いたコードをレビューしていてお茶をフイた良く似たコードを抜粋。

#include <stdio.h>

int
main(int argc, char* argv[]) {
  int a = 2, b = 1, c = 0;

  // a, b, c すべて同じなら
  if (a == b == c) {
    puts("正解");
  }
  return 0;
}

人間としては許してあげたいコードですが...
この質問と同様にコンパイラはこれをエラーとせずにコンパイルしてしまいます。
しかも「正解」のケースに入ります。

  1. a == b は偽(つまり0)
  2. 偽(0) == c は正

よって「正解」が表示されます。

mattn
  • 4,486
  • 14
  • 30
  • 2
    これは(笑)。if ( (a == b) ? (b == c) : 0 ) { # それにしても golang に ternary operator が欲しい…(絶対に入らないでしょうけど) –  Feb 04 '15 at 04:28
  • 5
    Pythonだとa == b == cが正に期待通り動きますね。(他にもこの意味解釈する言語あるのかな?) – yohjp Feb 04 '15 at 05:25
  • 4
    面白い。a < b < c とかもそうですね。Python だけなのかな。オペレータのオーバーロードができる言語だと、似た仕組みは作れそうな気がします。 – Hiroshi Yamamoto Feb 04 '15 at 10:53