ページ 1 / 1
C言語のgotoについて
Posted: 2014年1月21日(火) 15:05
by startcgengo
#include<stdio.h>
int main(void)
{
label:
int x;
scanf("%d",&x);
if(x==1)
goto label;
}
こういうプログラムを書いたのですが
scanfが最初の1回しか代入できません、
gotoでもとに戻るはずなのに何故できないのでしょうか?
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 15:50
by みけCAT
コードはBBcodeを有効にした状態でcodeタグで囲み、
かつ適切にインデントをしていただけると、見やすくてありがたいです。
最初の1回しか代入できていないことをどうやって確かめましたか?デバッガですか?
コンパイル結果のアセンブリを出力してみると、どんな処理がされているかわかります。
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 16:05
by みけCAT
試してみたところ、5行目で
「ラベルは文または宣言の一部にのみなることができます。文になることとは出来ません」
(注:「なることとは」は原文ママ)
というコンパイルエラーになりました。
ラベルとgotoを追加する前の、古いプログラムを実行しているのではないですか?
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 16:15
by softya(ソフト屋)
VC++でC++としてコンパイルした時はコンパイルが通ります。
なお、scanfはちゃんとループしてます。条件を勘違いしていなければですが・・・。
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 17:35
by YuO
startcgengo さんが書きました:scanfが最初の1回しか代入できません、
gotoでもとに戻るはずなのに何故できないのでしょうか?
scanfへの入力として,どのような文字列を与えましたか。
数字と空白以外のものを与えた場合,scanfはxへの代入に失敗し,バッファには元の文字列が残り続けます。
この結果,xが1になった後に失敗すると,xが1のままバッファから数字を取ろうとしては失敗し続けることになります。
e.g.) 入力:"1 x"の場合。
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 18:09
by startcgengo
こういう構造っていうのは
gotl label;という文と、
label:
という文の間に書いた全ての文はもう一回再定義されることになるんですか?
int x;
int x;
のように二回連続で定義したらエラーが出ますが、エラーが出ないという事は
理論的には再定義という事でOKですか?
Re: C言語のgotoについて
Posted: 2014年1月21日(火) 19:12
by softya(ソフト屋)
再定義ではないですね。単なるループです。
変数宣言などのコンパイル時に確定されるものと、実行文の処理を混同していると思います。
Re: C言語のgotoについて
Posted: 2014年1月22日(水) 17:14
by cgengostart
>softyaさん
goto=ループなんですか、だからエラーでないんですね、ループの場合
中に変数宣言があってもエラーでませんもんね、ありがとうございます、解決しました。
Re: C言語のgotoについて
Posted: 2014年1月22日(水) 18:36
by usao
ちょっと気になって↓のコードをVS2012で試したら出力は
Copy Constructor
Destructor
Copy Constructor
Destructor
Copy Constructor
Destructor
Copy Constructor
Destructor
Copy Constructor
だった.
5回のループでのT2は全て別の物なのだな.
コード:
class CTest
{
public:
CTest(){}
CTest( const CTest &rhs )
{
std::cout << "Copy Constructor" << std::endl;
}
CTest &operator=( const CTest &rhs )
{
std::cout << "operator=" << std::endl;
return *this;
}
~CTest(){ std::cout << "Destructor" << std::endl; }
};
int main( int argc, char **argv )
{
int iter_count = 0;
CTest T1;
label:
CTest T2 = T1; //ここで何と表示されるか?
if( iter_count++ < 5 )
{ goto label; }
return 0;
}