2012-04-29 3 views
4

私は現在C言語を学んでおり、次の2つのコードが異なった動作をするのか、単なるスタイルのものなのかを知りたかったのです。私の教授は彼のノートに次のコードをしたがif文の中にfopenの結果を代入する

... 
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行を置く利点があるかどうかを判断する。

答えて

5

違いはありません。多くの経験豊富なプログラマは、行を保存するために2番目の形式を使用することがありますが、は本質的に同じです。 2番目はもう少し "UNIX-y"になりがちです。ここでは、大部分の関数呼び出しは、成功する前にエラーがないかどうかチェックされてから続行されます。

+2

2番目のスタイルは 'if(condition &&(pFile = fopen(" foo "、" r "))= NULL)'のような状況に利点があります。言及する価値があるかもしれません。 –

+0

@ダニエルフィッシャー、はい。その回線は短絡評価を使用しており、ファイルは 'condition'が真の場合にのみ開かれることを指摘しておきます。 –

1

(pFile = fopen("myfile.txt", "r"))pFileを返すので、それらは同じですが、私は個人的にはより明示的ですから個人的に好きです。

1

これらの2つの変種は同等です。パフォーマンスには影響しません。しかし、私はそれが物事をより明確にするので、最初の変種がより良いと思う。

0

性能に違いはありませんが、2番目の方が明らかに好ましいです。

最初のファイルは、ファイルを開く際にファイルが正常に開かれたかどうかをテストするために開きます。

ファイルを開き、成功のためのテストをという単一のの操作と呼びます。これは、コード化するだけでなく、どのように考えるべきかを示しています。それらを2つの別々の操作と考えるべきではありません。ファイルが正しく開かれているかどうかをチェックしていないかぎり、/を開くまでファイルを開く操作は完了しません。

オープンとテストを2つの別々の操作として扱うことは、怠惰な思考につながるレイジーコーディングです。それをしないでください。

1

どちらのプログラムも同等です。

第1のスタイルは、読みやすく、第2のスタイルがよりコンパクトであると言う人がいます。

いくつかのコーディングガイドライン(MISRAの1つ)では、2番目のスタイルは禁止されています。 MISRAは、ifステートメントの制御式の代入演算子の使用を禁止しています。

0

ここで言うように、2つのセグメントは明らかに同一です。しかし、代入演算子=と等価演算子==の間の混乱を避ける傾向があるので、私は最初を好むでしょう。 foo(arg)がintを返す関数がある状況を考えてみましょう。表現(Y =のタイプので

int y; 

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

:あなたは平等(BTW式の場合では非常に一般的)と代入演算子を混同しましょう、今

int y; 

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

:あなたのような何かを書くだろう= foo(x))はintであり、上記はコンパイラによって正当なCコードとみなされます。これは明らかにあなたのコードにバグを作り出します。

int y; 

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

は明らかに、今あなたが平等で割り当てを混同する可能性が低い:

は今、最初のオプションを検討することができます。さらに、あなたが書く場合でも、y == foo(x);ステートメントとしてを実行すると、コンパイラは警告を出します。

0

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

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

  1. コードの2枚だけで、すべての可能な有効な入力変数値のため、全く同じ動作を定義する、またはください:前記、質問へのより概念的なアプローチは、自分自身に2つの質問をすることであると

    あなたが期待するインプットの同じ振る舞い(まさにまったく同じ振る舞い)?

  2. コンパイラがまったく同じ動作を定義している場合は、コンパイラがこれを見るのは簡単だと思いますか?

その場合、コンパイラはそれを説明した動作を実現するための最も効率的な方法であると考えて何にそれらの両方をコンパイルする「必要がある」ので、パフォーマンスの違いは「いけません」。もちろん、コンパイラはかなり愚かなことがあります。実際に問題がある場合は、チェックしてください。

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

+0

そのチップをありがとう。 – Peter

関連する問題