1 | if (表达式) |
1 | if (表达式) |
1 | switch (表达式) { |
1 |
|
break
语句将导致程序的执行立即从switch
语句中退出。在switch
语句中,case
的作用只是一个标号,因此,某个分支中的代码执行完后,除非使用break
或return
显式跳转,否则程序将进入下一个分支继续执行。
作为一种良好的程序设计风格,在switch
语句最后一个分支(即default
分支)的后面也加上一个break
语句。这样做在逻辑上没有必要,但当我们需要向switch
语句后添加其他分支时,这种防范措施会降低错误的可能性。
一个更通用的atoi
例子,它可以处理可选的前导空白符以及一个可选的加+
或减-
号。
1 |
|
逗号运算符,
是C语言优先级最低的运算符,在for语句中经常用到它。被逗号符分隔的一对表达式将按照从左到右的顺序进行求值。例如:reverse(s)
函数,该函数用于倒置字符串s中各个字符的位置。
1 |
|
某些情况下的逗号并不是逗号运算符,比如分隔函数参数的逗号,分隔声明中变量的逗号等,这些逗号并不保证各表达式按从左到右的顺序求值。
应该慎用逗号运算符。逗号运算符最适用于关系紧密的结构中,比如上面的reverse函数内的for语句,对于需要在单个表达式中进行多步计算的宏来说也很适合。逗号表达式还适用于reverse
函数中元素的交换,这样,元素的交换过程便可以看成是一个单步操作。
1 | for (i = 0, j = strlen(s)-1; i < j; i++, j--) |
C99规定了一种新的for循环语法,在控制表达式1的位置可以有变量定义。例如上例的循环变量i可以只在for循环中定义:
1 | int factorial(int n) |
如果这样定义,那么变量i只是for循环中的局部变量而不是整个函数的局部变量。在循环结束后就不能再使用i这个变量了。这个程序用gcc编译要加上选项-std=c99。这种语法也是从C++借鉴的,考虑到兼容性不建议使用这种写法。
示例:itoa
函数(atoi
函数的逆函数,把数字转换为字符串)
1 | /* itoa: convert n to characters in s */ |
break语句可以用于从for、while与do-while等循环中提前退出,就如同从switch语句中提前退出一样。break语句能使程序从switch语句或最内层循环中立即跳出。
下面的函数trim
用于删除字符串尾部的空格符、制表符与换行符。当发现最右边的字符为非空格符、非制表符、非换行符时,就使用break语句从循环中退出。
1 | /* trim: remove trailing blanks, tabs, newlines */ |
continue
语句用于使for
、while
或do-while
语句开始下一次循环的执行。在while
与do-while
语句中,continue
语句的执行意味着立即执行测试部分;在for
循环中,则意味着使控制转移到递增循环变量部分。continue
语句只用于循环语句,不用于switch
语句。某个循环包含的switch
语句中的continue
语句,将导致进入下一次循环。
C语言提供了可随意滥用的goto语句以及标记跳转位置的标号。从理论上讲,goto
语句是没有必要的,实践中不使用goto
语句也可以很容易的写出代码。
但是,在某些场合下goto
语句还是用得着的。最常见的做法是终止程序在某些深度嵌套的结构中的处理过程,例如一次跳出两层或多层循环。这种情况下使用break
语句是不能达到目的的,它只能从最内层循环退出到上一级的循环。下面是使用goto
的一个例子:
1 | for ( ... ) |
在该例子中,如果错误处理代码很重要,并且错误可能出现在多个地方,使用goto
语句将会比较方便。
标号的命名同变量命名的形式相同,标号的后面要紧跟一个冒号。标号可以位于对应的goto
语句所在函数的任何语句的前面。标号的作用域是整个函数。
我们来看另外一个例子。考虑判定两个数组a与b中是否具有相同元素的问题。一种可能的解决方法是:
1 | for (i = 0; i < n; i++) |
所有使用了goto
语句的程序代码都能改写成不带goto
语句的程序,但可能会增加一些额外的重复测试或变量。大多数情况下,使用goto
语句的程序段比不使用goto
语句的程序段要难以理解和维护,少数情况除外。因此,建议尽可能少的使用goto
语句。