首页
社区
课程
招聘
c语法,谁来解释下?
发表于: 2010-5-6 16:52 5661

c语法,谁来解释下?

2010-5-6 16:52
5661
int i=1;
        int a = 1;
        switch (i)
        {
        case 0:
                if (a)
                {       
                        ;
                }
                else
                {
        case 1:
                break;
                }
        default:
                break;
        }

竟然天煞的能编译通过  我去死好了  谁来解释下啊~~~~

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 492
活跃值: (51)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
耐人寻味,竟然这样也能通过?
2010-5-6 17:18
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
3
看来case是包不住的,优先级很高
2010-5-6 17:23
0
雪    币: 268
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
GUX
4
确实很怪异啊, 抓狂....
2010-5-6 17:25
0
雪    币: 46
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
i!=0,所以应该直接是case 0,然后就转到default退出了,case 0里面的语句没有语法错误所以不报错。
2010-5-6 17:28
0
雪    币: 46
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
或许可能跟编译器也有关系呢,楼主用什么编译的?
2010-5-6 17:30
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
编译器优化的缘故
2010-5-6 21:25
0
雪    币: 4911
活跃值: (145)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看样子LZ的RP值比较高
呵呵
2010-5-6 21:37
0
雪    币: 424
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
case 和 label的原理基本一样的,所以这本来就是符合标准的做法,而且还有很多专门利用这个特性的程序
2010-5-6 21:53
0
雪    币: 119
活跃值: (10)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
10
我猜,如果把case语句理解为标号,那么程序是可以理解的
case只是告诉程序可以跳到哪里,但case本身只是相当于标号的伪代码,不会影响程序的正常流程

(晕,又慢了。。 那也留着吧,和LS的想法差不多,虽然只是猜测。。)
2010-5-6 22:01
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
从语法上来说,这个例子没有错。C标准里,没有规定swich里的case,必须是在同一个深度的大括号里。
  int i=1;
  int a = 1;

  switch (i)
  {
    case 0:
      printf("case 0:");
      switch (i)
      {
          case 1:
          printf("case 0:  case 1:");
           break;
       }
       break;
    case 1:
        printf(" case 1:");
        break;
    default:
        break;
  }
在这个例子里,两个 case 1:,外层的swich是会忽略掉内存swich里的那个。但lz举的例子里,是合法的情况,没必要报错。
2010-5-6 22:03
0
雪    币: 281
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
这位兄弟的代码应该运行不了把?我这边运行提示出现重复的case 1:~~~~~~~~~~~~
2010-5-6 22:10
0
雪    币: 75
活跃值: (803)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
在网上看到有介绍c语言 switch语句 对应的文法
A →switch ( E) {
W→A case C:
W→I case C:
I →WS ;
D →I default :
M →DS ;}
其中M代表整个switch语句,S代表语句
及标签对应的文法:
labeled_statement ->
         IDENTIFIER ':' statement
        | CASE constant_expression ':' statement
        | DEFAULT ':' statement

楼主的这种写法是能够根据switch语句的文法进行自底向上进行移入-归约 ,编译器不会报错。
S 代表   if (a)
    {  
      ;
    }
    else
    {
  case 1:
    break;
    }

只不过case 1:被当做S其中的一部分移入,红色部分一起被归约为S。我不认为 if (a) { ;}else { 这残句可以进行归约。也就是说编译器认为 case 1 是S的一部分,而不是W的一部分。
虽然这么理解可以回答编译器不报错的疑问,但这样的话编译器会漏掉一个switch分支,在后面生成代码的时候又不知道它怎么能搞定这种情况。

初学编译原理,偶等高手来批评
2010-5-6 23:41
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
4:        int i=1;
0040D418   mov         dword ptr [ebp-4],1
5:      int a = 1;
0040D41F   mov         dword ptr [ebp-8],1
6:      switch (i)
7:      {
0040D426   mov         eax,dword ptr [ebp-4]
0040D429   mov         dword ptr [ebp-0Ch],eax
0040D42C   cmp         dword ptr [ebp-0Ch],0
0040D430   je          main+3Ah (0040d43a)
0040D432   cmp         dword ptr [ebp-0Ch],1
0040D436   je          main+49h (0040d449)
0040D438   jmp         main+50h (0040d450)
8:      case 0:
9:        if (a)
0040D43A   cmp         dword ptr [ebp-8],0
0040D43E   je          main+49h (0040d449)
10:       {
11:         a = 2;
0040D440   mov         dword ptr [ebp-8],2
12:       }
13:       else
0040D447   jmp         main+50h (0040d450)
14:       {
15:     case 1:
16:         a = 6;
0040D449   mov         dword ptr [ebp-8],6
17:       break;
18:       }
19:     default:
20:       break;
21:     }
22:   }
0040D450   pop         edi
0040D451   pop         esi
0040D452   pop         ebx
0040D453   mov         esp,ebp
0040D455   pop         ebp
0040D456   ret

编译器后会直接执行case1的语句,看来case比if else优先级要高啊
2010-5-7 00:14
0
雪    币: 2347
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
if else
本来就在case 0内部!!
有什问题??
2010-5-7 00:46
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
16
其实 swich case结构就是一堆goto语句
这样理解就好多了
举个例子:
swich(i)
{
case 0:
something0;
break;
case 1:
something1;
case 2:
something2:
default:
somethingdefault;
break;
}
somethingout;

伪代码
cmp i,0
jz something0;
cmp i,1
jz something1;
cmp i,2
jz something2;
jmp somethingdefault;

something0:
jmp somethingout;
something1:
something2:
somethingdefault:
jmp somethingout;
somethingout:
2010-5-7 12:10
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
我在xp下使用vs2005和MinGW编译,均通过,无报错。

int i=0;
输出:case 0:


int i=1;
输出: case 1:
2010-5-8 00:02
0
游客
登录 | 注册 方可回帖
返回
//