2016-10-12 6 views
20

int i = 5のような宣言の戻り値/型は何ですか?forループの条件として変数宣言がうまく機能するのはなぜですか?

なぜ、このコードはコンパイルされません。これは

#include <iostream> 

void foo(void) { 
    std::cout << "Hello"; 
} 

int main() 
{ 
    int i = 0; 
    for(foo(); int i = 5; ++i)std::cout << i; 
} 
+1

'int i = 5'は有効な式ではありませんか?そして、かっこ内に有効な式が必要です。 –

+0

2番目のプログラムがコンパイルされても、あなたは無限ループに襲われます。それは端末に印刷 '5'を維持します。 – abhiarora

+1

もっと興味深いのは、iを0に初期化するとfalseを返すということです。 –

答えて

25

forループのいずれかであることを条件が必要です式または宣言:

条件 - のいずれか

  • は、文脈上boolに変換可能な式です。この式は各反復の前に評価され、falseが返された場合は ループが終了します。
  • ブレースまたはイコールイニシャライザによる単一の変数の宣言。イニシャライザは各反復の前に評価され、宣言された変数の値がfalseに変換される場合は 、ループは が終了します。

(int i = 5)==5は全く有効でexpressionではありませんので、第一のコードは動作しません。 (宣言でもありません)operator==のオペランドも式になりますが、int i = 5は式ではなく宣言です。

int i = 5の場合の2番目の有効なケースと一致するため、2番目のコードが動作します。; aで初期変数が1つの変数の宣言。判定のためにiの値はboolに変換されます。常に5であり、無限ループにつながります。

+1

forループの条件部分に変数を宣言することはできませんでした! –

2

このコードはacutally準拠していない間

#include <iostream> 

void foo(void) { 
    std::cout << "Hello"; 
} 

int main() 
{ 
    int i = 0; 
    for(foo(); (int i = 5)==5 ; ++i)std::cout << i; 
} 

を:

for (foo(); int i = 5 == 5; ++i) 

をそれは、5 == 5場合は、これに私を設定するチェックブール結果(1) - >無限ループ

for(foo(); int i = 5; ++i) 

これは単に5に設定された後iの値をチェックし、そうboolに変換するとき...それは同様に常にtrueだ - >無限ループ

+0

'i!= NULL'はちょっと変わっていますが、あなたは' i!= false'を意味するかもしれませんか? – songyuanyao

+0

NULL == 0なので、私はここで奇妙なものは見えません。私はブール値ではありません。ちょっと、上記の答えは良いです;) – Treycos

+0

より正確には、 'i'の値は' bool'その後、判断に使用されます。このプロセスでは、「NULL」または「0」は含まれません。とにかく、結果は同じです。 – songyuanyao

0

Cプログラミング言語のforループの構文は次の通りである:

for (init; condition; increment) { 
    statement(s); 
} 

初期化ステップが最初に実行され、一度だけれます。 initを使用して ループ制御変数を宣言して初期化することができます。

次に、条件が評価されます。真の場合は、ループ本体 が実行されます。 falseの場合、ループの本体は実行されず、 'for' ループの直後に制御の流れが次の文にジャンプします。

'for'ループの本体が実行された後、制御の流れはインクリメントステートメントに戻る をジャンプします。このステートメントにより、 はループ制御変数を更新できます。

for(foo(); (int i = 5)==5 ; ++i)std::cout << i; 

上記の文はエラー(GCCを使用してコンパイル)は、次のあなたを与えるだろう:C

error: expected primary-expression before ‘int’ 
     for(foo(); (int i = 5) == 5; ++i)std::cout << i; 

    error: expected ‘)’ before ‘int’ 

一次式はかなりのいずれかであることができ、あなたの最初のプログラム文を考慮

品物数:

a name (of a variable or a function) 
a typename 
an operator 
a keyword like if or while 
the list goes on and on ... 

このエラーは、文(int i = 5) == 5が有効な式ではなく、コンパイラが他の方法で解釈しようとしているためです。しかし、int i = 5の宣言は、conditionの有効な条件としてforループを使用することができます。この宣言は、initializerという値(2番目のプログラムでは5)と評価されます。ただし、2番目のプログラムは無限ループになり、端末には5の印刷が行われます。ただし、イニシャライザの値が0の場合は、最初のチェックで条件がfalseに評価され、forループボディは一度も実行されません。

+0

あなたが与えた見積もりは、 "条件"部分の変数を宣言することについて何も言わず、 "init"部分の宣言のみを言います(宣言は他の部分では許されないというヒントです)。また、CとC++の間に違いがあるかもしれません。 – ilkkachu

+0

私はそれを以下に述べました "しかし、2番目のプログラムはint i = 5として動作します。この宣言は2番目のプログラムで5のイニシャライザの値に評価されるので、forループの条件チェックの有効条件として使用できます。" – abhiarora

-3

第2の例では、チェック文が初期化されているため、forループの構文に従って初期化文が最初に来て、次に検査とそれ以降の更新が行われますが、iは検査の一部として5として初期化されます。 forループは継続されます。あなたがfoo()の代わりに0を入れた場合は戻り値の型がvoidであるとして、初期化中のfoo()呼び出しを使用して

がforループに違いはありません、は、あなたが同じ出力が得られます

ここでは、最初の例であるを考えてみましょう.2番目の例と同じように、あなたのチェック文は初期化であり、そこにそれらの括弧がないとうまくいくでしょう。 宣言は値を返さないので、(int i = 5)は値を返さないため、 "== 5"の5と比較することはできません。

しかし、あなたはをしようとした場合 "のために(FOO();私は= 5 == 5 int型; ++ I)..."、チェックステートメントは、int型I =(5 =と同じようにコンパイル= 5)。 5 == 5が真であるため、値1を返し、iの値として初期化されます。したがって、出力は11111 ......

TL; 宣言は値を返さないため、(int i = 5)は値を返しないため、5と比較することはできません。第1の例のように「== 5」

問題を解決しました。

+0

_宣言は値を返さないので(int i = 5)...比較することはできません... " - しかし、質問はなぜそれが暗黙的に比較されるのか第二の例では真実のために。あなたの答えには少し矛盾がありますか?私は 'int i = 5 == 5'がどのようにそれに来るのか分かりません。なぜなら、それはちょうど質問のスニペットに似ている' int i = 1'を言うちょっとした方法だからです。 – ilkkachu

+0

int i = 1と言っても、検査文の宣言であるため、実行可能である限り、コンパイラは気にしません。したがって、チェックする必要があるかどうかをチェックする代わりに、iを1に初期化し続けます。if条件で初期化を試行してください。 if(i = 1){...}のようなものは、iは1に初期化され、if文が実行されます。 – Zac

関連する問題