第一关 分支与循环语句

发布于:2023-02-14 ⋅ 阅读:(450) ⋅ 点赞:(0)

目录

分支语句

一,if分支语句

1.if语句的使用

2.常见错误和规范

3.例题

二,switch 分支语句

1.使用方法

2.例题

循环语句

一,while语句

1.使用方法

2.while中的break和continue

3.例题

二,for循环

1.使用方法

​编辑。

注意事项:

2.for循环中break与continue的使用方法

3.特殊的for循环代码

4.例题

三,do...while循环

使用方法:

四,goto语句

用法:

正确用法:

五,循环练习题

1.计算n的阶乘

2.计算 1!+2!+3!+……+10!

3.在有序数组中查找某个数字n(重要的算法思想)

4. 编写代码,演示多个字符从两端移动,向中间汇聚。

5.编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。

6.猜数字游戏


​​​​​​

分支语句

一,if分支语句

1.if语句的使用

语法:

单分支:

if(表达式)    

        语句;

双分支:

if(表达式)    

        语句1;

else    

        语句2;

多分支:

if(表达式1)    

        语句1;

else  if(表达式2)  

        语句2;

else

        语句3;

表达式:表达式时决定选择方向的条件,当表达式结果为真时,执行if下的语句,为假时,进入其他位置。

语句:上述表达时为真时执行的语句。

单分支:

int main()
{ 
    int age=0;
    if (age < 18)
		printf("未成年\n");
    return 0;
}

 双分支

int main()
{ 
    int age=0;
    if (age < 18)
		//if包含多条语句时要用{}包含
	{
		printf("未成年\n");
		printf("不能喝酒\n");
	}
	else
		printf("成年\n");
    return 0;
}

注意:当 if 或 else下面包含多条执行语句时,需要用{ }包起来。

多分支:

int main()
{
    int age = 0;
	if(age < 0)
		printf("年龄输入有问题\n");
	scanf("%d", &age);
	if(age<18)
		printf("青少年\n");
	if(age >= 18 && age < 30)
		printf("青年\n");
	if(age >= 30 && age < 45)
		printf("中年\n");
	if(age >= 45 && age < 60)
		printf("壮年\n");
	if (age >= 60 && age < 90)
		printf("老年\n");
	else
		printf("寿星\n");
    return 0;
}

2.常见错误和规范

(1)先来看下面的代码

int main()
{    
    int a = 0;
	int b = 2;
	if (a == 1)
		if (b == 2)
			printf("hehe\n");
	else//会和最近的if匹配。
		printf("haha\n");
	return 0;
}

这个代码中else看起来和第一个if对其,但实际上程序并不会在第一个if结束走后到它,

这个else会和最近的if匹配

所以写代码时应将相应的if和else对齐。

(2)有时我们写代码时经常会将if()中表达式写成=

比如if(a=0);

这样写的代码有时编译器并不会报错,但这会在运行时导致一些错误产生

所以我们在写代码时可以将需要判断的表达式写为如下的样式:

int a=18;
if(18==a)
    printf("已成年")

将if(a==18)改为if(18==a),这样写,当我们忘记一个=号时,编译器会进行报错,提醒我们修改。

3.例题

练习1:判断一个数是非位奇数

int main()
{  
    int a = 0;
	scanf("%d", &a);
	if (1 == (a % 2))
	{
		printf("a为奇数\n");
	}
	else
	{
		printf("a为偶数\n");
	}
    return 0;
}

练习2:输出1~100之间的奇数

int main()
{  
    for (int i = 1;i <= 100;i++)
	{
		int b = i % 2;
		if (1 == b)
		{
			printf("%d\n", i);
		}
    }
    return 0;
}

二,switch 分支语句

1.使用方法

语法:

switch(整形表达式)

{

语句项:

}

(1)先通过一个例子来看

int main()
{
    int day = 0;
	scanf("%d", &day);
	switch (day)//day必须是整形
	{
	case 1://case后也必须是整形常量表达式
		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("输入有误\n");
		break;
	}
    return 0;
}

switch(表达式),其中 表达式 必须整形

case :接受switch表达式中的整形,如果和case后的整形相同,则将该case中的语句进行编译。

break:退出switch选择,如果没有break,则当前case结束后,会继续往下编译

default:当输入的值在case中未找到时,则进入default中

