前言
C语言是结构化的程序设计语言,这里的结构为顺序结构、选择结构、循环结构。
我们的日常生活中离不开这些结构,如:当我们要完成一个任务时,制定一个计划,按照计划的顺序来会事半功倍;完成一个阶段后,我们需要进行选择判断同时产生分支,根据一个阶段的完成情况进行选择下一阶段的任务量或者做其他任务;为达到目标,我们可能需要反复进行一个工作,如不断学习,这样我们进入一个循环。
在C语言中,我们同样可以进行以上三个结构来解决我们生活中的各种问题。
选择结构(也是分支结构):我们可以通过if、switch来实现。
循环结构:我们可以通过for、while、do while来实现。
同时我们还需要一些关系操作符和逻辑操作符帮助我们更好地实现分支和循环。
1.关系操作符
C 语语言于比较的表达式,称为 “关系表达式”(relational expression),里面使用的运算符就称为“关系运算符”(relational operator),主要有下面6个。
“>”
大于运算符“<”
小于运算符“>=”
大于等于运算符“<=”
小于等于运算符“==”
相等运算符 注意:要区别“==”
与“=”
,具体会引起的错误请见下方“if”语句。“!=”
不相等运算符
消息表达式通常返回0
或1
表示真假。C语言中0表示假,非0表示真。
多个关系符不能连用,如a>b>c
应写为a>b&&b>c
2.逻辑操作符
-
“!”
逻辑取反运算符(改变单个表达式的真假)。
-
“&&”
与运算符,就是并且的意思(两侧表达式都为真才为真否则为假)。
-
“||”
或运算符,就是或者的意思(两侧表达式都为假才为假否则为真)。
注:C语言中,0表示假,非0为真。
3.分支
3.1.if语句
3.1.1.普通if判断语句
判断一个非0整数数是否为偶数,我们可以写出下方代码
#include<stdio.h>
int main()
{
int n;
printf("请输入一个非0整数:"); scanf("%d", &n);
if (n % 2 == 0)//如果这个数是2的倍数则为偶数
printf("%d为偶数\n",n);
return 0;
}
3.1.2.if…else分支语句
判断一个非0整数数为奇数还是偶数,我们可以用if…else组合写出下方代码
#include<stdio.h>
int main()
{
int n;
printf("请输入一个非0整数:"); scanf("%d", &n);
if (n % 2 == 0)
printf("%d为偶数\n", n);
else
printf("%d为奇数\n", n);
return 0;
}
3.1.3.if语句判断的多语句执行
if判断为真后,如果if下方不加{}
就只会执行下面一条语句,如果要执行多条语句,使用{}
将需要执行的语句括起来,构成一个整体。else同理。
eg:如果我们要判断一个人是否成年,然后就可以知道他是否可以去网吧。我们可以写以下代码:(流程如图1所示)
#include<stdio.h>
int main()
{
int n;
printf("请输入一个人的年龄:"); scanf("%d", &n);
if (n < 18)
{
printf("未成年\n");
printf("不可以去网吧\n");
}
else
{
printf("成年了\n");
printf("可以去网吧\n");
}
return 0;
}
如果不加大括号就会造成以下情况(流程如图2所示)
#include<stdio.h>
int main()
{
int n;
printf("请输入一个人的年龄:"); scanf("%d", &n);
if (n < 18)
printf("未成年\n");
else
printf("成年了\n");
printf("可以去网吧\n");//语句1
return 0;
}
根据结果可以得出,无论成年还是未成年都会输出语句1,这里显然不符合要求。
3.1.4.if语句的嵌套
当我们要判断一个数是负数、0、正数且为正数的时候判断是奇数还是偶数,。我们就可以用一个if嵌套来实现。
#include<stdio.h>
int main()
{
int n;
printf("请输入一个数:"); scanf("%d", &n);
if (n != 0)
{
if (n > 0)
{
if (n % 2 == 0)
printf("%d是正数且是偶数\n", n);
else
printf("%d是正数且是奇数\n", n);
}
else
printf("%d是负数\n", n);
}
else
printf("%d是零\n", n);
return 0;
}
3.1.5.else if语句
使用else if语句可以在一定程度上使代码更简洁,也可以减少循环次数,如3.1.4的例题可简化为以下代码
#include<stdio.h>
int main()
{
int n;
printf("请输入一个数:"); scanf("%d", &n);
if(n>0&&n%2==0)
printf("%d是正数且是偶数\n", n);
else if(n>0&&n%2!=0)
printf("%d是正数且是奇数\n", n);
else if(n<0)
printf("%d是负数\n", n);
else if(n==0)
printf("%d是零\n", n);
return 0;
}
3.1.6.多个if…else的就近原则
#include<stdio.h>
int main()
{
int n;
printf("请输入一个数:"); scanf("%d", &n);
if (n > 0)//if1
if (n == 1)//if2
printf("hehe\n");
else//else1
printf("haha\n");
return 0;
}
if2与else1离得近,所以if2与else1是一个组合,当输入的数大于0时进入if2与else1的组合再进行判断打印结果,如果不大于0则什么也不输出。
如果if1与else1构成一个组合,输入一个不大于0的数应该会打印“haha”,但结果并没有,具体结果和流程图如下:
3.1.7.==
与=
搞混写入if语句造成结果
当我们要判断一个数等于3时打印"haha",==
与=
搞混时,代码如下
正常代码:
#include<stdio.h>
int main()
{
int n;
printf("请输入一个数:"); scanf("%d", &n);
if (n == 3)
printf("haha");
return 0;
}
错误代码:(==
写成=
时,使n被赋值3,3为非0,if语句判断为真,所以不论输入何值都会进行打印)
#include<stdio.h>
int main()
{
int n;
printf("请输入一个数:"); scanf("%d", &n);
if (n = 3)
printf("haha");
return 0;
}
3.2switch语句
switch语句相当于多个if…else结构用于判断条件有多个结果的情况,可以把多重else if改成更易用、可读性更好的形式。
3.2.1.switch语句的格式
switch(表达式){//表达式必须是整形表达式
//case后面的值必须是整形常量表达式,case和值之间要加空格
case 值1: 结果1//如果表达式满足值1,就会执行结果1
case 值2: 结果2//如果表达式满足值2,就会执行结果2
default: 结果3//如果值1和值2都不满足,就会执行default后的结果
}
不满足整形VS报错情况如下:
3.2.2.switch和break
switch语句中,case后面如果判断为真就执行case后面的语句,但如果没有一个出口,就会一直执行下面的语句直到switch结束。
eg:求一个数除以3的余数。
错误代码:(流程图如图1所示)
#include<stdio.h>
int main()
{
int num;
printf("请输入一个大于0的数:"); scanf("%d", &num);
switch (num%3)
{
case 1:printf("余数为1\n");
case 2:printf("余数为2\n");
default:printf("余数为0\n");
}
return 0;
}
正确代码:(流程图如图2所示)
#include<stdio.h>
int main()
{
int num;
printf("请输入一个大于0的数:"); scanf("%d", &num);
switch (num%3)
{
case 1:printf("余数为1\n"); break;
case 2:printf("余数为2\n"); break;
default:printf("余数为0\n"); break;
}
return 0;
}
不一定每一个case后面都要跟一个break语句,如当我们需要知道一天是工作日还是周末,我们就可以写出下面代码。(流程图如图3所示)
#include<stdio.h>
int main()
{
int day;
printf("请输入今天星期几:"); 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;
default:printf("输入错误\n"); break;
}
return 0;
}
3.2.3.switch语句中case和default的顺序问题
在switch语句中,我们对case
和default
的顺序并不做要求,只要case
和default
的顺序能够满足需求就行,不过一般是将default
放在最后处理。
4.循环
4.1.while语句
4.1.1.while语句格式
while(表达式)//当表达式为真时,进入循环
//while默认只控制一条语句
语句;//如果要多语句执行,需将多条语句套上大括号
4.1.2.流程图
eg:打印1-10的数。
#include<stdio.h>
int main()
{
int n = 1;
while (n <= 10)
{
printf("%d ", n);
n++;
}
return 0;
}
4.2.for语句
4.2.1.for语句格式
for(表达式1;表达式2;表达式3)
语句;//默认控制一条语句,如果想控制多条语句加大括号
//注意:
//1.表达式之间用分号隔开,括号最后不加分号
//2.表达式1用于循环变量初始化
//3.表达式2用于循环结束条件判断
//4.表达式3用于循环变量的调整
//5.表达式1、2、3均可省略,但分号不能省略
4.1.2.流程图
eg:打印1-10的数。
#include<stdio.h>
int main()
{
int n;
for (n = 1; n <= 10; n++)
{
printf("%d ", n);
}
return 0;
}
4.3.while循环和for循环对比
for循环和while循环都有变量初始化、循环结束判断、调整变量三个部分,但从上面对比图可以看出,for循环三个部分比较集中,便于代码的维护,如果代码多时while循环比较分散,所以形式上for循环更好一点。
4.4.do…while循环
4.4.1.do…while格式
do
语句;//默认控制一条语句,如果想控制多条语句加大括号
while(表达式);//分号不要忘
和while语句、for语句不同的是do…while语句是先执行语句,再判断表达式是否继续循环;while语句和for语句是先进行判断,再判定是否执行语句。
4.1.2.流程图
eg:打印1-10的数。
#include<stdio.h>
int main()
{
int n=1;
do
{
printf("%d ", n);
n++;
} while (n <= 10);
return 0;
}
4.5.continue和break语句
在循环进行过程中,某些状况发生的时候,需要提前终止循环,这是非常常见的现象。这时可以使用判断语句,在加break
和continue
两个关键字加入到循环语句中。
break: 用于永久终止循环,只要break
执行,直接跳出循环,继续往后执行。
continue: 跳出本次循环continue
后的代码,循环是否停止还要根据判断语句执行,在for循环和while循环中有所差异。
4.5.1.while中的continue和break语句
break举例
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;//i等于5时执行break语句,结束循环
printf("%d ", i);
i++;
}
return 0;
}
打印1、2、3、4后,i等于5,执行break
语句,跳出循环,不再进行后面的打印,所以只要break
语句被执行,就永久终止循环了。
continue举例
continue
是继续的意思,跳出本次循环continue
后的代码,循环是否停止还要根据判断语句执行。如果将上面代码中的break
换成continue
,程序会发生什么呢?
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;
//continue执行后就会跳过后面的i++语句和语句1,i就一直等于5,程序就会进入死循环
printf("%d ", i);//语句1
i++;
}
return 0;
}
4.5.2.for中的continue和break语句
break举例
for循环中的break语句和while循环中一样,只要被执行就会直接终止循环,举例代码如下:
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=10;i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
continue举例
如果我们将上面代码中的break换成continue又会是什么结果呢?
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=10;i++)
{
if (i == 5)
continue;
//这里执行了continue语句,对i++并无影响,只是跳过下面的语句1
printf("%d ", i);//语句1
}
return 0;
}
4.5.3.while循环和for循环中continue的区别
4.5.4.do…while中的continue和break语句
do…while中的continue和break语句和while中的continue和break语句的作用几乎一模一样
break举例
#include <stdio.h>
int main()
{
int i=1;
do
{
if (i == 5)
break;
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
continue举例
#include <stdio.h>
int main()
{
int i=1;
do
{
if (i == 5)
continue;
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
4.6.goto语句
goto语句可以实现在同一函数内跳转到设置好的标号处。
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
注意: goto语句有一个致命的缺点,一旦滥用goto语句将会导致逻辑混乱,导致系统崩溃等问题!!!