Bootstrap

C语言--语句

C语言–语句



前言

C语言中由一个分号 ; 隔开的就是一条语句
例如int a = 0; 就是一条语句
只有一个分号 ; 也算是一个语句,我们称为空语句


一、分支语句

1.if语句

基础结构

单分支
if(表达式)
	语句1;
	
如果表达式为真,则执行语句1
双分支
if(表达式)
	语句1;
else
	语句2;
	
如果表达式为真,则执行语句1,跳过语句2
如果表达式为假,则执行语句2,跳过语句1

若要执行多条语句则需要花括号{ }

if(表达式)
{
	语句1;
	语句2;
}
else
{
	语句3;
	语句4}

多语句分支

if(表达式1)
	语句1;
else if(表达式2)
	语句2;
else
	语句3;

如果表达式1为真,则执行语句1
如果表达式1为假,表达式2为真,则执行语句2
如果表达式1为佳,表达式2为假,则执行语句3
总结为:从上往下运行代码,有一个为真则只执行为真的语句就结束整个分支语句
       若都不为真,则执行最后一个else的语句

这里会有一个新手经常容易犯的问题,就是在写代码时忘记写else,只写了if
例如:判断一个数是否大于10或者大于5(例子可能不太恰当,主要还是想说这个问题)

int a = 11;
if(a > 10)
	printf("a大于10");
if(a > 5)
	printf("a大于5");
运行结果应该是打印了 a大于10 a大于5
多了一个a大于5,结果是错误的

正确的代码应该为
int a = 11;
if(a > 10)
	printf("a大于10");
else if(a > 5)
	printf("a大于5");
当a>10时,表达式1成立,那么只会执行第一个语句printf("a大于10");
整个分支语句就结束了,即使a>5也不会执行printf("a大于5");

匹配规则

记住这句话:else只与离它最近的if匹配,除非由花括号{ }

int a = 11;
if(a>10)
	printf("1");
if(a<10)
	printf("2"):
else
	printf("3");
打印结果为1 3
此时这个else和它上面一个if(a<10)相匹配

int a = 11;
if(a>10)
{
	printf("1");
	if(a<10)
		printf("2");
}
else
	printf("3");
打印结果为 1
此时的elseif(a>10)相匹配

2.switch语句

switch 是整型表达式,只能用整型int定义,允许套娃使用
case 是整型常量表达式,正确:case 1,错误:case 1.0
break 结束switch结构的运行,无break会走完整个switch内的语句
default 表达的值与所有的case标签的值都不匹配时使用

switch语句中的default子句可以放在任意位置

基础结构

int day = 0;
switch是整型表达式,所以这里的day用int定义

scanf("%d",&day);
switch(day)
{
	case 1printf("星期一\n");
		break;
	case 2printf("星期二");
		break;
	case 3printf("星期三");
		break;
	case 4printf("星期四");
		break;
	case 5printf("星期五");
		break;
	case 6printf("星期六");
		break;
	case 7printf("星期日");
		break;
	default:
		printf("输入错误");
		break;
}
int day = 0;
scanf("%d",&day);
switch(day)
{
输入1,没有break,会一句一句向下执行,直到break出现或者switch结束
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日")
		break;
	case 6:
	case 7:
		printf("休息日")
		break;
	default;
		printf("输入错误");
		break
}

二、循环语句

break 会跳出循环
continue 会跳到循环的开头

1.while语句

基础结构

while(表达式)
{
	语句1;
}
若表达式结果为真,则重复执行语句1

break直接跳出while语句

while(1)
{
	printf("hhhh");
	break;
}
循环判断永远为真,只能用break跳出循环
打印结果为一个 hhhh

continue回到while语句的开头

int n = 0;
while(n < 5)
{
	printf("%d ",n);
	n++;
	continue;
	break;
}
打印结果为0 1 2 3 4
continue会回到while语句的开头,break语句无法执行到,n == 5时为假,结束循环

getchar与while的运用

用于处理scanf中无法接受的空格和回车
getchar每次从输入中获取单个字符,一个字符一个字符的读取