以上面的代码来说,当输入1时,进入case 1 语句,打印 星期一  然后break退出switch

当输入9时,因为case中未找到,进入default,打印 输入有误 然后break退出

(2)看下面一段代码

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;
}

当case中的语句相同时可用将其合并。如上代码。

编程好习惯 :

在每个 switch 语句中都放一条default子句是个好习惯,也可以在后边再加一个 break 。

2.例题

#include <stdio.h>
int main()
{
   int n = 1;
   int m = 2;
   switch (n)
   {
    case 1:
            m++;
    case 2:
            n++;
    case 3:
            switch (n)
           {//switch允许嵌套使用
             case 1:
                    n++;
             case 2:
                    m++;
                    n++;
                    break;
           }
    case 4:
            m++;
            break;
    default:
            break;
   }
    printf("m = %d, n = %d\n", m, n);
    return 0;
}

打印的结果为:m=5,n=3;

循环语句

一,while语句

1.使用方法

语法:

while(表达式)

{

         循环语句;

}

int main()
{
    int i = 1;
	while (i <= 10)
	{
		
		printf("%d ", i);
		i++;
	}
    return 0;
}

上述代码会打印数字1 2 3 4 5 6 7 8 9 10

whlie括号中的表达式是判断循环是否进行的依据,表达式为真时,进行循环,表达式为假时,跳出循环

2.while中的break和continue

(1)break

在循环中遇到break,就终止该循环。

int main()
{   
    int i = 1;
	while (i <= 10)
	{
		if (5 == i)
		{
			break;
		}
		printf("%d", i);
		i++;
	}
}

上述代码打印:1 2 3 4

(2)continue

continue是用来终止本次循环的,也就是本次循环中continue后的代码不会执行,直接跳转到while语句的判断部分,进行下一次循环的入口判断。

int main()
{
    int i = 1;
	while (i <= 10)
	{
		if (5 == i)
		{
			continue;//会跳过本次循环continue之后得到所有代码
		}
		printf("%d", i);
		i++;
	}
    return 0;
}

上述代码当i=5时,会进行continue,跳过本次循环

输出:1 2 3 4 6 7 8 9 10

3.例题

(1)输入一个字符并打印它

int main()
{
	int ch = 0;
	//定义一个字符,因为字符在计算机中储存为ASCII码值,所以可以定义为整形
	while ((ch = getchar()) != EOF)//当取到输入字符为EOF时,跳出循环
		putchar(ch);//putchar用于打印单个字符,打印ch
	return 0;
}

这段代码中

getchar(),putchar()函数
getchar()函数:从内存缓冲区中找到并拿走输入的一个字符
当你没有输入字符时,getchar函数会先等待输入,并从内存缓冲区中读取
putchar()函数:打印一个字符

1.内存缓冲区
我们前面提到getchar函数时从内存缓冲区中拿出一个字符,那这个内存缓冲区又是什么呢?
就是:键盘输入的内容不会直接进入内存中,而是先进入内存缓冲区,再进入内存。
 

2.什么是EOF
EOF表示end of file(文件结束标志),在计算机中它的定义是-1

getchar()函数可以在内存缓冲区中读取到一个输入字符
(ch = getchar())表示把getchar()得到的字符赋给ch这个函数的返回值,它的返回值应该是字符ch对应的ASCII码值
(ch = getchar()) != EOF 表示函数返回值不是EOF
注意:我们想向下运行程序需要按回车,回车输入的\n也是一个字符
getchar先读取到你输入的字符,比如字母a,还会读取缓冲区中还有一个输入的\n
相当于getchar先找到你输入的字符进行打印,然后又找到了\n,进行打印(即读完字符后又读了回车\n)
这个while语句实现了多次输入,而当我们想结束程序跳出循环时,只需要按ctrl+z就会使函数读取到EOF
输入:a
输出:a

(2)输入密码程序

int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	printf("请确认密码(Y/N):");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

 这个代码的问题是:
当你输出123456的时候,直接就确认失败了,按理来说scanf需要读取2次数据,但键盘上直接输入123456和回车,就直接结束了

