2016-10-14 18 views
16

if-elseステートメントをC言語で記述するとき、 "等しくない"オペレータを優先的に使用する理由はありますか?両方が同じ結果を生み出すことができる時は?if-elseステートメントの "等しい"オペレータと "等しくない"オペレータ

次のコードは、コンテキストを示しています。これにより、引数countが2の場合、文字列がユーザから取得されます。しかし、引数の値が他にあれば、エラーメッセージが表示されます。

int main(int argc, string argv[]) 
{ 
    string msg; 

    if (argc == 2) 
    { 
     msg = GetString(); 
    } 
    else 
    { 
     printf("ERROR: Please only enter a single key! \n"); 
     return 1; 
    } 

しかし、私は「に等しいではない」、および関連するアクションを弾くことにあれば、他のループの条件を変更することにより、上記とまったく同じ結果を達成することができます。以下を参照してください:

int main(int argc, string argv[]) 
{ 
    string msg; 

    if (argc != 2) 
    { 
     printf("ERROR: Please only enter a single key! \n"); 
     return 1; 
    } 
    else 
    { 
     msg = GetString(); 
    } 

とにかく、両方とも同じ結果が得られますが、どちらか一方を優先的に使用する必要がありますか?

+0

もしそれが重要だと思うなら、あなたはコンパイラがそれほど簡単な変換を行うと期待するべきです。 – jamesdlin

+0

'main()'がそれらの配列を受け入れるので、このコードに 'string'が何であるかという疑問もあります。 'string'が' char * 'と等価でなければ、コードは未定義の振る舞いをします。 'GetString()'が 'char * '以外のものを返すと、未定義の振る舞いも潜在的にあります。このコードスニペットで未定義の振る舞いがある場合、 'if'ステートメントの実装方法に関する議論は疑問です。 – Peter

+8

原則を問わず、すべてのコーディングスタイルの質問を締め切らせてもらえますか?これらのことは議論するのに非常に重要であり、どこにでもフォーラムはありません。プログラミング本は、典型的にスタイルは言及しておらず、プログラマーもそうではない。その結果、すべてのCおよびC++プログラムの大半は、読み込み不能なものです。ベテランプログラマーのスタイルに関する実践的な議論を聞くことは、誰にとっても非常に役に立ちます。 SOはこの目的には理想的です。 – Lundin

答えて

12

C++には1つの技術的な理由があります。その理由は、==!=以上に使用する習慣がある場合、多くの演算子をオーバーロードする必要がないからです。

これは、関数オブジェクト(「ファンクタ」)を扱うときに重要です。たとえば、標準のコンテナクラスを使用して独自のカスタムオブジェクトを格納し、それらを自動的にソートする場合などです。関数オブジェクト(std :: equal_toなど)が機能するには、クラスが==演算子のみをオーバーロードする必要があります。 ==!=の両方をオーバーロードする必要はありません。

同様に、他の関数オブジェクトでは、<にオーバーロードするだけで、すべてが< > == != <= >=でないことが必要です。


一般的に、否定は人間の脳が理解するのは容易ではありません。特に二重否定がある場合。順序が技術的に重要でない場合は、最初に等価チェックを書くことは、ほとんどのプログラミング言語でカスタムです。ほとんどの場合、コードを読みやすくなります。

しかし、しばしばプログラミングとコーディングスタイルでは、黒または白のルールはありません。チェックの理由がエラーを見つけることである場合、エラー処理を書き込む最も読み易い方法が「人間は読み込みを困難にする」よりも優先されます。私たちはこれにさらに多くのエラー処理を追加する必要が想像し

if(input == good) 
{ 
    if(format == expected) 
    { 
    do_stuff(); 
    return ok; 
    } 
    else 
    { 
    return error_format; 
    } 
} 
else 
{ 
    return error_input; 
} 

は、これもよく書かれていないコードを考えてみましょう。非常に一般的なケース:多くのエラー処理を含むパーサまたはデータプロトコルデコーダを作成しているとします。ネストされた中括弧の複数のレベルは、すぐにコードを完全な混乱に変えるでしょう。

==から!=に変更すると、ifステートメントをネストする必要がなくなります。

if(input != good) 
{ 
    return error_input; 
} 

if(format != expected) 
{ 
    return error_format; 
} 

// if we got here then all is well 
do_stuff(); 
return ok; 

これは非常に読みやすく、我々はより多くのエラーチェックを追加する必要がある場合は十分に拡張されます。だから!=に変更することで、コードを読みやすくしました。

13

これは単なるコーディングスタイルの問題です。

ところで
int main(int argc, string argv[]) 
{ 
    if (argc != 2) 
    { 
     printf("ERROR: Please only enter a single key! \n"); 
     return 1; 
    } 

    string msg = GetString(); 
} 

::私はメインのロジックをネスト嫌い、私はそれを記述しますmainのsignatrueはint main(int argc, char *argv[])でなければなりません。

+1

"ちょうど"スタイルの問題かもしれませんが、それでも良いスタイルを持つのは良いことです。 Cの場合、特にOPの質問のどちらのオプションよりも、あなたのソリューションははっきりとよりクリーンで、より慣用的です。 –

5

私は通常、人間と同じようにコードを「読みやすく」するため、「同等」を好む。コードを単純化します。ランタイムにはまったく影響を与えないので(「以前の会社のコーディングガイドラインの一部だった」)、「ルール」よりも「いいコーディングガイドライン」と呼ばれることになります。この

チェック:

if (!isEmpty()) 

それはテストは、あなたが書いた場合よりも、何をするかを理解するために数ミリ秒よりあなたの脳を取る:

if (isEmpty()) 

それは実行時に影響を与えない場合であっても、私は通常、「等しい」と「それは等しくない」を好む。

同じ引数は、変数と関数名になります。 isSet属性/方法をisNotSetよりも優先してください。 if (!isNotSet())のようなコードを読むことは、たとえ最後に同等であっても、if (isSet())よりも簡単です。

あなたは、コードを使用している場合は、上制御することはできませんし、この1つは、その後、負の質問に答えるメンバーを提供します。

if (!isNotSet()) 
0

if (isNotSet()) 

は間違いなくよりも、開発者のための読みやすいですこれはプログラム設計の質問です。プログラマは、実行、メンテナンス、可読性、およびパフォーマンスのためにどれが良いかを判断する必要があります。さらに、これらは全く異なる2つのステートメントです。 argcが2のときにGetString()を呼び出すよりも、あなたの関数が呼び出すようにしたい。数字が2でないときはいつでも。

+0

質問の2つのコードスニペットは同じ動作をします。 – user3386109

1

他の人が言っているように、それはスタイルの問題です。本当の違いはありません。

ただし、一貫性を保つことを心がけてください。あるブロックでvalue1 == 2をチェックしている場合は、次のブロックチェックを行わないでください。value2 != 4。唯一の悪いスタイルは矛盾したスタイルです。コンパイラによって適用され、より簡単な最適化がは「意図実行フローを混乱させる可能性があるので

+0

'value1 == 2 'のときに関数の論理を短絡し早期に返すことができ、' value2 == 4'のときにロジックの重要な部分が適用されない場合はどうなりますか? if(value2!= 4){} else {/ * logic * /} 'よりもクリーンで、' if(value2!= 4){/ * logic * == 4)){/ * logic * /} 'となります。型に両方の演算子が定義されていると仮定すると、テストする必要があるものに最も適したものを使用する方が一般的です。 –

0

は今日では、2例の間には意味的な違いはありません。

おそらく30〜40年前に、Cコンパイラのコード生成ステップが書かれたコードにかなり忠実であったときに、2つの選択の間に多少の違いがあるかもしれません。

実際の違いは、今日の構文とスタイルの明確さです。だから、

、書き込み中に

while(*dst++=*src++); 

if(! isOK()) 
    dontDoIt(); 
else 
    doIt(); 
に見られるよう

が、今日、

for(i=0; src[i] != 0; i++) 
    dst[i] = src[i]; 
dst[i] = '\0'; 

後者は一般的に、より読みやすいかもしれないような非常に同じマシンコードを生成することができ

および

if(isOK()) 
    doIt() 
else 
    dontDoIt(); 

「明快さ」は絶対的な値ではなく、読者や査読者の「プログラミングのスキルと味」だけでなく、コード自体にも依存します。

ボトムライン:あなたのものを選択し、均一性のためにそれに固執する!

関連する問題