在本文中,我们学习分支语句,循环语句和goto语句
在C语言中,语句是一条完整的执行单元,它用于表达某种操作或执行特定的任务。C语言中的程序由一个个语句组成,每个语句都按照一定的顺序被执行。
C语言中常见的语句有以下几种:
x = 10;
int x = 10;
if (x > 5) { ... }
、while (x < 10) { ... }
、break;
{
int x = 10;
printf("x = %d\n", x);
}
;
注意,每个语句必须以分号结尾,分号表示语句的结束。编译器会按照语句的顺序逐一执行代码中的语句,以完成相应的操作和任务。
在c语言中,又九种控制语句,可分为以下三类:
在人生中,我们会面临着多种选择,不同的选择又有不同的结果,这就产生了分支
以上便是一个简单的双分支示意图,在c语言中我们通过if语句和switch语句来实现分支结构
那if语句的语法结构是怎样的呢?
if(表达式)
{
语句;
}
双分支:
if(表达式)
{
语句1;
}
else
{
语句2;
}
多分支:
if(表达式1)
{
语句1;
}
else if(表达式2)
{
语句2;
}
else
{
语句3;
}
注意:else后面不带表达式
以下是这段代码的执行方式:
首先,会对表达式1进行求值判断。如果表达式1的结果为真(非零),则执行语句1,并跳过后续的 else if 和 else 部分。如果表达式1的结果为假(0),则继续执行下一步。
如果表达式1的结果为假(0),则会继续对表达式2进行求值判断。如果表达式2的结果为真(非零),则执行语句2,并跳过后续的 else 部分。如果表达式2的结果为假(0),则继续执行下一步。
如果前面的条件都不满足(即表达式1和表达式2的结果都为假),则执行语句3。
需要注意的是,条件语句的每个条件表达式都会按从上到下的顺序进行求值判断。一旦某个条件满足,则会执行相应的语句块,并跳过后续的条件和语句块。如果没有任何条件满足,则会执行最后的 else 语句块(如果有的话),或者整个条件语句结束。
if-else if-else 和 if-if-if 语句有一些不同之处。让我们来看一下它们的区别。
if (condition1)
{
// 执行代码块1
}
else if (condition2)
{
// 执行代码块2
}
else if (condition3)
{
// 执行代码块3
}
else
{
// 执行默认代码块
}
if (condition1)
{
// 执行代码块1
}
if (condition2)
{
// 执行代码块2
}
if (condition3)
{
// 执行代码块3
}
执行逻辑不同:
if-else if-else:当满足条件1时,执行代码块1,然后跳过后续的 else if 和 else 分支。如果条件1不满足,则继续检查下一个 else if 条件,依此类推如果没有任何条件满足,最后执行 else 分支(如果有)。
if-if-if:每个 if 语句都会独立地进行条件判断和执行。不论前面的条件是否满足,都会检查并执行每个 if 语句。
执行次数不同:
if-else if-else:只有一个分支会被执行。一旦条件满足,会执行相应代码块,并跳过后续分支。
if-if-if:多个分支可以同时被执行。每个 if 语句都会独立地进行条件判断和执行。
综上所述,if-else if-else 和 if-if-if 在执行逻辑和执行次数上有所不同。我们需要根据具体的业务需求和逻辑,选择适合的条件语句结构来编写代码。
接下来看一段代码:
#include
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
这是一段有坑的代码:
一般人可能会认为,因为a == 1这个条件不满住,所以会执行else这个语句,打印 haha,其实不然,下面是代码的运行的结果:
可见打印的结果是hehe而不是haha,这是为什么呢?
主要原因是因为
else是和离它最近的if进行匹配的
所以这段代码的结果是打印hehe
那么我们该怎么避免这种错误呢?
我们可以适当的使用{ }可以使代码的逻辑更加清楚。
以下是改进的代码
#include
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
{
printf("hehe\n");
}
}
else
{
printf("haha\n");
}
return 0;
}
这样 else 就是和第一个 if 进行匹配了,注意, else 和 if 一定要同等级,虽然第二个if在视觉上更近一些,但是第二个 if 和 else 的等级不一样。请注意辨别
请大家判断以下两个代码哪个更好
//代码1
int num = 1;
if(num == 5)
{
printf("hehe\n");
}
//代码2
int num = 1;
if(5 == num)
{
printf("hehe\n");
}
这两段代码作用相同,判断变量num
是否等于5,并打印出"hehe"。在这种情况下,两段代码效果相同
然而,代码4中的写法更好,将常量值放在等式的左侧。这种写法称为"常量左移"或"常量前置",是一种常见的编程习惯。使用常量左移的好处是可以避免在条件表达式时,错误地将=
写成==
,这种错误是比较常见的。将常量放在左侧时,如果不小心写成if(num = 5)
,编译器会报错,因为赋值操作返回的是赋值的值,所以num = 5的结果为真,执行if中的代码块,这样就和我们的初衷就背离了
所以,代码4的写法更好,可以提高代码的安全性和可读性。
在 C 语言中,switch 语句用于根据某个表达式的值选择执行不同的代码块。它的语法结构如下:
switch (expression)
{
case constant1:
// 代码块1
break;
case constant2:
//代码块2
break;
default:
// 代码块3
}
其中 expression
是需要进行比较的表达式,可以是整数或字符类型。每个 case
后面的 constant
是一个常量,它会与 expression
进行比较。如果 expression
的值与某个 case
后面的 constant
相等,程序将执行对应的代码块。如果没有匹配到任何 case
,那么将执行 default
后面的代码块(如果有deault)。
在 switch 语句中,break 语句用于跳出 switch 语句。当程序执行完某个 case 的代码块后,如果没有 break 语句,程序将会继续执行下一个 case 的代码块,直到遇到 break 或者 switch 语句结束。这种不加 break 的情况被称为 “case 穿透”。
如果在某个 case 的代码块中不加 break,会导致程序继续执行下一个 case 的代码块,而不会进行比较。这可能是有意为之,也可能是错误。比如:
switch (value)
{
case 1:
// 代码块 1
case 2:
// 代码块 2
break;
case 3:
// 代码块 3
break;
default:
// 代码块 4
}
如果 value
的值为 1,那么将会执行 代码块 1、代码块 2 和 代码块3 和代码块4。因为在第一个 case 中没有使用 break,所以程序会继续向下执行。加入 break 语句可以控制代码的执行流程,避免出现不可预期的结果。
总结一下,switch 语句是根据表达式的值选择执行不同的代码块。通过在各个 case 中使用 break 语句可以控制代码的流程。如果没有使用 break,会导致 case 穿透,程序会继续执行下一个 case 的代码块。
在c语言中,switch语句也是一种分支语句。常常用于多分支的情况。
例如我们需要写这样一个程序:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
如果用 - if - else if - else 语句写的话应该是这样:
#include
int main() {
int day;
printf("请输入一个数字: ");
scanf("%d", &day);
if (day == 1)
{
printf("星期一\n");
}
else if (day == 2)
{
printf("星期二\n");
}
else if (day == 3)
{
printf("星期三\n");
}
else if (day == 4)
{
printf("星期四\n");
}
else if (day == 5)
{
printf("星期五\n");
}
else if (day == 6)
{
printf("星期六\n");
}
else if (day == 7)
{
printf("星期日\n");
}
else
{
printf("输入无效,请输入一个介于1-7之间的数字。\n");
}
return 0;
}
c语言为我们提供了一个专门处理多分支的语句switch
用switch语句我们可以这样写:
#include
int main() {
int day;
printf("请输入一个数字代表星期几(1-7):");
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;
default:
printf("无效的输入\n");
}
return 0;
}
使用 switch 语句处理多分支和使用 if 语句处理多分支都可以实现相同的功能,但它们在某些方面有不同的优势。
以下是 switch 语句相对于 if 语句的一些优点:
代码可读性:当存在多个互斥的选项时,使用 switch 语句可以使代码更加简洁和可读。每个 case 独立地处理一个特定的情况,使代码结构清晰。
性能优化:在某些情况下,使用 switch 语句可以提高代码的执行效率。因为 switch 语句的实现方式使用了跳转表(jump table),可以直接根据表达式的值跳转到对应的分支,而不需要逐个检查每个条件。
代码可维护性:当需要添加或修改分支条件时,使用 switch 语句可以更方便地进行扩展和维护。只需要添加或修改相应的 case 分支即可,而不需要修改大量的 if 条件。
需要注意的是,switch 语句只能处理离散的值,比如整数类型或字符类型。它对于范围的处理能力有限,而 if 语句可以使用逻辑运算符来处理更复杂的条件。
总之,选择使用 switch 语句还是 if 语句取决于具体的业务需求,以及在代码的可读性、性能和可维护性之间做出权衡。
在生活中,有些事情需要我们重复不断的去完成,比如说睡觉,洗澡,吃饭,学习,而在c语言中我们可以通过while循环 for循环和do while循环来重复执行某一段代码。
下面我们来一一介绍
在C语言中,while
循环是一种基本的循环结构,它允许我们根据给定的条件重复执行一段代码。while
循环的基本语法如下:
while (condition) {
// 执行的代码块
}
当condition
条件为真(非零)时,循环中的代码块会被执行。执行完一次代码块后,会再次判断condition
条件是否为真,如果为真,则再次执行代码块,以此类推,直到condition
条件为假(零),才会退出循环。
使用while循环的时候注意以下几点:
下面是一个使用while
循环的简单示例:
#include
int main() {
int count = 0;
while (count < 5)
{
printf("Count: %d\n", count);
count++; // 更新循环变量
}
return 0;
}
在上述示例中,通过设置count
变量,循环执行5次。我们在代码块中每循环一次让count自增1,这样能够让条件最终变假,不会陷入死循环
在C语言中,for循环是一种用于重复执行代码块的循环结构。它允许我们指定循环变量的初始值、循环条件和每次循环后更新循环变量的操作。for循环的语法如下:
for (初始化表达式; 循环条件; 更新表达式) {
// 循环体
}
for循环的作用是重复执行循环体,并允许我们对循环变量进行精确控制。我们可以使用它来实现一系列需要重复执行的任务
下面是一个简单的例子,展示了如何使用for循环计算1到10的和:
#include
int main()
{
int sum = 0;
for (int i = 1; i <= 10; i++)
{
sum += i;
}
printf("Sum: %d\n", sum);
return 0;
}
在这个例子中,我们使用了三个重要的组成部分来控制循环的行为:
初始化表达式:我们将循环变量 i
设置为1,指定了循环的起始值。
循环条件:我们使用 i <= 10
作为循环条件,这意味着当 i
小于等于10时循环继续执行,否则循环结束。
更新表达式:在每次循环结束后,我们使用 i++
将循环变量 i
增加1,以便进行下一次迭代。
循环体部分中,我们将当前的 i
值添加到 sum
变量中,因此在每次循环迭代中,sum
的值会被更新。
最终,我们输出了 sum
的值,结果为1到10的和,即55。
使用for循环时需要注意的一些点包括:
例如:
for (x = 0,y = 0; x < 2 && y< 5;++x,++y)
{
//代码块
}
for(;;)是最简单的死循环,因为这个for循环没有判断条件,默认为真
在C语言中,"break"和"continue"是控制循环的关键字。continue和break都可以用在 for、while、do-while 循环以及 switch 语句中。它们分别用于终止循环和跳过当前迭代,让程序按照特定的需求执行。
以下是一个使用break语句的示例:
#include
int main()
{
int i;
for (i = 1; i <= 10; i++)
{
if (i == 5)
{
break;
}
printf("%d ", i);
}
printf("Loop ended!\n");
return 0;
}
输出:
1 2 3 4 Loop ended!
在上面的示例中,当i等于5时,break语句会立即终止循环,因此只输出了1、2、3和4。
以下是一个使用continue语句的示例:
#include
int main()
{
int i;
for (i = 1; i <= 10; i++)
{
if (i == 5)
{
continue;
}
printf("%d ", i);
}
printf("Loop ended!\n");
return 0;
}
输出:
1 2 3 4 6 7 8 9 10 Loop ended!
在上面的示例中,当i等于5时,continue语句会跳过当前迭代,而不执行后面的代码。因此,输出中没有数字5。
总结:
下面我们来看一段代码:
#include
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ",i);
}
return 0;
}
//代码2
#include
int main() {
int count = 0;
while (count < 5)
{
printf("Count: %d\n", count);
count++; // 更新循环变量
}
return 0;
}
在for循环中,循环变量的初始化、条件判断和更新都在一个地方进行,使得代码更加集中、简洁。而while循环的三个部分可能比较偏远,这样查找和修改循环变量就不够集中和方便
当你想要先执行一次循环体,然后再根据条件判断是否继续执行循环时,可以使用C语言中的do-while循环。
do-while循环的基本语法如下:
do
{
// 循环体
} while (条件);
do-while循环的执行过程是这样的:首先执行循环体,然后在循环体执行完之后再进行条件判断。如果条件满足,则继续执行循环体,否则结束循环。因此,do-while循环保证至少执行一次循环体。
do-while 循环和 for 循环 while 循环没什么不同,都是重复做一件事情,只是 do-while ,循环会先执行一次代码块中的代码,仅此而已,因为使用场景有限,所以不是很经常使用
在C语言中,goto
语句可以用来无条件地转移到程序中的某个标签(label)处执行代码。它的基本语法如下:
goto label;
// ...
label://冒号
// 代码块
其中,label
是由用户自定义的标签,用来标识需要跳转到的位置。在执行到goto
语句时,程序将会跳转到label
所在的位置,继续执行标签处的代码块。
使用goto语句的时候需要注意以下几点:
合理使用goto
语句:由于goto
语句具有无条件跳转的特性,过度使用它可能导致程序结构混乱,难以理解和维护。因此,应谨慎使用goto
语句,避免滥用。
避免跳过变量初始化:当使用goto
语句跳转到某个标签时,应确保经过的代码路径中的变量已经被正确初始化。否则,可能会导致未定义的行为。
避免跨越变量作用域:在使用goto
语句时,应注意不要跨越变量的作用域。否则,可能会导致变量不可见或者访问非法内存的问题。
避免嵌套过多的goto
语句:嵌套过多的goto
语句会使代码变得复杂和难以理解。在逻辑结构清晰的情况下,尽量避免使用嵌套的goto
语句。
以下是goto语句的使用示例
使用goto语句来实现循环打印1-10的代码:
#include
int main() {
int i = 1;
loop:
printf("%d ", i);
i++;
if (i <= 10) {
goto loop; // 跳转到loop标签处继续循环
}
return 0;
}
在上述代码中,我们使用了一个标签loop来表示循环的起始点。通过使用goto语句,我们在每次打印完数字后跳转到loop标签处,从而实现了循环打印1-10的效果。
标记和goto无先后顺序
需要注意的是,尽管goto语句在某些特定情况下可能很方便,但它容易导致代码的可读性和维护性降低。因此,在实际开发中应尽量避免过多地使用goto语句,尽量使用其他更结构化的语句(如for循环、while循环)来实现循环逻辑。