scanf并不是直接从键盘中拿取数据的,在scanf与键盘之间还存在一个输入缓冲区.
scanf的工作原理是:先去输入缓冲区看一眼,有东西就读,没东西就等着输入.
实际上abcdef\n一开始输入的时候先放至缓冲区,这个时候scanf看到缓冲区有东西了,它就去拿走了123456放到password里面去了,
这个时候getchar读数据时发现缓冲区有\n(如果getchar发现缓冲区里面是空的,那么它将等待输入Y/N),于是把它读走放到ch上了,\n!='Y',因此确认失败。

3)打印字符串中的数字字符


int main()
{
    int ch = '\0';//对ch进行初始化,而'\0'的ASCII码为0 用char定义不严谨,因为getchar是由int而来,char的话可能会引发截断现象.
    while ((ch = getchar()) != EOF)//一个一个读取
    {
    if (ch < '0' || ch > '9')//相当于把它们的ASCII码值进行比较
        continue;//ch为非数字字符进入,跳过putchar
    putchar(ch);//为数字字符,不进入if,打印
    }
    return 0; 
}
//输入:abc1dcwrew123
//输出:1123

二,for循环

1.使用方法

语法:

for(表达式1;表达式2;表达式3)

{

循环语句;

}

表达式1 为初始化部分,用于初始化循环变量的。

表达式2 为条件判断部分,用于判断循环时候终止。

表达式3 为调整部分,用于循环条件的调整

for循环的四个步骤

int main()
{
    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        printf("%d ",i);//当i的值满足i<=10时打印i
        //在程序内的语句块执行完成后,程序执行调整语句i++,然后再次判断是否满足循环条件
    }
    return 0;
}
//输出:1 2 3 4 5 6 7 8 9 10

注意事项:

不要在语句内部改变循环变量,

int main()
{
	int i = 0;
	for(i = 1;i <= 10;i++)
	{
		printf("%d ", i);
		i = 5;
	}
	return 0;
}

上述代买会变为6 死循环。

2.for循环中break与continue的使用方法

 与while相同

3.特殊的for循环代码

(1)for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议省略。

int main()
{
    for(;;)
    {
        printf("hehe\n");
    }
    return 0;
}

(2)for循环可以嵌套

int main()
{
    int i = 0;
    int j = 0;
    //根据for循环的嵌套,这里会打印100个hehe
    for(i = 0; i < 10; i++)
    {
        for(j = 0; j < 10; j++)
        {
            printf("hehe\n");
        }
    }    
}

(3)省去for循环里面的初始化

int main()
{
    int i = 0;
    int j = 0;
    for(; i < 10; i++)
    {
        for(; j < 10; j++)
        {
            printf("哈哈\n");
        }
    }
    return 0;
}

上述代码,在第一次进入循环时程序正常工作j=10时跳出循环,

因为没有初始化变量j就会一直保持10,从此不会再次进入循环

所以只会打印10个哈哈

4.例题

下面的代码循环了对少次?

#include <stdio.h>
int main()
{
    int i = 0;
    int k = 0;
    for(i = 0,k = 0; k = 0; i++,k++)
        k++;
    return 0; 
}

答案:零次,在for循环的判断那里k=0的表达式值本来就为0,0为假,不循环

三,do...while循环

使用方法:

语法:

do

{

循环语句;

}while(条件);

它不管条件符不符合它就先执行,执行完在判断是否需要继续再执行一遍。
特点:循环至少执行一次。

//用do...while循环打印1~10
int main()
{
    int i = 1;
    do//先执行
    {
        printf("%d\n", i);
        i++;
    } while (i < 10);//判断能不能接着执行,若不能,则跳出
    return 0;
}
//输出:1 2 3 4 5 6 7 8 9 10

do...while中的break和continue和之前的一样。

四,goto语句

用法:

int main()
{
	printf("hehe\n");
	goto flag;
	printf("haha\n");
flag:
	printf("heihei\n");
	return 0;
}

因为goto语句会打乱原来C语言的顺序,且可以用更加稳定的循环来代替,所以一般不用goto语句
但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

正确用法:

for (;;;)
{
    for (;;;)
    {
        for (;;;)
        {
            if (disaster)
                goto error;
        }
    }
 }
 ...
error:
    if (disaster)

正确使用方法实在其多次嵌套下,如果要退出循环需要多次使用break,而这时使用goto语句就比较简单。

小练习:

写一个关机程序, 只要程序运行起来,电脑在1分钟内就关机,如果输入:我是猪,才取消关机