char ch;
char s[100];
int i = 0;
while(ch = getchar()) != '\n')
{
	s[i++] = ch;
}
当输入为回车时会结束循环

一个输入密码的程序

int main()
{
	int a;
	char password[20];
	printf("请输入密码:");
	scanf("%s", password);
scanf不会接收空格和回车,当输入回车确定后,回车会被下面的a = getchar()接收
	printf("请确认Y/N");
	a = getchar();
	if (a == 'Y')
		printf("确认成功");
	else
		printf("确认失败");
	return 0;
无法按预想的逻辑运行,本质是因为输入密码后按下回车后,回车键被getchar接收,ASCll转义为10,故结果为确认失败
改进把回车键让另一个getchar接受,不影响到下一个getchar()
}
int main()
{
	int a = 0;
	int passage[20];
	printf("请输入密码");
	scanf("%s",passage);
	getchar();
回车键不会被a = getchar()接受,但如果输入密码时带有空格,空格会被getchar()接受,引发同样的问题,回车键被a = getchar()接收
	printf("请确认y/n");
	a = getchar();
	if(a == y)
		printf("确认成功");
	else
		printf("确认失败");
	return 0;
}
原因:输入密码时有同一个输入缓冲区,输入密码按下回车时例如123456\n,scanf只会识别123456,\n则会被getchar接受
空格也不会被scanf接受,会被getchar()接受
改进whilegetchar()结合
int main()
{
	int a = 0;
	int passage[20];
	printf("请输入密码")
	scanf("%s",passage);
	getchar();
	while(getchar() != '\n')getchar()不等于 \n即回车键的时候继续执行
	{}
	printf("请确认Y/N");
	a = getcahr()
	if(a == 'y');
		printf("确认成功");
	else
		printf("确认失败");
	return 0;
}

2.do while语句

记住 不管条件是否成立,循环至少执行一次!!!

基础结构

do
{
	语句1;
}while(表达式)
当表达式结果为真则进入循环

3.for语句

表达式1:初始化部分
表达式2:条件判断部分
表达式3:结果调整部分

基础结构

for(表达式1;表达式2;表达式3)
{
	语句1;
}

打印从1到10

int main()
{
int i = 0;
for(i=1;i<=10;i++)
{
printf("%d ",i)
}
return 0;
}
初始化部分为第一次进入for循环的值,会通过条件判断部分,但第一次进入不会执行条件调整部分,而是第二次才会执行条件调整部分
判断完调整 调整后再判断再进去

for语句的初始化、判断、调整都可以省略

全省略

int main()
{
	int i = 0;
	for(;;)
	{
		printf("1");
	}
}

判断被省略,则判断条件恒为真

int main()
{
	int i = 0;
	for(i = 0;;i++)
	{
		printf("1\n");
	}
}

在这里插入图片描述

三、练习题

1.计算n的阶乘

int main()
{
	int n;
	int i;
	int sum = 1;
	scanf("%d",&n);
	for(i = 1;i <=n;i++)
	{
		sum = sum * i;
	}
	printf("sum = %d",sum);
	return 0;
}

2.计算1到n的阶乘

int main()
{
	int n = 0;
	int i = 0;
	int j = 0;
	int sum1 = 1;
	int sum2 = 0;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		sum1 = sum1 * i;
		sum2 = sum1 + sum2;
	}
	printf("%d", sum2);
	return 0;
}

3.在一个有序的数组中查找到具体的数字

二分查找:效率高,要求数组排列有序

int main()
{
	int arr[] = { 1,5,8,9,52,70,100 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int n = 0;
	scanf("%d", &n);
	int left = 0;
	int right = sz - 1;
	int mid = 0;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (n < arr[mid])
		{
			right = mid - 1;
		}
		if (n > arr[mid])
		{
			left = mid + 1;
		}
		if (n == arr[mid])
		{
			printf("找到了,下标是%d\n", mid);
			break;
		}
	}
	if(n != arr[mid])
		printf("找不到\n");
	return 0;
}

4.演示多个字符从两端移动,向中间汇聚

