1. ホーム
  2. c

[解決済み] C言語の論理ANDはなぜ短絡的な動作をしないのですか?

2023-07-17 14:06:35

質問

これは宿題のようなものですが、私はこのトピックについて調べ、かなり深く考えましたが、これを理解することができません。質問は、コードのこの部分が表示されないと述べている 短絡的な動作 と書いてあり、その理由を尋ねています。しかし、私にはこれが短絡的な動作を示すように見えるのですが、なぜそうならないのか、どなたか説明していただけないでしょうか。

C言語では

int sc_and(int a, int b) {
    return a ? b : 0;
}

の場合は a が偽の場合、プログラムは b を評価しようとしないが、私は間違っているに違いない。なぜプログラムは b に触れる必要がないのでしょうか?

どのように解決するのですか?

これはひっかけ問題です。 b は入力引数で sc_and メソッドへの入力引数であり、したがって常に評価されます。言い換えれば sc_and(a(), b())a() を呼び出し b() (を呼び出し(順番は保証されません)、次に sc_and の結果で a(), b() に渡されます。 a?b:0 . これは三項演算子自体とは関係なく、絶対に短絡してしまいます。

UPDATE

私がこれを「トリッククエスチョン」と呼んだ理由に関して。それは、(少なくともOPによって再現されるように)「短絡」を考慮するためのコンテキストが明確に定義されていないためです。多くの人が、関数の定義だけを与えられても について質問しているのだと思い込んでしまいます。 ボディ 関数の 彼らはしばしば、関数をそれ自体として式として考えていないのです。これは質問の「トリック」です。一般的なプログラミング、特にC言語のようなルールに多くの例外がある言語では、そのようなことはできないことを思い出させるためです。例:このような質問をされた場合。

次のようなコードを考えてみましょう。から呼び出されたとき、sc_and は短絡的な動作をするでしょうか? メイン :

int sc_and(int a, int b){
    return a?b:0;
}

int a(){
    cout<<"called a!"<<endl;
    return 0;
}

int b(){
    cout<<"called b!"<<endl;
    return 1;
}

int main(char* argc, char** argv){
    int x = sc_and(a(), b());
    return 0;
}

を考えているはずだとすぐにわかるでしょう。 sc_and をそれ自体の演算子として考えていることはすぐにわかるでしょう。 ドメイン固有の言語 という演算子として使用し への呼び出しが sc_and が短絡的な振る舞いをするかどうかを評価します。 && . なぜなら、三項演算子に注目するのではなく、C/C++の関数呼び出しの仕組みに注目することになっているのは明らかだからです。 sc_and を短絡させるようなものを書けという質問につながると思います。 #define を使うことになります。)

三項演算子自体が行うことを短絡的と呼ぶかどうか(あるいは「条件付き評価」のような他の何か)は、短絡的の定義に依存しますし、それについての考えについてはさまざまなコメントを読むことができます。私の場合はそうですが、それは実際の質問や私がそれを「トリック」と呼んだ理由にはあまり関係ありません。