在C语言的流程控制中包括顺序结构、选择结构(分支结构)和循环结构,任何程序都由着三种结构组合而成。
一、选择结构
C语言中通过关系运算和逻辑运算构造选择判断的条件。故要了解关系运算和逻辑运算如何运用。
1.关系运算
关系运算的运算符包括“>”“>=”“<=”“==”“!=”,它们都为双目运算符,其中“>”“>=”“<=”“<”优先级高于另外两种。
int n;
n > 5; //关系表达式
表达式都是有值的,其结果反应一种关系成立与否,即0为假,1为真。C语言中用int型来记录逻辑结果。要注意C语言中的关系表达式与数学中的有所不同,例如
int a = 1;
0 < a < 5;
其结果不在是a的范围在0和5中间,(0<a)<5其中0<a为真其逻辑值为1,1<5为真其逻辑值为1,故该程序最后的结果为1.
2.逻辑运算
逻辑运算的预算符有“&&”与,“||”或,“!”非
(1)&&
运算形式:表达式1 && 表达式2
运算规则:一假为假
int a = 1;
int b = 0;
b = a < 0 && ++a;
printf("a = %d b = %d",a,b);
在逻辑与运算中,先从左边的表达式开始运算,且在运算时具有短路特性(截断特性)即当&&左边的表达式为假时就结束运算,不在运算右边的表达式,本次运算的结果就为0。故在上述程序中,由结合性b = (a<0) &&(++a),a<0为假,其逻辑值为0,运算到此结束(++a)不进行运算,故该程序的运行结果为a = 1 b = 0.
(2)||
运算形式:表达式1 || 表达式2
运算规则:一真为真
逻辑或运算同样从左边的表达式开始运算,同样具有截断特性,即当左边表达式为真时结果就位真,不再计算右边的表达式。需要注意的是,&&的优先级高于||,当&&和||同时出现时先运算&&。
(3)!
运算规则:真假相对
注意:!为单目运算符,其优先级较高。
在进行运算时,我想下图应该是记在心中的:优先性从上到下递减。
若x=y=z=1;t=++x||++y&&++z;t的值为__,x的值为__,y的值为__,z的值为__.
由优先级和结合性t=++x||((++y)&&(++z)),t = 1,x=2,y=1,z=1.在本题中有涉及到一个问题,系统是如何判断一个量的“真”和“假”的呢?规定:0为假,即其值为0、'\0'、NULL;非零就是真,即从数值角度看其值不为0。这里同时还有一个问题,就是在代码编写时int x=y=z=1;这种编写形式是错误的,因为y与z没有定义,变量名要先定义后使用。
3.条件语句
(1)if语句
形式一:处理单个情况-单分支
语法形式:
if(表达式)
{
语句
}
语义:如果表达是为真,则执行语句,语句执行完,也表示if语句结束,程序继续往下;表达式为假表示if语句结束,程序继续往下
注意:if(表达式);//不加分号
形式二:处理两种情况-双分支
语法形式:if(表达式)
{
语句1
}else
{
语句2
}
语义:如果表达是为真,则执行语句1,语句1执行完,也表示if语句结束,程序继续往下;表达式为假执行语句2,执行结束表示if语句结束,程序继续往下。
注意:对于else(表达式)这种写法是错误的,没有这种写法。
这里有学习到对其命令,即当代码输入的格式不对齐时,可用该命令进行对齐:单行对齐:“==”两个等号;多行对其:shift+“v”再配合方向键选中多行+“=”;全局对齐:“gg”+“=”+shift+“g”。
形式三:处理多分支
语法格式:
if(表达式1)
{
语句1;
}else if(表达式2)
{
语句2;
}else...
{
...
}else
{
}
语义:如果表达式1为真,执行语句1,执行结束,表示if语句结束,程序往下进行,如果表达式1为假,判断表达式2,若表达式2为真,则执行语句2,执行结束,表示if语句结束,程序往下进行.....
在编程中经常会用到if语句的嵌套,这时就会涉及到if和else的配套,那么如何区分if是与哪一个else是一起的呢?这里要知道的是,有单独的if语句没有单独的else语句,故else一定和某一个if配对,故在区分else究竟与哪一个if配对时一般从最里面的else开始找,向前找离else最近的还未使用的if配对。
与if-else相类似的运算有条件运算,条件运算的格式为:表达式1?表达式2:表达式3,其含义为:判断表达式1,若为真,则执行表达式2,若为假,则执行表达式3,简单来说条件运算为if-else的简写。
4.switch语句
switch(表达式)
{
case 常量表达式:
语句1;
break;
case 常量表达式2:
语句2;
break;
......
default:
语句n+1;
break;
}
语义:首先求解表达式,用表达式的结果与下面的case后面的常量表达式进行匹配,匹配成功则执行对应case下的语句,直达遇到break或者switch语句的“}”才结束。
在使用switch语句时,应当注意的是:
(1)switch后面的表达式必须是一个整型表达式,其结果必须为一个值
(2)case后面必须是一个整型常量表达式,不能出现变量
(3)“case 常量表达式:”相当于是一个标签,代表其下面语句
(4)default不一定写在最后,当其现在中间位置时,如果没有break,就不会跳出switch语句,会忽略用于匹配的case标签继续向下执行switch中的其他语句,直到遇到break或者switch的“}”才结束switch语句,所以要求default中写入break,同时也要求在每个case的语句中也加入break。
(5)若出现在几个case下执行的语句是相同的,则可以将其写在一起,只在最后一个case下面写入语句即可。
switch(n)
{
case 1:
case 2:
case 3:
case 4:
printf("hello world!\n");
break;
}
二、循环结构
C语言中的循环语句包括:goto、while、do---while、for.
1.goto
语法格式:goto 标签
goto本身并不是循环语句而是跳转语句,但是当他配合上其他语句可构成循环语句。这里的抱歉类似于平时看书时的书签,书签的目的是帮助我们直接找到要看的内容,这里的标签也是这个道理,它帮助程序在运行时直接找到下一个要执行的语句。此外,当设计多层嵌套式,若想要从最里面的循环中跳到最外面,借用break要一层一层循环向外跳出,但借助goto可以直接跳出整个循环体,可以更快捷的到指定位置。
#include<stdio.h>
int main(void)
{
int i = 0;
loop:
printf("hello world! i = %d\n",i++)
if(i > 50000)
{
goto exit;
}
goto loop;
exit:
return 0;
}
那么究竟如何写出正确的循环结构呢?构成循环结构的要素:(1)循环体,即反复执行的代码(2)循环的初始条件结束条件,即当达到这个条件时跳出循环(3)使循环趋于结束的操作或语句(4)结束条件,即当达到这个条件时跳出循环。
2.while语句
语法形式:
while(表达式)
{
语句
}
语义:判断表达式,若为真,则执行语句,语句执行后继续判断表达式,重复上述操作,直到表达式为假时跳出while语句,继续往下进行;若为假,则直接跳出while语句,往下进行。
当在使用while时,while(表达式);这种语句在编译时不会报错,但由于“;"相当于一个空语句,while会一直执行这个空语句,而不执行下面的语句,故在变下代码时应小心避免这种情况的出现。