C语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构。也就是说在C语言所有的代码都是这三种结构。
本篇文章将会着重讲解转向语句break、continue和goto语句的使用
关于C语言三种结构的详细讲解请阅读前两篇文章
【C语言基础篇】结构控制(上)顺序结构和选择结构-CSDN博客
转向语句用来直接控制程序的执行流程,从而改变循环结构、选择结构以及函数的正常执行流程。
这些语句在编写程序时常被用到,特别是当循环体内部分支比较复杂时,可用于简化分支语句的条件,减少条件分支语句if的嵌套深度及分支数,使程序更易阅读和理解。
在编写代码时,应根据实际需求选择合适的转向语句,并确保代码的可读性和可维护性。
(但goto语句尽量少用,因为这不利于结构化程序设计,滥用它会使程序流程无规律、可读性差,稍后会在文章中介绍)
一、break语句
break 的作用是用于跳出switch结构或循环结构,只要 break 被执行,直接就会跳出循环或switch代码块,继续往后执执行。
当有break语句位于多重循环的内循环中,它只能跳出内循环,即只能跳出一层循环。
下面以打印1-10的数字为例,分别展示break在三种循环中的使用和效果
1. break在 while 循环中
#include <stdio.h> int main() { int i = 1; while (i <= 10) { if (i == 5) break; //当i=5时,break跳出循环,结束打印 printf("%d ", i); //打印结果为1 2 3 4 i++; } return 0; }
2. break在 for 循环中
#include<stdio.h> int main() { for (int i = 1; i <= 10; i++) { if (i == 5) break; //当i=5时,break跳出循环,结束打印 printf("%d ", i);//打印结果为1 2 3 4 } return 0; }
3. break在 do…while 循环中
#include<stdio.h> int main() { int i = 1; do { if (i == 5) break;//当i=5时,break跳出循环,结束打印 printf("%d ", i);//打印结果为1 2 3 4 i++; } while (i <= 10); return 0; }
4. break在 switch 语句中
break对于switch语句的作用不同于三种循环——
break在switch中属于是必不可少的选项。在switch中,case相当于switch的入口,break相当于switch的出口。如果没有在某个case后面没有break语句,代码会继续往下执行,有可能执行其他 case语句中的代码,直到遇到 break 语句或者 switch 语句结束
比如下面这个例子,输入一个数字打印周几,正常情况下应该是每个case跟一句break,这样能做到“一进一出”
#include<stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("周一\n"); break; case 2: printf("周二\n"); break; case 3: printf("周三\n"); break; case 4: printf("周四\n"); break; case 5: printf("周五\n"); break; case 6: printf("周六\n"); break; case 7: printf("周日\n"); break; } return 0; }
比如输入一个数字2,就会输出周二
如果去掉break语句,再输入一个数字2。就会看到程序从case 2进入之后,直到整个switch语句执行完才结束
#include<stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("周一\n"); case 2: printf("周二\n"); case 3: printf("周三\n"); case 4: printf("周四\n"); case 5: printf("周五\n"); case 6: printf("周六\n"); case 7: printf("周日\n"); } return 0; }
当然,break在switch语句中不一定要在每一条case语句后面出现
当需要多个case入口共用一段代码和出口,就可以省略break。
比如下面这种情况
#include<stdio.h> int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("周末\n"); break; } return 0; }
5. break 总结
break用于循环结构中时,在while循环、for循环和do...while循环中的使用方法和效果相同。
都是在满足某个条件时,使用break跳出循环,不再执行未完成的循环语句。不过要注意,break只能跳出一层循环,如果要跳出多层循环,需要在对应的每层循环中使用break语句。
break用于switch结构时,一般情况下,每条case语句和default语句都需要有对应的break语句。但需要多个case语句共用一个“出口”时,只在最后一个入口的后面跟随break语句
二、continue语句
continue的作用时在循环结构中,根据某个判断条件结束本次循环,即循环体中continue语句后边的部分不再执行,直接进入下一次循
下面依然以打印1-10的数字为例,分别展示continue在三种循环中的使用和效果
1. continue在 while 循环中
#include <stdio.h> int main() { int i = 1; while (i <= 10) { if (i == 5) continue; printf("%d ", i); i++; } return 0; }
当i=5时,continue跳出本次循环,但由于跳过了循环变量调整部分,导致了死循环
打印结果为1 2 3 4...死循环(可以看到控制台的光标一直在闪烁)
2. continue在 for 循环中
#include<stdio.h> int main() { for (int i = 1; i <= 10; i++) { if (i == 5) continue; printf("%d ", i); } return 0; }
当i=5时,continue跳出本次循环,进入到循环变量调整和循环条件判断部分(因为for循环的循环变量调整部分是单独拿出来的,所以没有像while循环中使用continue一样进入死循环)
打印结果为1 2 3 4 6 7 8 9 10
3. continue在 do...while 循环中
#include<stdio.h> int main() { int i = 1; do { if (i == 5) continue; printf("%d ", i); i++; } while (i <= 10); return 0; }
当i=5时,continue跳出本次循环,但由于跳过了循环变量调整部分,所以和上面的while循环一样,导致了死循环
打印结果为1 2 3 4...死循环
4. continue 总结
continue在三种循环中的使用方法都是相同的——在满足某种条件时,使用continue跳过每次循环后面的代码,直接进入下一次循环
但continue在三种循环中的使用效果有所不同:
- 在while循环和do...while循环中,如果continue刚好跳过了循环变量调整部分,将会导致死循环
- 而在for循环中,由于循环变量调整部分是单独拿出来的,所以使用continue不会导致死循环
三、goto语句
goto语句也称为无条件转移语句,在C语言是⼀种非常特别的语法,goto 语句和语句标号配合使用, 可以实现在同⼀个函数内跳转到设置好的标号处。
C语言不限制程序中使用标号的次数,但各标号不得重名。goto 语句的语义是改变程序流向, 转去执行语句标号所标识的语句。
goto 语句通常与选择语句配合使用,比如 if 语句。可用来实现条件转移, 构成循环,跳出循环体等功能。但是要注意,goto语句与 if 语句构成的循环,是无法用break打破的
所以在结构化程序设计中一般不主张使用 goto 语句来强制改变程序的走向, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
goto语句的使用格式如下
goto 语句标号;
.........
语句标号:
........
goto语句使用示例
#include<stdio.h> int main() { int i = 1; while (i <= 10) { if (i == 5) goto exit; printf("%d ", i); i++; } exit: printf("\n"); return 0; }
程序执行结果如下
goto 语句如果使用不当,就会导致在函数内部随意乱跳转,打乱程序的执行流程,所以我们的建议是能不用尽量不去使用;
但是 goto 语句也不是一无是处,在多层循环的代码中,如果想快速跳出,使用 goto 就非常的⽅便了
for(...) { for(...) { for(...) { if(disaster) goto error; } } } error: //...
四、return语句
在C语言中,return语句用于从函数中返回。
当程序执行到函数中的return语句时,函数的执行会立即结束,返回到调用该函数的地方。return语句可以带有一个表达式,该表达式的值将作为函数的返回值。
如果return语句没有表达式,那么函数返回的值是未定义的。
- 函数必须有返回值类型,除了void类型的函数。void类型的函数不返回任何值,因此不需要return语句。
- 函数可以有多个return语句,以便在不同的条件下返回不同的值。但是,一旦执行到return语句,函数就会立即结束,后面的代码不会被执行。
- 如果函数没有return语句,那么函数会在最后一行隐式地返回一个值。对于main函数,这个隐式返回值通常是0,表示程序正常结束。对于其他函数,这个隐式返回值是未定义的,因此应该避免使用没有return语句的函数。
- 如果函数的返回类型是指针类型,那么return语句可以返回一个指针。在这种情况下,需要确保返回的指针是有效的,以避免潜在的内存访问错误。
1. void类型函数 无需返回值和return语句
void print(int num) { for (int i = 0; i <= i; i++) { printf("%d ", i); } }
2.多个return语句作为不同情况下的返回值
int max(int a, int b) { if (a > b) return a; else return b; }
3.应返回值的函数没有return语句
#include<stdio.h> int max(int a,int b) { } int main() { int m = 1, n = 2; printf("%d", max(m, n)); }
main函数的返回值默认为0
其他函数的返回值时一个随机值
4.函数的返回值是指针类型
int* add(int m, int n) { int *result= (int*)malloc(sizeof(int) * 2); result[0] = m; result[1] = n; return result; }
五、转向语句总结
C语言中,转向语句有break、continue、goto、return四种,分别有着不同的使用方法和效果
- break可用于循环结构或switch结构中。用于循环结构时,会立即跳出该层循环;用于switch结构时,作为不同分支的出口,跳出switch结构
- continue用于循环结构中。根据某个判断条件结束本次循环,跳过本次循环后面的代码,直接进入下一次循环。不过要注意,continue用于while循环和do...while循环中,可能会跳过循环变量调整部分,导致死循环。
- goto语句与相应的语句标号配合使用,用改变程序流向, 转去执行语句标号所标识的语句。 在结构化程序设计中一般不主张使用 goto 语句来强制改变程序的走向, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
- return语句用于函数中。当程序执行到函数中的return语句时,函数的执行会立即结束,return语句后跟随的表达式将作为函数的返回值。
如若您发现文章存在错误,还望多多指正