これは単純な問題のようですが、直感的ではありません。ループ内のデータ型の定義
は、あなたがこのようなループがあるとしましょう:
int i;
for(i=0;i<10;i++){
float b = 25.2;
float c;
c=b+i;
}
は、すべて単一のループにfloatとしてBを定義する任意の負の影響はありますか?小さながあり、
おかげで...
これは単純な問題のようですが、直感的ではありません。ループ内のデータ型の定義
は、あなたがこのようなループがあるとしましょう:
int i;
for(i=0;i<10;i++){
float b = 25.2;
float c;
c=b+i;
}
は、すべて単一のループにfloatとしてBを定義する任意の負の影響はありますか?小さながあり、
おかげで...
これは完全に大丈夫です。ループ内にfloat
しか使用していないのであれば、これは問題ないと思います。
コードの明瞭さはループに入れるのが理にかなっていますが、主に味の問題です。
しかし、私は似たような状況が追跡するのは難しいバグになり、コンパイラの警告を生成しない見てきました
int i,j;
for (i=0;i<count;i++)
{
int j;
// stuff
}
のような状況に注意してください。ちょうどテスト
編集、gcc
は異なり、コンパイルんが、-O3
で生成されたアセンブリは同じです。 gcc -S file.c
でテストしてください。更新:-O1
で十分です。実際には変数を宣言する順序によって異なります。あなたの例でfloat
がint i;
以下と宣言された場合、コンパイルされたアセンブリは同じです。
は、コンパイラが、ここで最適化しないと仮定すると...私はそれを持っているだろうと思ったが、私はこれで動作するコードを見てきましたので、それほどわかりませんすべてのループにフロートを割り当てる際に支払われるペナルティ。フロートをループの外に宣言する方がいいでしょう。
ただし、コードによって異なります。時には、そのような変数を宣言する方がきれいです。あなたがパフォーマンスで支払う価格はおそらくかなり小さいです。
b
を初期化していないため、使用して未定義の動作を呼び出しています。
パフォーマンスの問題が懸念される場合、コンパイラは割り当てを最適化するだけです。
oops、bの値の初期化を修正するためのコードを編集しました。 –
これはまったく問題ではありません。また、この記事を見てみたいことがあります[1]
[1] Difference between declaring variables before or in loop?
ありがとうございました、リンクは役に立ちました! –
うれしい私は助けることができました! – Chris
あなたはそれだけでその範囲を制限ブロック(中括弧で囲まれたもの)で変数を定義する場合、あなたは「できますそれを外で使用しないでください。プログラムをよりクリーンにするだけです。
プログラムあなたの変数を開始bracetでスタックに配置し、閉じるbracetで変数を割り当てますが、良いコンパイラはサブルーチン(メソッド)を入力して終了する時点で実行する必要があります。
また、これはC++の機能であり、実際には構造化されたプログラミングに一歩踏み込んでいます(また、C++プログラミングはスクリプト言語を使用するようなものですが、変数を宣言する必要はありません深刻なCまたはJavaプログラマーにこれを伝えてください)。
私が知る限り、ブロックの先頭に変数を宣言するのは、Cの機能であり、特にC++ではありません。 – mvds
C++では、ブロック内の任意のポイントで新しい変数を任意に宣言できますが、厳密なC89ではブロックの先頭でのみ可能です。これはこの例には当てはまりません。 C99では、C++と同じ変数宣言動作も可能です。この動作はGNU gccのようなコンパイラ拡張の一部です。 – birryree
私はすべてのローカル変数がコードの前にリストされる必要があった昔は覚えています。たぶん、以前のC標準でした。 (あるいは多分私は間違っていることを覚えています。私は非常に古くなりました!)Cmでは、宣言は関数ではなく*ブロック*の先頭になければならないと言います。http://docs.hp.com/ja/92501 -90029/ch01s03.html#d0e837うん、おそらくあなたは正しい。 – ern0
C99コンパイラの前では、同じスタックスペースが各繰り返しに使用されることが多いため、実際にはループ内の変数を宣言するためのパフォーマンスに影響はありませんでした。 。私はC99コンパイラが似たようなことをすると思いますが、わかりません。
ほとんどのコンパイラはこれを最適化します。最悪の場合は、スタック上に新しいフロートを作成することです。これは、ほとんどのアーキテクチャでは非常に安価な操作です。使用直前に変数を宣言する方が早い場合もあります。しかし、あなたのプログラムがパフォーマンスに影響を受けていれば、まずアセンブリ言語を使用しているはずです。
C99以降では、以前のバージョンのCではあいまいな変数が作成されたループにスコープされることを指定します。異なるコンパイラはそれを別々に実装します。ループを含む関数のスコープ内に同じ名前の変数が存在する場合(変数が関数のスコープとして扱われるため)、C99コンパイラの命名の競合に遭遇する可能性があるので、これは注意することが重要です。
個人的には、私は常にループ内の変数を宣言します。それはよく実行され、そのループで使用される変数が存在することを明確に示します。それは、そのコードの意図を明確に示すようにコードを構造化することです。
これは-03と-01とは何ですか? –
@O_O:GCCの最適化レベルは-O1から-O3までです(数字は0ではなくOです)、コードを "少し"から "かなりたくさん"最適化するようにコンパイラに指示します。 '-Os'は、コードサイズを最適化するようにコンパイラに指示します。 http://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there – nmichaels
これらは最適化フラグです。数字が高いほど、トリックが多くなります。しかし、Cコードとの1対1の関係が遠く離れているため、最適化されたアセンブリは高速であるかもしれませんが、より大きくなり、デバッグ(高度に)最適化されたコードは難しくなります。 – mvds