#include<stdio.h>
#include<stdlib.h>
int main()
{
	char arr1[] = "Hello World";
	char arr2[] = "###########";
	int left = 0;
	int right = strlen(arr1) - 1;
	while (left <= right)
	{
		arr1[left] = arr2[left];
		arr1[right] = arr2[right];
		printf("%s\n", arr1);
		left++;
		right--;
	}
	return 0;
}

在这里插入图片描述

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

int main()
{
	char passage[20] = { 0 };
	int i = 0;
	for (i = 3; i > 0; i--)
	{
		printf("请输入登录密码:");
		scanf("%s", passage);
		if (!strcmp(passage, "asdf123"))
		{
			printf("登录成功\n");
			break;
		}
		else
			printf("密码输入错误,还剩%d次机会\n",i-1);
	}
	return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/66568175690d43a5a895f38e3c6187cc.png

在这里插入图片描述

6.将3个数从大到小输出

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int tmp = 0;
	scanf("%d%d%d", &a, &b, &c);
	if (a < b)
	{
		tmp = a;
		a = b;
		b = tmp;
	}
	if (a < c)
	{
		tmp = a;
		a = c;
		c = tmp;
	}

7.给定两个数,求这两个数的最大公约数

使用的是辗转相除法
m n
m>n
r = m % n
m = n
n = r
if(m % n == 0)
n是最大公约数

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n = 0;
	int m = 0;
	int r = 0;
	scanf("%d%d", &m, &n);
	if (m > n)
	{
		while (m%n)
		{
			r = m % n;
			m = n;
			n = r;
		}
		printf("最小公约数为:%d\n", n);
	}
	else
	{
		while (n % m)
		{
			r = n % m;
			n = m;
			m = r;
		}
		printf("最小公约数为:%d\n", m);
	}
	return 0;
}

8.打印1000年到2000年之间的闰年

1.能被4整除,并且不被100整除
2.能被400整除

#include<stdio.h>
int main()
{
	int i = 0;
	int count = 0;
	for (i = 1000; i <= 2000; i++)
	{
		if (i % 4 == 0 && i % 100 != 0)
		{
			printf("%d ",i);
			count++;
		}
		else if (i % 400 == 0)
		{
			printf("%d ",i);
			count++;
		}
	}
	printf("\n");
	printf("%d", count);
	return 0;
}

9.打印100到200之间的素数

试除法
a 和 b中至少有一个数字 ≤ 开平方 i

int main()
{
	int i;
	int z;
	int count = 0;
	for(i = 101;i < 200;i += 2)
	{
		for(z = 2;z <= sqrt(i);z++)
		{
			if(i % z ==0)
				break;
		}
		if(z > sqrt(i))
		{
			printf("%d ",i)
			count++;
		}
	}
	printf("count = %d",count);
	return 0;
}

10.1到100的所有整数中出现多少个数字9

#include<stdio.h>
int main()
{
	int i = 0;
	int count = 0;
	for (i = 1; i <= 100; i++)
	{
		if (i % 10 == 9)
		{
			count++;
		}
		else if (i / 10 == 9)
		{
			count++;
		}
	}
	printf("count = %d\n", count);
	return 0;
}

11.求10个整数中最大值

易错点:要把arr[0]做为比较的第一个元素

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int max = 0; 
当数组内全是负数的时候,不成立,因为改进int max = arr[0]; 先假设最大为arr[0]
	int i;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		if (max < arr[i])
			max = arr[i];
	}
	printf("最大值是 %d", max);
	return 0;
}

12.猜数字游戏

#include<stdio.h>
#include<time.h>
void game()
{
	int num = 0;
	int m = 0;
	num = rand() % 100;
	while (m != num)
	{
		scanf("%d", &m);
		if (m > num)
			printf("猜大了\n");
		else if(m<num)
			printf("猜小了\n");
	}
	printf("猜对了,是%d\n", m);
}

void menu()
{
	printf("########################\n");
	printf("#####1.play  0.exit#####\n");
	printf("########################\n");
}

int main()
{
	int input = 0;
	do
	{
		设置时间戳
		srand((unsigned)time(NULL));
		menu();
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			break;
		case 1:
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}
;