QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1354|回复: 12

就这么个小问题把我给难住了。问了一圈也没人知道为什么

[复制链接]
发表于 2006-5-19 10:09:35 | 显示全部楼层 |阅读模式
switch (a) {
    case 1 :
        int i = 10;    /* 在这里声明变量就报错 */
        foo1();
        foo2();
        break;
    case 2 :
        ;
        int j = 10;    /* 放一条语句在前面就行了 */
        foo1();
        foo2();
        break;

      ...
};

上面的代码编译通不过。大家不妨试一试。报int i = 10;那边有错。
如果说case里面不能声明局部变量,那为什么case 2的写法就可以了?实在想不出为什么。我是在linux2.4.20/gcc3.2.2下编译的。
谁能帮我解释一下,先谢谢了!
发表于 2006-5-19 10:57:43 | 显示全部楼层
把代码再重新整理一下发上来,case 2: 下面的分号是干什么的?
回复

使用道具 举报

发表于 2006-5-19 11:08:35 | 显示全部楼层
用花括号把case1块里的语句括起来
回复

使用道具 举报

 楼主| 发表于 2006-5-19 16:51:18 | 显示全部楼层
TO: 2楼,分号表示一条语句。就是说在声明变量的前面放一条语令就不报错了,要是它是case后的第一条语句就会报错。

TO: 3楼,用花括号括起来肯定是没有问题了。但是书上明明写的很清楚,case里面可以不用花括号的呀。
回复

使用道具 举报

发表于 2006-5-19 17:14:20 | 显示全部楼层
在case里声明变量,如果不把它放在语句块中,是非法的。
在声明前加个语句可以编译通过可能是gcc的特性吧,cl是不行的。
在case里定义变量,如果不用块包含,那么它对于后面的所有case都是可见的,这恐怕不是你想要的结果。
回复

使用道具 举报

发表于 2006-5-19 17:19:22 | 显示全部楼层
你可以查一下C标准,看看怎么回事
回复

使用道具 举报

发表于 2006-5-20 16:34:31 | 显示全部楼层
C语言版本的问题,把 int i; 定义到程序的最前面试试

有些C编译器只能在程序最头上定议变量
回复

使用道具 举报

发表于 2006-5-21 23:51:46 | 显示全部楼层
符号  :   可以代表一种派生关系吧,  比如  class B: public a {}, 虽然派生没有 int 这种情况,但是我感觉从合理性上来看,  可能就是因为这种原因使编译器报错了呢.  建议lz 把出错信息放上来给大家参考一下吧.
回复

使用道具 举报

发表于 2006-5-22 10:45:39 | 显示全部楼层
这个现象挺奇怪。在c语言中根本就不允许在函数中间声明任何变量。
所以这个应该是C++的规则:It is illegal to jump past a declaration with an initializer unless the declaration is enclosed in a block.
一个声明并初始化变量的语句, 在该语句所在的语法范围内,该语句必须被执行,否则编译器就报错。
不过奇怪的是被break掉的语句虽然也有可能永远不被执行,但编译器好像管不了。

例如:
void main(int argc, char* argv[])
{
goto lab1:
    int i  = 1;
lab1:
}
上面的语句int i  = 1;不会被执行, 编译就出错。 把int i  = 1; 改为int i ;就能编译通过但有警告。或者这样
void main(int argc, char* argv[])
{
goto lab1:
    {
    int i  = 1;
    }
lab1:
}

也能通过,因为在int i  = 1;所在的范围内这条语句肯定被执行了.

void main(int argc, char* argv[])
{
goto lab1:
    {
goto lab2;
    int i  = 1;
lab2:
    }
lab1:
}
这样又不能通过,因为在int i  = 1;所在的范围内这条语句没被执行.

void main(int argc, char* argv[])
{
        while(1)
        {
                int m =1;
                m ++;
                break;
                int n = 2;
                n++;
        }
}
上面的int n = 2;
虽然永远不能执行,但它是被break掉的,所以编译器可以编译通过,编译器好像没看见break一样。

一个switch语句是一个语法范围,因为有一个{} ,所有的case在同一个范围内。
一个switch语句除了最后一个case肯定被执行外(去掉所有的break),其它的case都有可能不被执行(就算去掉所有的break也不行,都其实是被goto掉的),所以不能声明初始化变量语句。除非放在{}中。
回复

使用道具 举报

发表于 2006-5-25 17:09:09 | 显示全部楼层
解释的都非常太好。
回复

使用道具 举报

发表于 2006-5-25 17:37:38 | 显示全部楼层
利用了gcc扩展的语句,不要这么写,ansi c标准是禁止的。
回复

使用道具 举报

发表于 2006-6-30 11:12:36 | 显示全部楼层
这个问题我也遇到过,如果你要在case里面再申明变量的话,就一定要用{}括起来, 还有一种方法就是把变量声明放在switch之前, 不用{}也就没有问题. 原因我猜应该是GCC编译器的问题, 具体什么原因就不知道了.
回复

使用道具 举报

发表于 2006-6-30 16:56:45 | 显示全部楼层
c99是允许在其它语句后再声明变量的。
是属于标准里的,不是扩展语句
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-2 12:33 , Processed in 0.044630 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表