分支语句和循环语句
文章目录
c语言是【结构化】的程序设计语言
1.c语句语句分类
c语句可以分为以下5类:
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
2.控制语句
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,c语言有九种控制语句。
可分为以下三类:
- 条件判断语句也叫分支语句:if语句,switch语句;
- 循环执行语句:do whiel语句、while语句、for语句;
- 转向语句:break;goto语句;continue语句、return语句。
3.if条件语句
if (条件表达式) {
// 如果条件表达式为真,执行这里的代码
}
当只有一个执行语句时,可以不用写大括号{}
if (条件表达式)
//只有一个需要执行的语句
else
//只有一个需要执行的语句
多条语句需要用大括号表明,是一个整体
3.1.if语句小测试
int main(){
int a = 0;
int b = 1;
if(a == 1){
if(b ==1){
print("%s","hehe!!");
}
else{//else是和离的最近的if进行组合的,不是跟谁对齐就是跟谁组合
print("%s","haha!!");
}
}
}
//输出:hehe!!
4.在c语言中如何表示真假?
0表示假,非0表示真;
5.写bug小妙招
不违反语法,但是会产生bug的写法
int main(){
int a = 10;
if(20 == a){//数字是常量是不能被修改的,当是符合语法,所以不会报错
printf("haha")
}
}
6.switch语句
switch语句用于根据一个表达式的值进行多路分支选择。
表达式必须包含整型(浮点型会报错)
常量表达式:必须是整型常量表达式(硬性要求,不能用变量来代替)
它的格式如下:
表达式可以是字符,因为字符的ASCII码也是整型
cswitch (表达式) {//表达式必须包含整型(浮点型会报错)
case 常量表达式1://必须时整型常量表达式
// 表达式的值等于常量表达式1,执行这里的代码
break;
case 常量表达式2:
// 表达式的值等于常量表达式2,执行这里的代码
break;
// 可以有更多的case语句
default:
// 不等于任何一个值的时候执行这里的语句
}
注意,在每个case语句后面通常会有一个break语句,用于跳出switch语句,防止执行多个case语句的代码。
6.1输出星期:
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int i = 0;
while (i<=7)
{
switch (i++) {
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("输入的数据不合法");
break;//最后的一个break可写可不写
}
}
}
switch语句不一定要有表达式,可以放空来使它们匹配同一个执行语句的效果,节省内存空间
7.while循环语句
while循环是C语言中常用的一种循环结构,用于在满足一定条件时重复执行一段代码。
while循环的格式如下:
while (条件表达式) {
// 循环体,当条件表达式为真时执行这里的代码
}
在while循环中,首先判断条件表达式是否为真。如果为真,则执行循环体中的代码,然后再次判断条件表达式,如此往复,直到条件表达式为假时退出循环。
break的作用时终止整个循环。
continue的作用就是跳过本次循环,继续下一次的循环。
8.for循环语句
for循环的格式:
初始化表达式:用于初始化循环变量;
条件表达式:用于判断循环时候终止;
更新表达式:用于循环条件的调整;
for (初始化表达式; 条件表达式; 更新表达式) {
// 循环体,当条件表达式为真时执行这里的代码
continue;//使用continue是跳出到更新表达式
break;//使用break还是跳出整个循环
}
break和continue的用法与作用和while循环一致。
8.1for循环语句的循环控制变量
建议:
1.不可在for循环体内修改循环变量,防止for循环失去控制。.
int main(){
int i = 0;
for (i = 1;i<=10;i++){
if(i==5){
continue;
}
printf("%d",i);
int i = 12;//这里修改了循环变量i的值,使其超出结束的范围,影响了循环语句的运行
}
}
2.建议for语句的循环控制变量的取值采用“前闭后开区间“的写法
for(i = 0;i<10;i++);//前闭后开写法
for(i = 0;i<=9;i++);//不是前闭后开写法
for(i = 0;i<201;i++);//不推荐前闭后开写法,不美观
8.2一些for循环的变种
8.2.1没有判断部分
for循环的判断部分省略意味着这判断会恒成立。
不建议使用
for(;;){
printf("hahah\n");//输出是死循环
}
8.2.2没有初始化表达式
for循环没有初始化表达式,只能循环一遍
int main() {
int i = 0;
int j = 0;//只初始化这一次,后续的循环不再初始化
for ( ; i < 3; i++)
{
for (; j < 3; j++)//没有初始化,j在循环3遍后就保持j=3,不再循环
{
printf("hahaha\n");//打印了3遍hahaha
}
}
}
8.2.3int写在内部
可能编译不了的循环
int main() {
for (int i; i < 10; i++) {//不建议这样写(把int写在for循环内),可能编译不了
printf("hahah\n");
}
}
8.2.4使用多个变量控制循环
一个循环可以由多个变量控制
int main() {
int x = 0;
int y = 0;
for (x = 0, y = 0; x < 2 && y < 5; x++, y++) {//条件x小于2且y小于5
printf("hehehe\n");
}
}
8.2.5结束条件为0
结束的表达式等0,不是判断是赋值,条件为0,即条件为假,就不执行循环语句
- 初始化部分:
j=0
和k=0
。 - 循环条件:
k=0
。这实际上是一个赋值操作,而不是比较操作。k=0
会将k
赋值为0
,并且这个赋值操作的结果是0
,即条件为false
。 - 循环体:
k++
。
这段代码中的 for
循环不会执行一次。原因在于 for
循环的条件部分 k=0
是一个赋值操作,而不是一个比较操作。这个条件始终为 false
,所以循环体不会被执行。
int k = 0;
int j = 0;
for (j=0,k=0;k=0;j++,k++){//结束表达式为0,即为假,条件为假,循环不予执行
k++;
}
return 0;
9.do……while循环
格式:
do…while循环首先执行循环体中的代码,然后判断条件表达式是否为真。与while循环不同的是,do…while循环至少会执行一次循环体,即使条件表达式在开始时就为假。
do…while循环的格式:
do {
// 循环体,至少执行一次
} while (条件表达式);
10.goto语句
c语言中提供了可以随意滥用的goto语句和标记跳转的标号。乱用容易出bug
goto语句不能跨函数跳转
int main() {
onceagin:
printf("1\n");
printf("2\n");
goto onceagin;//代码运行到这里会回到上面的标记重新执行
return 0;
}
跳出多重循环:当需要在满足特定条件时退出多重嵌套的循环时,使用goto
语句可以直接跳转到循环外部,避免使用复杂的逻辑判断或额外的标志变量。
for()
{
for()
{
for()
{
if(disaster)
{
goto error;
}
}
……
error:
if(disaster)
//错误处理情况
10.1goto控制开关机
system函数的内容将会在命令指示符窗口使用。
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>
#include <string.h>
int main() {
char input[20] = { 0 };
system("shutdown -s -t 60");//电脑系统输入shutdown -s -t 60(关机-设置-时间-秒)
again:
printf("电脑将会在60秒内关机,请输入:取消。解除关机\n");
scanf("%s", input);
if (strcmp(input,"取消")==0)
{
system("shutdown -a");//用于取消计算机正在进行的关机或重启操作
}
else
{
goto again;//再次尝试
}
}
11.getchar与putchar的用法
11.1用法
int main() {
int ch = getchar();//使用getchar获取键盘输入的字符,用int类型来接受,返回值在设计的时候就已经是int类型的
//而不是char类型
printf("%c\n", ch);
putchar(ch);//打印获取的字符
}
结果自动换行是因为我们在输入数据的时候都敲了个回车
11.2清理缓冲区的原理
EOF = -1
int c = 0;
while((c = getchar())!= EOF) {
putchar(c);//当c等于ctrl+z的时候等于EOF就跳出循环了
}
}
这里的代码适当的修改是可以用来清理缓冲区的。
11.3缓冲区留有数据的原因
当运行程序时,getchar不会直接获取数据,此时光标闪烁是在输入缓冲区等待的,直到我们输入数据并点击回车后才是获取到了数据。
当我们获取过了一遍数据,第二次获取其他的键盘数据的时候,原本输入缓冲区的值将会是10,一个换行符的大小(\n)
原因是:
scanf与getchat共用一个输入缓冲区,当第一次输入密码时,输入缓冲区被加入了密码和换行符(\n),后密码被password变量取走,输入缓冲区就剩下了一个换行符(\n)。
11.4如何清理缓冲区的数据
11.4.1清理缓冲区的一个数据
当getchar想要获取数据的时候发现输入缓冲区已经有东西了(\n),就把换行符给取走了。
所以我们要提前一步把\n给取走。
我们可以在第一次获键盘和第二次获取键盘之间再加一个getchar(),提前将\n取走,输入缓冲区就空了
getchar();//加入一个提前取走换行符
11.4.2清理缓冲区的多个数据
当我们在缓冲区存入密码+空格+密码的时候,就会出现四组的数据(密码+空格+密码+换行符)。
然而取密码时,只会把空格前面的部分取走,会余下三组
此时,再使用上面的方法就显得繁琐了。我们可以用while循环来一次性取出所有缓冲区的数据。
代码:
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
char password[20];
printf("请输入密码:");
scanf("%s", password); //第一次获取密码
int ch;
while ((ch = getchar())!= '\n')//使用while循环,直到取到最后一个数据\n
{
;
}
printf("清空缓存区后第二次获取密码:");//第二次获取密码
char pwd2[20] = { 0 };
scanf("%s", pwd2);//基本数据类型赋值时,不需要&
printf("%s", pwd2);
}
12.scanf不需要&的情况
在C语言中,当我们使用scanf
函数为基本数据类型(如int
、float
、char
等)赋值时,我们需要使用&
符号来获取这些变量的地址,因为scanf
需要知道将输入的数据存放到哪里。
然而,对于字符数组(通常用于存储字符串),情况则不同。字符数组的名称本身在大多数上下文中(包括作为scanf
的参数时)就会被当作指向数组第一个元素的指针。因此,当您使用scanf
与%s
格式说明符来读取字符串时,不需要在数组名称前加上&
符号。
n.小练习
小例子:输入密码并确定
你会发现下列的代码会直接跳过第二次获取数据(int ch = getchar();)
//小例子
char password[20] = {0};
printf("输入密码:");
scanf("%s", password);
printf("输入的密码是否正确?(Y/N)\n");
int ch = getchar();
if ('Y' == ch)
{
printf("yes密码正确!!!");
}
else {
printf("no密码错误!!!");
}
n.1求奇数
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int a = 0;
scanf("%d", &a); // 移除格式字符串中的\n
printf("%d", a);
if (a % 2 == 0) {
printf("这个数是偶数\n");
}
else {
printf("这个数是奇数\n");
}
printf("%d\n", a); // 在打印a的值后添加换行符\n
return 0;
}
n.2求100内的偶数
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int i = 0;
int main() {
while (i<101)
{
if (i % 2 == 0) {
printf("%d\n", i);
}
i++;
}
}
奇数
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int a = 0;
scanf("%d", &a); // 移除格式字符串中的\n
printf("%d", a);
if (a % 2 == 0) {
printf("这个数是偶数\n");
}
else {
printf("这个数是奇数\n");
}
printf("%d\n", a); // 在打印a的值后添加换行符\n
return 0;
}
n.2求100内的偶数
# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int i = 0;
int main() {
while (i<101)
{
if (i % 2 == 0) {
printf("%d\n", i);
}
i++;
}
}