文章目录
序言
C语⾔是一门结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构这三种结构。
我们一般使⽤ if 、 switch关键字实现分⽀结构,使⽤ for 、 while 、 do while 等关键字实现循环结构。
一、if语句
1、if
if 语句的语法形式如下:
if (表达式)
语句
在C语⾔中,0为假,⾮0表⽰真。如果表达式的结果为真,就执⾏语句;为假,就不执⾏语句。
例如:输⼊⼀个整数,判断是否为奇数
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 2 == 1)
{
printf("%d是奇数\n", num);
}
return 0;
}
运行结果:
可以看到当我们输入3,满足表达式,表达式的结果为真,就执行语句。
2、else
如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要判断它是奇数还是偶数该怎么表⽰呢?那么这⾥就需要 if else 语句了,语法形式如下:
if (表达式)
语句1
else
语句2
例如:输⼊⼀个整数,如果是奇数就打印奇数,否则打印偶数。
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 2 == 1)
{
printf("%d是奇数\n", num);
}
else
{
printf("%d是偶数\n", num);
}
return 0;
}
运行结果:
可以看到当我们分别输入奇数和偶数时都会打印对应的语句。
3、嵌套if
在 if else 语句中,如果有多个条件需要判断,我们可以再else下面再套用if else语句。
例如:输⼊⼀个整数,如果是正数,再判断是奇数还是偶数;如果不是正数就输出负数。
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num > 0)
{
if (num % 2 == 1)
{
printf("%d是奇数\n",num);
}
else
{
printf("%d是偶数\n",num);
}
}
else
{
printf("输入的数是负数\n");
}
return 0;
}
运行结果:
以上就是嵌套if语句的用法,有了嵌套if语句,就可以完成更多复杂逻辑的判断。
例如:输⼊⼀个⼈的年龄
如果年龄<18岁,打印"少年"
如果年龄在18岁⾄44岁打印"⻘年"
如果年龄在45岁⾄59岁打印"中⽼年"
如果年龄在60岁⾄89岁打印"⽼年"
如果90岁及以上打印"⽼寿星"
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("少年\n");
}
else
{
if (age < 44)
{
printf("青年\n");
}
else
{
if (age < 59)
{
printf("中老年\n");
}
else
{
if (age < 89)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
}
}
}
return 0;
}
运行结果:
4、悬空else问题
如果有多个if 和一个else ,可以记住这样⼀条规则: else 总是跟最接近的 if 匹配。
例如:
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
运行结果:
我们可以看到,结果没有显示任何东西,因为a一开始被赋值为0,第一个if语句条件是a==1,不满足为假就执行else语句,但是没有对应的else语句,因为后面的else是和第二个if语句匹配的,因此就不打印任何东西。
我们我们希望else语句和第一个if语句匹配,只需要让第二个if语句成为第一个if语句下面的内容即可。
如下:
#include<stdio.h>
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语句匹配上了,if语句为假就执行了else语句。
二、关系操作符
C语⾔中⽤来⽐较的表达式,被称为关系表达式,关系表达式使⽤的运算符就称为关系运算符,主要有6个:
- ⼤于 : >
- ⼩于 : <
- ⼤于等于: >=
- ⼩于等于: <=
- 相等: ==
- 不相等: !=
使用方法就是a == b、a >= b
这样即可。
关系表达式的返回值一般是0或者1,0表示假,1表示真。
关系表达式常⽤于 if 或 while 结构。
注意:赋值操作符=和关系操作符==很容易写错,如果把if (x == 3)
写成了if (x = 3)
,因为x=3的返回值是3,所以if会一直判断为真。为了防止这种错误,以后如果在使用关系操作符 == 的时候,我们可以将数字写在前面,如if (3 == x)
这样,就可以避免犯错。
在关系操作符使用的时候还有一点需要注意:多个关系运算符不宜连⽤。
例如:i < j < k
这个表达式,本身是合法的不会报错,但是无法实现 j 的值在 i 和 k 之间,为什么呢?因为关系操作符计算时是从左到右,所以实际上是先计算i<j,返回值的0或1再和k进行比较。
如果想要实现 j 的值在 i 和 k 之间应该用:i < j && j < k
例如:我们输⼊⼀个年龄,如果年龄在18~36之间,我们就输出⻘年。
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18 && age <= 36)
{
printf("青年\n");
}
return 0;
}
三、条件操作符(三目操作符)
条件操作符也叫三⽬操作符,需要接受三个操作数的,形式如下:exp1 ? exp2 : exp3(exp1为表达式)
。
条件操作符的计算逻辑是:如果exp1为真,结果就为exp2,否则就为exp3。
例如:使⽤三目表达式找到两个数中的较⼤值。
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = a > b ? a : b;
printf("%d\n", c);
return 0;
}
使用三目操作符 a > b ? a : b
判断输入a,b的大小,a>b为真就返回a,否则就返回b。
四、逻辑操作符: !&& ||
逻辑运算符提供逻辑判断的功能,可以构建更复杂的表达式,主要有下⾯三个运算符。
① ! : 逻辑取反
② &&:逻辑与(都为真才为真)
③ || :逻辑或(有一个为真就为真)
1、 !
!:让一个变量由真变假,或由假变真。
例如:
#include<stido.h>
int main()
{
int flag = 0;
if (!flag)
{
printf("true");
}
else
{
printf("false");
}
return 0;
}
我们可以看到,flag被初始化为假,! flag让假变为真,所以执行if下面的语句。
2、&&
&&:两个都为真才为真。
例如:3⽉到5⽉是春天
#include<stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (month >= 3 && month <= 5)
{
printf("春季\n");
}
}
可以看到只有同时满足 month>=3 和 month<=5 才为真,才会执行语句。
3、||
||:有一个为真就为真。
例如:12月、1⽉或者2⽉是冬天
#include<stdo.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (month == 12 || month == 1 || month == 2)
{
printf("冬季\n");
}
return 0;
}
可以看到只要满足month == 12 、month == 1 、month == 2
三个条件中的一个就为真,就可以执行if语句。
练习:闰年的判断
#include<stdio.h>
int main()
{
int year = 0;
scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
printf("%d是闰年\n",year);
}
else
{
printf("%d不是闰年\n",year);
}
return 0;
}
4、短路
短路是指逻辑与(&&)和逻辑或(||)运算符在计算时,当左边表达式的值能确定整个逻辑表达式的结果时,就不再计算右边的表达式。
使用&&时,如果左侧表达式为假,那么整个表达式就为假,剩下的表达式都不会计算。例如:if(month >= 3 && month <= 5)
,如果输入的month是2,左边的表达式就为假,那么整个表达式也为假。
对于 || 来说:只要有一个为真,那么整个表达式就为真,剩下的表达式也都不计算。
例如:month == 12 || month == 1 || month == 2
,如果输入的month是12,那么整个表达式就为真。
练习:
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3;
i = a++ && ++b && c++;
printf("a=%d b=%d c=%d", a, b, c);
return 0;
}
运行结果:
我们可以看到,a++是先使用后++,所以表达式a++的值就是0,为假,又因为使用&&运算符,所以整个表达式的值就为假,后面的表达式都不会计算,因此最后的值b和c不会改变,而a因为后置++才变成1。
五、switch 语句
除了 if 语句外,C语⾔还提供了switch 语句来实现分⽀结构。
switch 语句是⼀种特殊形式的 if else 结构,⽤于判断条件有多个结果的情况。
语法如下:
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
上⾯语法中,会根据表达式 expression 的值,执⾏对应的 case 分⽀;如果找不到对应的值,就执⾏ default 分⽀。
对于switch的使用还有个注意事项:expression 和 value 都必须是整型表达式!
我们进行一个练习:输出一个整数除3的余数。
如果使⽤if语句:
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 3 == 0)
printf("%d除3的余数是0\n",num);
else if (num % 3 == 1)
printf("%d除3的余数是1\n",num);
else
printf("%d除3的余数是2\n",num);
return 0;
}
如果使用switch语句,就更加的简便。
int main()
{
int num = 0;
scanf("%d", &num);
switch (num % 3)
{
case 0:
printf("%d除3的余数是0\n", num);
break;
case 1:
printf("%d除3的余数是1\n", num);
break;
case 2:
printf("%d除3的余数是2\n", num);
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
return 0;
}
运行结果:
我们可以观察到,switch其实还有一个注意点,就是分支中的语句执行完后,都要加break,这样才能跳出switch分支。
当然有时也不是每个分支都加break,例如:输⼊⼀个1~ 7的数字,1~ 5输出工作日,6~7输出节假日。
#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;
default:
printf("输入错误,请重新输入!\n");
break;
}
return 0;
}
运行结果:
实际上,当我们输入2时由于没有break语句,它就会接着往下执行,直到碰到break语句才会停止。
六、三种循环
1、while循环
C语⾔提供了3种循环语句, for、while、do while,我们先来讲解while语句,while语句和if语句的语法是类似的。如下:
if(表达式)
语句;
while(表达式)
语句;
但是他们也存在着区别:
#include<stdio.h>
int main()
{
if(1)
printf("hehe\n");
return 0;
}
运行结果:
#include<stdio.h>
int main()
{
while(1)
printf("hehe\n");
return 0;
}
运行结果:
我们可以看到,当if语句的表达式为真时,会执行一次if语句的代码,而while语句的表达式为真时,就会循环执行while语句的代码。
while循环的使用规则:先判断表达式,表达式为假跳出循环;为真就执行语句,并再次判断表达式。
练习1:输出1~10的整数。
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
return 0;
}
练习2:输⼊⼀个正整数,逆序打印这个整数的每⼀位。例如:输⼊:1234,输出:4 3 2 1
思路:while循环%10得到末尾,再/10。
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
while (num)
{
printf("%d ", num % 10);
num /= 10;
}
return 0;
}
2、for循环
for 循环是三种循环中使⽤最多的, for 循环的语法形式如下:
for(表达式1; 表达式2; 表达式3)
语句;
表达式1:初始化。
表达式2:判断结束条件。
表达式3:调整。
for循环的使用规则:先初始化,再判断表达式2,为假跳出循环,为真就执行语句、并调整,再进行判断。
练习1:输出1~10的整数。
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
练习2:输出1~100之间3的倍数的数字之和。
思路:遍历1-100,如果是3的倍数就求和。
#include<stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 1; i <= 100; i++)
{
if (i % 3 == 0)
{
sum += i;
}
}
printf("%d\n", sum);
return 0;
}
可以再优化一下:将for (i = 1; i <= 100; i++)
改为for (i = 3; i <= 100; i+=3)
。
3、do-while 循环
在循环语句中 do while 语句使⽤得最少,它的语法如下:
do
{语句};
while(表达式);
while 和 for 这两种循环都是先判断满⾜条件就执⾏语句,如果不满⾜就跳出循环;
⽽ do while 循环是先进⼊循环体,执⾏一遍语句,再判断表达式,为真就执行语句,为假就跳出循环。
特点:do while循环至少执行一次。
练习1:输出1~10的值
#include<stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i<=10);
return 0;
}
练习2:计算一个正整数的位数。例如输⼊1234 ,输出4。
#include<stdio.h>
int main()
{
int count = 0;
int num;
scanf("%d", &num);
do
{
count++;
num /= 10;
} while (num);
printf("%d", count);
return 0;
}
任何一个数都至少是一位数,而do while循环至少执行一次就很适合。
七、break和continue语句
break语句的作⽤:跳出整个循环,继续往后执行。
continue语句的作⽤:跳过本次循环 continue 后边的代码,继续循环。
1、在while循环中
1)break语句
break语句的使用:
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
{
break;
}
printf("%d ", i);
i++;
}
return 0;
}
可以看到循环执行了4次,而到第5次的时候由于有break语句,就直接跳出循环。
2)continue语句
continue语句的使用:
int main()
{
int i = 1;
while (i <= 8)
{
if (i == 5)
{
continue;
}
printf("%d ", i);
i++;
}
return 0;
}
我们可以看到,代码陷入了死循环,那么为什么呢?当进入第5次循环时,由于执行了continue语句,所以后面的printf("%d ", i)
和i++
这两句都不会执行,那么 i 就会一直停留在4,就会导致一直死循环。
那我们该如何修改代码呢?其实我们只需要在break语句之前先执行一遍i++
,即使break语句让后面的语句不再执行,可是在它之前已经执行了一遍i++
,就不会影响后续的循环,而只会跳过本次循环。
int main()
{
int i = 1;
while (i <= 8)
{
if (i == 5)
{
i++;
continue;
}
printf("%d ", i);
i++;
}
return 0;
}
2、在for循环中
1)break语句
与while循环中一致,只要执行到break语句就直接跳出整个循环,再继续往后执行。
#include<stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5)
{
break;
}
printf("%d ", i);
}
return 0;
}
2)continue语句
与while循环中也一致,执行到continue语句,就跳过本次循环之后的代码,再进行下一轮循环。
#include<stdio.h>
int main()
{
int i = 1;
for (i = 1; i <= 10; i++)
{
if (i == 5)
{
continue;
}
printf("%d ", i);
}
return 0;
}
3、在do while循环中
1)break语句
用法同上一致:
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
{
break;
}
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
2)continue语句
用法也同上一致:
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
{
continue;
}
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
八、循环嵌套
前⾯学习了三种循环 while 、for、 do while ,这三种循环往往嵌套在⼀起使用才能更好解决问题,也就是我们所说的:循环嵌套。
练习:打印100-200之间的素数
注:素数⼜称质数,只能被1和本⾝整除的数字。
思路:先遍历100到200的整数,再判断整数能否被从2到自身前一位的数整除,不能整除就是素数。
#include<stdio.h>
int main()
{
for (int num = 100; num <= 200; num++)
{
//先假设是素数
int flag = 1;
//遍历2到自身前一位的数
for (int i = 2; i <= num - 1; i++)
{
//能整除就不是素数,跳出循环。
if (num % i == 0)
{
flag = 0;
break;
}
}
//遍历完都不能整除 就是素数
if (flag == 1)
{
printf("%d ", num);
}
}
return 0;
}
九、goto语句
goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
例如:
#include<stdio.h>
int main()
{
goto next;
printf("hehe\n");
next:
printf("haha\n");
return 0;
}
可以看到当执行到goto语句时,我们会直接跳转到标号处继续执行。
在多层循环的代码中,想要快速跳出就可以使⽤goto语句。
for (...)
{
for (...)
{
for (...)
{
if (disaster)
goto error;
}
}
}
error
...
这串代码中想要跳出3层for循环嵌套就得使⽤3个 break语句,如果使用goto语句就相当的简单了。