分支循环语句和getputchar的用法

分支语句和循环语句


c语言是【结构化】的程序设计语言

1.c语句语句分类

c语句可以分为以下5类:

  1. 表达式语句
  2. 函数调用语句
  3. 控制语句
  4. 复合语句
  5. 空语句

2.控制语句

控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,c语言有九种控制语句。

可分为以下三类:

  1. 条件判断语句也叫分支语句:if语句,switch语句;
  2. 循环执行语句:do whiel语句、while语句、for语句;
  3. 转向语句: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;
        defaultprintf("输入的数据不合法");
            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,即条件为假,就不执行循环语句

  1. 初始化部分j=0k=0
  2. 循环条件k=0。这实际上是一个赋值操作,而不是比较操作。k=0 会将 k 赋值为 0,并且这个赋值操作的结果是 0,即条件为 false
  3. 循环体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函数为基本数据类型(如intfloatchar等)赋值时,我们需要使用&符号来获取这些变量的地址,因为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++;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值