如何在switch case中定义变量(不用花括号)

这个周末有幸见到了几位神交已久的库友(天天/迪迪/丁丁),大家一起扯了些有的没的,很开森!

天天考了我一个问题,在C语言里面,如何在switch case中定义一个变量?要求是不用花括号

这个问题是背景是,下面的代码是编译不过的,因为在case后面不能直接定义变量。

switch (v) {
   case 1:
      int a;
      get_value_of_xx(&a);
      set_yy(a);
      break;
   case 2:
      //do_sth
      break;
   defalut:
      break;
}

天天问我用什么特殊的招式可以化解这个编译错误?(加花括号不算)

答案竟然是把

case 1:

改成

case 1:;

加一个分号,是不是觉得很有趣?是不是百思不得其姐?(反正我是)

天天给我讲了一个我以前从未意识到的问题,case 和 defalt 其实都是标签,这么一说我一下子就明白了达夫设备的工作原理(虽然老早就知道达夫设备,但没有悟透)

维基百科上有对达夫设备的介绍 http://zh.wikipedia.org/wiki/%E8%BE%BE%E5%A4%AB%E8%AE%BE%E5%A4%87

send(to, from, count)
register short *to, *from;
register count;
{
	register n = (count + 7) / 8;
	switch(count % 8) {
	case 0:	do {	*to = *from++;
	case 7:		*to = *from++;
	case 6:		*to = *from++;
	case 5:		*to = *from++;
	case 4:		*to = *from++;
	case 3:		*to = *from++;
	case 2:		*to = *from++;
	case 1:		*to = *from++;
		} while(--n > 0);
	}
}

我把C99标准拿出来学习了一下,标签的巴科斯范式:

(6.8.1) labeled-statement:

identifier : statement

case constant-expression : statement

default : statemen

如天天所说,case和default都是标签。

那么 statement 的巴科斯范式是怎么样的呢?

(6.8) statement:

labeled-statement

compound-statement

expression-statement

selection-statement

iteration-statement

jump-statement

标签后面几乎什么都可以,但唯独不可以是 declaration expression  (定义变量的表达式)

也就是说,可以这样

case 1:
{
  int a;
}

但不可以这样

case 1:
  int a;

因为上面的写法不符合标签的巴科斯范式,编译器在做语法分析的时候报错

但是一旦写成

case 1:;
   int a;

编译就通过了,因为分号作为空语句,完全符合标签的巴科斯范式

这篇文章话只说了1/3,至于为什么标签后面(紧接其后)不能定义变量? C++又是怎么样的? 请读者自行思考和试验,我只负责抛砖。

今天冬至,太困了,不写了。

时间: 2024-10-11 18:29:41

如何在switch case中定义变量(不用花括号)的相关文章

case中定义变量

1.c语言switch/case中定义变量 case 0: int b = 0 ; printf("0");break; case 1: printf("1");break; default: printf("default");break; C和C++都会报错 情况1: case 0: int b; b = 0 ; printf("0");break; case 1: printf("1");break;

PHP字符串中的变量解析(+教你如何在PHP字符串中加入变量)

定义字符串的时候,用单引号或者双引号都是可以的.我个人习惯是用双引号.在输出字符串的时候,若字符串中含有字符串变量,使用单引号和双引号则是有区别的.如下面程序: 1 2 3 4 5 6 7 8 <?php $website = "NowaMagic"; $name = 'Gonn'; echo 'Welcome to visit $website. My name is $name.'; echo '<br>'; echo "Welcome to visit

freemarker 模板中定义变量

在模板中可以定义三种类型的变量: 简单变量:它能从模板中的任何位置来访问,或者从使用 include 指令引入的模板访问.可以使用 assign 或 macro 指令来创建或替换这些变量. 局部变量:它们只能被设置在宏定义体内,而且只在宏内可见.一个局部变量的生存周期只是宏的调用过程.可以使用 local 指令在宏定义体内创建或替换局部变量. 循环变量:循环变量是由指令(如 list )自动创建的,而且它们只在指令的开始和结束标记内有效.宏的参数是局部变量而不是循环变量. 示例:使用 assig

C++中switch 语句中的变量声明和

switch 内部的变量定义: 1 int i = 1; 2 switch(i) 3 { 4 case 0: 5 string str; //error 6 int val1 = 0; //error 7 int val2; //right 8 int val3; val3 = 0; //right 9 case 1: 10 val2 = 9; 11 cout << val2 << endl; 12 } <C++ Primer> P163: 如果在某处一个带有初始值的变

dos中定义变量与获取常见的引用变量以及四则运算(set用法)

在dos中使用set定义变量: set  a=8              (注意等号两边没有空格) 引用变量如: echo  %a%        将打印a的值 (%a%是获取变量a的值) dos中要使用算术运算,需要使用 set 命令: set  /a  val=3*4     将打印12     (注意等号两边没有空格) 例子 @echo off set b=8888 rem 下一条语句定义了dos中的算术运算 set /a val = 3*2 for /l %%i in (1,1,%va

关于在头文件中定义变量的问题

如果在一个头文件中定义了一个变量 A.h: int i; 在A.cpp,B.cpp...文件中包含了这个头文件,编译时就会产生重复定义的错误.问题所在是因为int i;这句代码是定义了一个i变量,包含一次头文件就定义了一次i,包含多次肯定引起错误.如果改成extern int i;这句代码就变成了一个声明了.并不会定义i这个变量.不过在多个cpp文件里初始化一样会出现错误.只能在一个cpp文件中进行初始化.

c语言头文件中定义变量

最近在看一个PHP的扩展源码,编译的时候的遇到一个问题: ld: 1 duplicate symbol for architecture x86_64 仔细看了一下源码,发现在头文件中 出现了全局变量的定义 ZEND_DECLARE_MODULE_GLOBALS(xx) 简单开来,可以这么理解 // t1.h #ifndef T1_H #define T1_H int a = 0; #endif //------------------ //t1.c #include "t1.h" #

在properties.xml中定义变量,在application.xml中取值问题

如果为application.xml中的变量赋默认值,同时又在properties.xml中变量赋值,而加载后是取不到properties.xml中的值的问题. 解决这个问题需要加上黑体部分配置: <bean id="sysConfiguration" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">        <property na

如何在Ubuntu Scope中定义设置变量并读取

在本遍文章中,我们来讲解怎么对我们的Ubuntu Scope进行设置.对Scope而言,有些时候我们希望能够使用设置来改变我们的显示,或对我们的搜索进行重新定义.关于更多Scope的开发,请参阅网站:http://developer.ubuntu.com/scopes/ 1)首先创建一个最基本的Scope 我们首先打开SDK,并选择"Unity Scope"模版.我们选择一个项目的名称为"settingscope": 接下来,我们选择"Empty scop