3

変数を宣言して初期化するか、単に宣言する方が良いですか? 最善かつ最も効率的な方法は何ですか?

たとえば、次のコードがあります。

#include <stdio.h>

int main()
{
    int number = 0;

    printf("Enter with a number: ");
    scanf("%d", &number);

    if(number < 0)
        number= -number;

    printf("The modulo is: %d\n", number);

    return 0;
}

を初期化しない場合number、コードは正常に動作しますが、知りたいのですが、それはより高速で、より優れており、より効率的ですか? 変数を初期化してもよろしいですか?

4

6 に答える 6

10

scanf失敗する可能性があります。その場合、には何も書き込まれませんnumberしたがって、コードを正しくしたい場合は、コードを初期化する必要があります(またはの戻り値を確認してくださいscanf)。

間違ったコードの速度は通常は関係ありませんが、たとえばコードの場合、速度にまったく違いがある場合は、それを測定できるとは思えません。0に設定するintと、I/Oよりもはるかに高速になります。

于 2013-03-04T12:14:49.327 に答える
3

変数を初期化せず、コードにバグがある場合(たとえば、数値を読み取るのを忘れた場合)を想定します。その場合、数値の初期化されていない値はガベージであり、実行が異なると、異なる結果が出力(または動作)されます。

ただし、すべての変数を初期化すると、一定の結果が得られます。エラーを追跡するのは簡単です。

はい、ステップを初期化すると、コードに低レベルのステップが追加されます。たとえばmov $0, 28(%esp)、低レベルのコードで。しかし、その1回限りのタスク。コードの効率を損なうことはありません。

したがって、常に初期化を使用することをお勧めします。

于 2013-03-04T12:14:58.687 に答える
3

速度を言語のせいにしないでください。その属性は言語の実装に属します。速い実装と遅い実装があります。高速な実装に関連する最適化があります。十分に最適化されたマシン コードを生成するコンパイラは、初期化が不要であると推測できる場合、初期化を最適化します。

この場合、実際には初期化が必要です。scanf が失敗したかどうかを検討してください。scanf が失敗すると、戻り値はこの失敗を反映します。次のいずれかが返されます。

  1. 読み取りエラーまたは EOF (実装で定義された方法でトリガーされる可能性があります。通常、Windows では CTRL+Z、Linux では CTRL+d) があった場合はゼロ未満の値。
  2. 変換エラーが発生した場合 (たとえば、scanf に指示したときに stdin に「a」を入力した場合) は、scanf に提供されたオブジェクトの数よりも少ない数 (オブジェクトを 1 つしか提供していないため、この失敗の戻り値は 0 になります) '0'..'9' のシーケンスを整数に変換します)、
  3. scanf が割り当てることができたオブジェクトの数。あなたの場合、これは1です。

これらの戻り値 (特に #3) のいずれもチェックしていないため、コンパイラは初期化が必要であると推測できず、最適化して取り除くことができません。変数が初期化されていない場合、これらの戻り値のチェックに失敗すると、未定義の動作が発生します。ニワトリは、頭がなくても生きているように見えることがあります。scanf の戻り値を確認することをお勧めします。そうすれば、変数が初期化されていない場合は、初期化されていない値の使用を避けることができ、そうでない場合は、変数を使用するのではなく、エラー メッセージを生成して誤った戻り値を処理すると仮定して、コンパイラが初期化を最適化できます。

編集:未定義の動作のトピックについては、次のコードで何が起こるかを検討してください。

if(number < 0)
    number= -number;

number が -32768 で INT_MAX が 32767 の場合、-(-32768) は int として表現できないため、C 標準のセクション 6.5、パラグラフ 5 が適用されます。

セクション 6.5、パラグラフ 5 は次のように述べています。

式の評価中に例外的な条件が発生した場合 (つまり、結果が数学的に定義されていないか、その型の表現可能な値の範囲内にない場合)、動作は未定義です。

于 2013-03-04T12:26:19.580 に答える
1

最新のコンパイラでは、効率に違いはありません。コーディングスタイルが主な考慮事項です。一般に、コードを宣言するときにすべての変数を初期化すると、コードがわかりやすくなり、間違いが発生する可能性が低くなります。ただし、あなたが与えた場合、変数はscanfによって効果的に初期化されるので、冗長な初期化を行わない方がよいと思います。

于 2013-03-04T12:15:30.937 に答える
1

プログラマーは変数を初期化しないため、簡単なエラーを何度見たことかわかりません。ちょうど 2 日前に、SO に関する別の質問がありました。直面している問題の最終結果は、単に OP が変数を初期化しなかったために問題が発生したというものでした。

「速度」と「効率」について話すときは、コードがどれだけ速くコンパイルまたは実行されるかを単純に考慮するのではなく (この場合はとにかくほとんど無関係です) 、コードに単純な間違いがある場合のデバッグ時間を考慮してください。非常に簡単にできる変数を初期化しなかったという事実に。

また、私の経験では、大企業向けにコーディングする場合、コベリティやklocworkなどのツールを使用してコードを実行します。これらのツールは、セキュリティ リスクがあるため、初期化されていない変数を検出します。

于 2013-03-04T12:21:39.460 に答える
1

その前に、次の質問に答える必要があります。

1) この関数は何回呼び出されましたか? 10.000.000 回呼び出す場合は、最善を尽くすことをお勧めします。

2) 変数を初期化しない場合、コードは安全であり、例外をスローしないと確信していますか?

その後、int の初期化はコード内でそれほど変化しませんが、文字列の初期化ははいです。

初期化されていない変数がある場合、プログラムにバグがある可能性があるため、すべての制御を確実に実行してください。

于 2013-03-04T12:18:35.517 に答える