用goto语句:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");
	again:
	printf("电脑即将在300秒后关机,如果输入我是猪,则取消关机\n");
	scanf("%s", input);
	if (strcmp(input, "我是猪") == 0)
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}

	return 0;
}

用循环语句:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	char input[20] = { 0 };
		system("shutdown -s -t 60");
	
		while (1)
		{
			printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
			scanf("%s", input);
			if (strcmp(input, "我是猪") == 0)
			{
				system("shutdown -a");
				printf("关机取消\n");
				break;
			}
		}
		return 0;
}

五,循环练习题

1.计算n的阶乘

#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int ret = 1;
	for (i = 1;i <= n;i++)
	{
		ret = ret * i;
	}
	printf("%d\n", ret);

	return 0;
}

2.计算 1!+2!+3!+……+10!

#include<stdio.h>
int main()
{
	int n = 0;
	int i = 0;
	int ret = 1;
	int sum = 0;
	for (n = 1;n <= 10;n++)
	{
		ret = 1;//需要将ret初始为1,以避免下面出错
		for (i = 1;i <= n;i++)
		{
			ret = ret * i;//(1)1*1=1,(2)1*1=1,1*2=2,(3)2*1=2,2*2=4,4*3=12
		}
		sum = sum + ret;//(1)0+1=1,(2)1+2=3,(3)3+12=15
	}
	
	printf("%d\n", sum);

	return 0;
}

或者用递归

#include<stdio.h>
int main()
{
	int n = 0;
	int ret = 1;
	int sum = 0;
	for (n = 1;n <= 10;n++)
	{
		ret = ret * n;
		sum = sum + ret;
	}
	printf("%d\n", sum);

	return 0;
}

3.在有序数组中查找某个数字n(重要的算法思想)

#inlcude<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	int k = 7;
	while(left<=right)
	{
		int mid = (left + right) / 2;
    //	int mid = left + (right - left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是:%d\n", mid);
			break;
		}
	}
	if (left > right)
		printf("未找到\n");
	return 0;
}

4. 编写代码,演示多个字符从两端移动,向中间汇聚。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>//system函数的头文件
int main()
{
	char arr1[] = "welcome to c++!!!!!";
	char arr2[] = "###################";

	int left = 0;
	int right = strlen(arr1)-1;
	
	while (left<=right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);	
		Sleep(500);//window下sleep函数参数的单位是毫秒
		system("cls");//可以执行系统

		left++;
		right--;
	}
	printf("%s\n", arr2);
	

	return 0;
}

5.编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。

#include<stdio.h>
#include<string.h>
假设正确密码是"jkljkl"
int main()
{
	int i = 0;
	char password[20] = { 0 };
	for (i = 0;i < 3;i++)
	{
		printf("请输入密码:");
		scanf("%s", password);
		//判断密码的正确性
		//strcmp 是 string compare 的缩写,用来比较字符串是否相同,相同返回0,需要引入头文件#include<string.h>.
		//strcmp(表达式1,表达式2),1>2返回>0的数,1<2返回>0的数,1=2返回=0.
		//字符串比大小比的是ASCLL码值
		if (strcmp(password,"jkljkl")==0)
		{
			printf("密码正确,登陆成功\n");
			break;
		}
		else
		{
			printf("密码错误\n");
		}
	}
	if (i == 3)
	{
		printf("退出程序\n");
	}
	return 0;
}

6.猜数字游戏

猜数字游戏

随机生成1~100之间的数字

如果你猜小了,告知猜小了 

如果你猜大了,告知猜大了 

如果你猜对了,告知猜对了

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void menu()
{
	printf("********************\n");
	printf("****** 1.play ******\n");
	printf("****** 0.exit ******\n");
	printf("********************\n");
}
void game()
{
	//1.生成随机数
	//rand函数可以生成随机数
	//返回一个0~RAND_MAX(32767)的值
	int ret = rand() % 100 + 1;//%100 使得取值在0~99之间,+1->1~100
	//printf("%d\n", ret);
	
	//2.猜数字
	while (1)
	{
		int guess = 0;
		printf("请猜数字:");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了!");
			break;
		}
	}
}
int main()
{
	int input = 0;
	//生成随机数
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新选择");
			break;
		}
		
	} while (input);
	
	return 0;
}