c++中为什么不允许跳过变量初始化语句

Expect_excellent 2014-08-08 11:11:26
//错误
goto next;
int a=0;
next:a=2;
cout<<a<<endl;

//成功
goto next;
int a;
next:a=2;
cout<<a<<endl;
...全文
717 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
我看你有戏 2014-08-09
  • 打赏
  • 举报
回复
引用 楼主 u011006816 的回复:
//错误
goto next;
	int a=0;
	next:a=2;
	cout<<a<<endl;
//成功
goto next;
	int a;
	next:a=2;
	cout<<a<<endl;
next:;a=2; 冒号后面加个分号
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
[quote=引用 5 楼 u011006816 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] “变量赋值”和“变量初始化”不是一回事! “变量赋值”发生在运行期,其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期,其写法遵循初始化列表语法规定。
这个我懂。我就是想知道c++中为什么不允许跳过变量初始化语句,对于定义语句却允许跳过,好多规定不是简单的规定吧?里面肯定有它的原因。[/quote] 我只能建议你研读gcc和g++源代码相关片断了.[/quote]老师能告诉我该怎么读吗?我是新手,对您说的东西不胜了解。
风叶落 2014-08-08
  • 打赏
  • 举报
回复
goto这个好陌生啊,问题不是C++不允许,是你没事找事。
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
引用 5 楼 u011006816 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] “变量赋值”和“变量初始化”不是一回事! “变量赋值”发生在运行期,其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期,其写法遵循初始化列表语法规定。
这个我懂。我就是想知道c++中为什么不允许跳过变量初始化语句,对于定义语句却允许跳过,好多规定不是简单的规定吧?里面肯定有它的原因。[/quote] 我只能建议你研读gcc和g++源代码相关片断了.
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
“变量赋值”和“变量初始化”不是一回事! “变量赋值”发生在运行期,其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期,其写法遵循初始化列表语法规定。
这个我懂。我就是想知道c++中为什么不允许跳过变量初始化语句,对于定义语句却允许跳过,好多规定不是简单的规定吧?里面肯定有它的原因。
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
“变量赋值”和“变量初始化”不是一回事! “变量赋值”发生在运行期,其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期,其写法遵循初始化列表语法规定。
神奕 2014-08-08
  • 打赏
  • 举报
回复
不用goto。
shiguojie19892 2014-08-08
  • 打赏
  • 举报
回复
跳过了怎么初始化呀,坦白的说我学c++两年了,从来没有看过goto,也不知道怎么用。 也没有遇到万不得已必须使用的地步。别给自己找麻烦。
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
用{}括住
X MAN 2014-08-08
  • 打赏
  • 举报
回复
编程从不用GOTO。 程序多了,都不知跳到哪里去了。
shiter 2014-08-08
  • 打赏
  • 举报
回复
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
幻夢之葉 2014-08-08
  • 打赏
  • 举报
回复
引用 21 楼 u011006816 的回复:
[quote=引用 16 楼 jianwen0529 的回复:] [quote=引用 9 楼 Saleayas 的回复:] 当你跳过构造的时候,那么在析构的时候,怎么办呢??
这个貌似有点道理。 真实原因貌似就是因为如果goto了,后续在销毁方面有问题。 你可以在这方面想。[/quote]
switch(2)
{case 1:int a=2;break;
case 2: a=3;break;}
a的作用域是从定义开始到},}结束前它会析构,这样解释不就没问题吗?[/quote] 那是我记错了,请看我的19L,里面解释了。
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 29 楼 lovesmiles 的回复:
[quote=引用 27 楼 lovesmiles 的回复:] [quote=引用 26 楼 u011006816 的回复:] [quote=引用 23 楼 lovesmiles 的回复:] [quote=引用 21 楼 u011006816 的回复:] [quote=引用 16 楼 jianwen0529 的回复:] [quote=引用 9 楼 Saleayas 的回复:] 当你跳过构造的时候,那么在析构的时候,怎么办呢??
这个貌似有点道理。 真实原因貌似就是因为如果goto了,后续在销毁方面有问题。 你可以在这方面想。[/quote]
switch(2)
{case 1:int a=2;break;
case 2: a=3;break;}
a的作用域是从定义开始到},}结束前它会析构,这样解释不就没问题吗?[/quote] 晕倒,a的定义都被你跳过了,还怎么构造?如果a的定义没有被跳过即int a=2被执行了,那case 1要来何用?[/quote]照你这么说。
switch(2)
{case 1:int a;break;
 case 2:a=2;break;}
不能用了?[/quote] switch(2) {case 1:int a=1;break;//加上初始化确实不能用 case 2:a=2;break;}[/quote] 实测下面代码也不能用: #include <iostream> using namespace std; class A { public: A(){}; A(int a){}; }; int _tmain(int argc, _TCHAR* argv[]) { switch(2) {case 1:A a ;break;//自定义的类,也无法这样子用 case 2:a=2;break;} }[/quote]这个和string类似,用书上的话说就是存在隐式初始化。就是搞不清为什么能跳过定义,不能跳过定义和初始化
勤奋的小游侠 2014-08-08
  • 打赏
  • 举报
回复
引用 27 楼 lovesmiles 的回复:
[quote=引用 26 楼 u011006816 的回复:] [quote=引用 23 楼 lovesmiles 的回复:] [quote=引用 21 楼 u011006816 的回复:] [quote=引用 16 楼 jianwen0529 的回复:] [quote=引用 9 楼 Saleayas 的回复:] 当你跳过构造的时候,那么在析构的时候,怎么办呢??
这个貌似有点道理。 真实原因貌似就是因为如果goto了,后续在销毁方面有问题。 你可以在这方面想。[/quote]
switch(2)
{case 1:int a=2;break;
case 2: a=3;break;}
a的作用域是从定义开始到},}结束前它会析构,这样解释不就没问题吗?[/quote] 晕倒,a的定义都被你跳过了,还怎么构造?如果a的定义没有被跳过即int a=2被执行了,那case 1要来何用?[/quote]照你这么说。
switch(2)
{case 1:int a;break;
 case 2:a=2;break;}
