5

私は現在 C を学んでおり、次の 2 つのコードの動作が異なるのか、それとも単にスタイルの問題なのかを知りたいと思っていました。

いくつかのソースを見ると、次のコードがあります。

...
FILE * pFile;
pFile = fopen ("myfile.txt","r");
if (pFile == NULL)
{ some code }
...

私の教授は彼のメモに次のコードを持っています:

...
FILE * pFile
if ((pFile = fopen("myfile.txt","r")) == NULL)
{ some code }
...

これが単にさまざまなプログラマーによるスタイルの好みなのか、それとも if ステートメント内に return/set 行を配置する利点があるのか​​を知りたかっただけです。

4

7 に答える 7

5

違いはありません。より経験豊富なプログラマーは、行を節約するために2番目の形式を使用することがありますが、基本的には同じです。2つ目は、もう少し「UNIX-y」になる傾向があり、続行する前に、ほとんどの関数呼び出しが(成功ではなく)エラーについてチェックされます。

于 2012-04-29T21:13:54.413 に答える
1

(pFile = fopen("myfile.txt", "r"))が返されるので、それらは同一ですpFileが、より明示的であるため、私は個人的に最初のものを好みます。

于 2012-04-29T21:15:43.007 に答える
1

これらの2つのバリアントは同じです。パフォーマンスには影響しません。ただし、最初のバリアントの方が、状況がより明確になるため、より優れていると思います。

于 2012-04-29T21:16:53.707 に答える
1

両方のプログラムは同等です。

より読みやすいという理由で最初のスタイルを好む人もいれば、よりコンパクトであるという理由で 2 番目のスタイルを好む人もいます。

詳細については、一部のコーディング ガイドライン ( MISRAが 1 つ) では、2 番目のスタイルが禁止されていることに注意してください。MISRA は、ifステートメントの制御式で代入演算子を使用することを禁止しています。

于 2012-04-29T21:40:22.273 に答える
0

ここで述べたように、2 つのセグメントは明らかに同一です。ただし、代入演算子 = と等値演算子 == の間の混乱を避ける傾向があるため、最初のものをお勧めします。int を返す関数foo(arg)がある状況を考えてみましょう。次のように記述します。

int y;

if ((y = foo(x)) == 0) {
    ... some code ...
}

ここで、代入演算子と等価性を混同しているとしましょう (ところで、if 式では非常に一般的です)。

int y;

if ((y == foo(x)) == 0) {
    ... some code ...
}

(y == foo(x))の型が int であるため、上記はコンパイラによって正当な C コードと見なされます。これにより、明らかにコードにバグが発生します。

ここで、最初のオプションを考えてみましょう。

int y;

y = foo(x);
if (y == 0) {
    ... some code ...
}

明らかに、代入と等式を混同する可能性は低くなります。さらに、y == foo(x);と書いても ステートメントとして、コンパイラーは警告を発行します。

于 2012-04-29T22:33:54.737 に答える
0

既存の回答は非常に優れていますが、C の何かがパフォーマンスの問題であるかどうかという質問にどのようにアプローチするかについて、いくつか追加する必要があります。

まず、確認する簡単な方法は、コードの両方のバージョンをコンパイルして、生成されたファイルgcc -O3を比較することです。.oそれらが同一である場合、もちろん、パフォーマンスの違いはあり得ません (少なくとも、現在使用しているコンパイラ/バージョンでは違います)。

そうは言っても、質問に対するより概念的なアプローチは、2 つの質問を自問することです。

  1. 2 つのコードは、考えられるすべての有効な入力変数値に対してまったく同じ動作を定義しますか?それとも、期待する入力に対して同じ動作のみ (または同様の動作でさえ) を定義しますか?

  2. それらがまったく同じ動作を定義している場合、コンパイラがこれを簡単に確認できると思いますか?

その場合、パフォーマンスの違いは「ありません」。コンパイラは、説明されている動作を実現するための最も効率的な方法であると考えるものに両方をコンパイルする「必要がある」ためです。もちろん、コンパイラが非常に愚かな場合もあるので、本当に問題がある場合は、確認することをお勧めします。

あなたの場合、コードの両方のバージョンがまったく同じ動作を定義しています。最適化が完全に無効になっている場合を除いて、それらを異なる方法でコンパイルしたコンパイラを見つけるのは難しいと思います。

于 2012-04-29T22:50:34.053 に答える
0

パフォーマンスに違いはありませんが、明らかに 2 番目の方が優れています。

1 つ目は、ファイルを開こうとする試みと、ファイルを開く成功のテストとを分離します。

2 つ目は、ファイルを開いて成功するかどうかのテストを 1つの操作にします。これはまさに、コード化するだけでなく、それについてどのように考える必要があるかということです。それらを 2 つの別個の操作と考えるべきではありません。ファイルを開く操作は、ファイルが正しく開いたかどうかを確認するまで完了しません。

開くこととテストすることを 2 つの別個の操作として扱うことは、ずさんな思考につながる怠惰なコーディングです。やらないでください。

于 2012-04-29T21:30:41.600 に答える