不能用了?[/quote] switch(2) {case 1:int a=1;break;//加上初始化确实不能用 case 2:a=2;break;}[/quote] 实测下面代码也不能用: #include <iostream> using namespace std; class A { public: A(){}; A(int a){}; }; int _tmain(int argc, _TCHAR* argv[]) { switch(2) {case 1:A a ;break;//自定义的类,也无法这样子用 case 2:a=2;break;} }
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
#include <stdio.h>
#include <setjmp.h>
jmp_buf mark;
int i=0;
void c() {
    printf( "c in\n");
    if (1==i%2) longjmp( mark, i );
    printf( "c out\n");
}
void b() {
    printf( "b in\n");
    c();
    printf( "b out\n");
}
void a() {
    printf( "a in\n");
    b();
    printf( "a out\n");
}
void main( void )
{
   int jmpret;
   jmpret = setjmp( mark );
   printf( "Start %d\n",jmpret);
   if( jmpret == 0 ) {
       printf( "First\n");
       a();
       i++;
       a();
   } else {
       printf( "Second\n");
   }
}
//Start 0
//First
//a in
//b in
//c in
//c out
//b out
//a out
//a in
//b in
//c in
//Start 1
//Second
//
老师虽然看不懂你写的看法,但我能看出你写的是关于构造和析构。 当然你也多次建议我别用goto,这个我知道,我也没用过,只是为了搞清这个原因才用它跳转的。至于无法析构,我感觉这个应该不对吧。因为我在函数内跳转,函数内定义的局部变量的生存周期应该到函数的}才结束,那时候才析构,我的跳转并不会打乱析构的顺序,也不会跳过哪个析构呀!
勤奋的小游侠 2014-08-08
  • 打赏
  • 举报
回复
引用 26 楼 u011006816 的回复:
[quote=引用 23 楼 lovesmiles 的回复:] [quote=引用 21 楼 u011006816 的回复:] [quote=引用 16 楼 jianwen0529 的回复:] [quote=引用 9 楼 Saleayas 的回复:] 当你跳过构造的时候,那么在析构的时候,怎么办呢??
这个貌似有点道理。 真实原因貌似就是因为如果goto了,后续在销毁方面有问题。 你可以在这方面想。[/quote]
switch(2)
{case 1:int a=2;break;
case 2: a=3;break;}
a的作用域是从定义开始到},}结束前它会析构,这样解释不就没问题吗?[/quote] 晕倒,a的定义都被你跳过了,还怎么构造?如果a的定义没有被跳过即int a=2被执行了,那case 1要来何用?[/quote]照你这么说。
switch(2)
{case 1:int a;break;
 case 2:a=2;break;}
不能用了?[/quote] switch(2) {case 1:int a=1;break;//加上初始化确实不能用 case 2:a=2;break;}
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 23 楼 lovesmiles 的回复:
[quote=引用 21 楼 u011006816 的回复:] [quote=引用 16 楼 jianwen0529 的回复:] [quote=引用 9 楼 Saleayas 的回复:] 当你跳过构造的时候,那么在析构的时候,怎么办呢??
这个貌似有点道理。 真实原因貌似就是因为如果goto了,后续在销毁方面有问题。 你可以在这方面想。[/quote]
switch(2)
{case 1:int a=2;break;
case 2: a=3;break;}
a的作用域是从定义开始到},}结束前它会析构,这样解释不就没问题吗?[/quote] 晕倒,a的定义都被你跳过了,还怎么构造?如果a的定义没有被跳过即int a=2被执行了,那case 1要来何用?[/quote]照你这么说。
switch(2)
{case 1:int a;break;
 case 2:a=2;break;}
不能用了?
边走边瞧 2014-08-08
  • 打赏
  • 举报
回复
来比较一下两句代码有啥区别吧:

    int a;
    a = 2;
// 003113BE  mov         dword ptr [a],2 

	int a = 0;
// 00C613BE  mov         dword ptr [a],0 
	a = 2;
// 00C613C5  mov         dword ptr [a],2 
边走边瞧 2014-08-08
  • 打赏
  • 举报
回复
引用 22 楼 go_and_see 的回复:
[quote=引用 14 楼 u011006816 的回复:] 用goto不是我的初衷,我只想知道为什么不能跳过定义并初始化了的变量,显然goto是跳过最直接的办法。谢谢你,我好像懂了。能不能这么理解,如果有初始化语句的话,初始化有可能在编译阶段进行,有可能在运行阶段。如果跳过后,无法判断是否对变量初始化而引发的错误。
下面的代码,其实就是一行汇编,你让C++编译器如何分解为两条汇编指令呢。

	int a;
	a = 2;
// 003113BE  mov         dword ptr [a],2 
[/quote] 更正一下:前面一句说得不对,请忽略。
加载更多回复(15)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