【C语言】Section2_分支语句if-else,switch ; 循环语句while,for,do while ;goto语句

【补】使C语言结构化的程序设计语言,分为:顺序结构、选择结构、循环结构

目录

一、分支语句

1、if-else 分支语句

2、switch 分支语句-用于存在很多分支时

二、循环语句

1、while循环

2、for循环 

3、do while循环

[练习题]

【补】goto语句



#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

一、分支语句

1、if-else 分支语句

(1)【补】代码风格——好的代码风格可以消除歧义,并且利于读者理解——书籍《高质量 C\C++编程》

注意格式的书写,善用大括号的规范书写格式,形成好的代码风格;

#include <stdio.h>

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (b == 2)
		{
			printf("呵呵\n");
		}
		else
		{
			printf("呜呜\n");
		}
	}


	return 0;
}

(2)练习

①判断一个数是否为奇数

int main()
{
	int input = 0;
		scanf("%d", &input);
	if (1 == input % 2)
	{
		printf("是奇数\n");
	}
	else
	{
		printf("不是奇数\n");
	}

	return 0;
}

②输出1-100之间的奇数

【补】for循环的条件语句用分号; for( exp1 ; exp2 ; exp3 )

方法一:

int main()
{
	int i = 0;
	for (i=1 ; i <= 100 ; i++ )  //for循环的条件语句用分号; for( exp1 ; exp2 ; exp3 )
	{
		if(1==i%2)
		{
			printf("%d ", i);
		}
	}

	return 0;
}

方法二   不用 if 判断 ,直接+=2, 奇数循环

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

	return 0;
}

2、switch 分支语句-用于存在很多分支时

1、switch “开关”——必须是整型/整型常量表达式,字符也可以,因为字符存储是用的阿斯格码值;

2、格式:

switch(整型表达式)

{

   语句项

}

语句项,就是一些case语句,比如:

case  整型常量表达式:

          语句

例1输入的数值对应打印出星期几,1-星期一,2-星期二,3-星期三……

break 结束进程,后面不再继续输入,没有break ,case会一直运行!

case 决定入口,break决定出口

#include <stdio.h>
int main()
{
	int day = 0;
	scanf_s("%d\n",&day);
	switch (day)
	{
	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;
	}
	return 0;
}

例2 输入1 2 3 4 5 打印工作日; 输入6 7打印休息日;

输入其他数字打印“输入错误”——default

#include <stdio.h>
int main()
{
	int day = 0;
	scanf_s("%d\n",&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");
	}
	return 0;
}

 练习题:求m=?  n=?

【补】

switch可以嵌套使用;

没有break,case会一直运行下去

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

二、循环语句

1、while循环

(1)在while循环中,break用于永久终止循环,

(2)while执行流程:

(3)while中的continue

* continue用于跳过本次循环continue后面的代码,直接去判断部分看能否进行下一步循环

//结果= 1234死循环
//分析 continue的作用是跳过当前的后续操作,直接进入下一次判断,意思是,当i==5进入if语句,直接跳到下一次判断i<=10能否进入whle循环,此时因为i没有经过printf,也没有经过 i++,因此i还是=5,打印的只是1234,后面死循环;

//结果= 1234死循环
//分析 continue的作用是跳过当前的后续操作,直接进入下一次判断,意思是,当i==5进入if语句,直接跳到下一次判断i<=10能否进入whle循环,此时因为i没有经过printf,也没有经过 i++,因此i还是=5,打印的只是1234,后面死循环;
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if(i==5)
		{
			continue;
		}
		printf("%d ",i);
		i++;
	}

	return 0;
}

(2)【补】

getchar / putchar——从键盘(标准输入)读取 / 输出一个字符;

EOF= end of file 文件结束;

字符是以阿斯格码值的形式存储,因此char可以用int;

getchar 与 键盘之间有一个 缓冲区,getchar不会忽略缓冲区中的任何字符,包括 \n

int main()
{
	int ch = 0;
	while (ch = getchar() != EOF)
	{
		putchar(ch);
	}
	return 0;
}

(3)

scanf()其实在生活中不常用,因为它只能读一个字符

gets()可以读一整行

(4)password是数组 arr[ ],数组的数组名本来就是地址,因此sacnf 不用 取地址& pasaword

① 如果输入的密码只是数字,比如,12345 

上诉情况的缓冲区里有'\n',此时应该清理缓冲区,用一个gerchar把'\n'拿走

 ①把'\n'拿走了

#include <stdio.h>
//① 如果输入的密码只是数字,比如,12345 
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s",password);
    printf("请确认密码(Y/N):>");

	//上诉情况的缓冲区里有'\n',此时应该清理缓冲区,用一个gerchar把'\n'拿走
	
	getchar();     // ①把'\n'拿走了
	
	int ch = getchar();
	    if (ch == 'Y')
	    {
			printf("确认成功");
	    }
		else
		{
			printf("确认失败");
		}

	return 0;
}

#include <stdio.h>
//②如果输入的是字符串,比如,12345 abc,有空格——【不是很懂】
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	printf("请确认密码(Y/N):>");


	//假设此时输入的是:12345 abc
	//应该清理缓冲区的多个字符
	int tmp = 0;
	    while (tmp = getchar() != '\n');
		{
			;    //空格表示扔掉
		}

	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功");
	}
	else
	{
		printf("确认失败");
	}

	return 0;
}

【补】只打印数字字符,跳过其他字符  -ASCII表

2、for循环 

(1)格式

for(exp1 ; exp2 ; exp3)
{

循环语句;

}

exp1 初始化 

exp2 判断

exp3 调整

stmt 执行

(3)for循环的执行流程:

【举例】 打印1-10

int main()
{
  int i = 0;

  for (i = 1; i <= 10 ; i++)
    {
     printf("%d ", i);
    }

return 0;
}

建议左闭右开 for (i=0 ; ,i<10 ;i++}

一旦判断部分省略,会死循环

【问】打印几个 1 ?

结果:3*3= 9

 int main()
{
	 int i = 0;
	 int j = 0;
	 for (i = 0; i < 3; i++)
	 {
		 for (j = 0; j < 3; j++)
		 {
			 printf("1 ");
		 }
	 }
 return 0;
 }

【问】如果省去初始化,打印几个1?
//结果= 3个 

//分析: 最初i=0,符合i<3进入第一个for循环,然后j=0,符合j<3进入第二个for循环,直到j=3打印了3个1,但是因为生气了初始化,当i++时,j>3不能进入第二个for循环,不能形成 3*3

 int main()
 {
	 int i = 0;
	 int j = 0;
	 for ( ; i < 3; i++)
	 {
		 for ( ; j < 3; j++)
		 {
			 printf("1 ");
		 }
	 }
	 return 0;
 }

【问】循环几次?

结果:  k=0是赋值而非判断,k=0为假,不能循环,循环次0次;


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

3、do while循环

(1)do while的结构

do
{

 循环语句;

}

while(表达式);

(2)do while 先执行,后判断; while先判断,后执行

(3)do while循环的流程

【举例】打印1-10

int main()
{
	int i = 1;
	do
	{
		printf("%d ", i);
		i++;

	} while (i <= 10);

	return 0;
}

[练习题]

1、计算n的阶乘 n!

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

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

int main()
{
	int i = 0;
	int ret = 1;  //ret初识为1
	int sum = 0;
	for (i = 1; i <= 10; i++)
	{
		ret *= i;
		sum += ret;
	}
	printf("%d", sum);
	return 0;
}

3 、在有序数组中查找具体的某个数字n——二分法
 

二分查找/折半查找 - 效率高 ,  下标不会四舍五入,因为这是整型

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;  //  要查找的数字
	//在这个有序数组arr中查找k(7)的值

	int left = 0;

	int sz = sizeof(arr) / sizeof(arr[0]);  //元素个数
	int right = sz - 1;

	int mid = (left + right) / 2;  //mid是下标,arr[mid]对应数值

	while (left <= right)  //意思是数组里面有元素
	{
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else   //就是刚好 arr[mid]=k
		{
			printf("可找到,数值下标:%d", mid);
			break;
		}
	}

	if (left > right)  //意思是数组里没元素,找不到
	{
		printf("找不到");
	}
	return 0;
}

4、编写代码,演示多个字符从两端移动,向中间汇聚——意思是字符串逐渐向中间显现

比如,

打印 welcome to Beijing!!

w##############!

we############!!

wel###########g!!

...

welcome to Beijing!!

【补】strlen( )需要头文件 include <string.h>

int main()
{
	char arr1[] = "welcome to Beijing!";  //区别于 int arr[]={ 1,2,3,4,5 }
	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);
		left++;
		right--;
	}

	return 0;
}

【补】*来个动态版,加上Sleep函数,其单位是毫秒,需要引用头文件 include<windows.h>
 

#include <string.h>
#include <windows.h>

int main()
{
	char arr1[] = "welcome to beijing!";  //区别于 int arr[]={ 1,2,3,4,5 }
	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(1000);   //  睡眠打印速度1000毫秒,s一定要大写!

		left++;
		right--;
	}

	return 0;
}

【补】来个清空屏幕动态版!!!!!  加上 system("cls");

#include <stdio.h>
#include <string.h>
#include <windows.h>

int main()
{
	char arr1[] = "welcome to beijing!"; //区别于 int arr[]={ 1,2,3,4,5 }
	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(1000);   //  睡眠打印速度1000毫秒,S一定要大写!

		system("cls"); //  清空屏幕

		left++;
		right--;
	}

	printf("%s\n", arr1);

	return 0;
}

5、strcmp()函数,会根据 ASCII 编码依次比较 str1 和 str2 的每一个字符,直到出现不到的字符,或者到达字符串末尾(遇见\0

strncmp ()还可以指定字符串里用于比较的字符数

返回值:

  • 如果返回值 < 0,则表示 str1 小于 str2。
  • 如果返回值 > 0,则表示 str2 小于 str1。
  • 如果返回值 = 0,则表示 str1 等于 str2。

比较对应位置上的ASCII码值,比如abcqqqqq 与abd,  第三位c比d小,则第二个更大

5、输入密码,错误三次就退出程序

【补】比较两个字符串,不能用==,要用strcmp()函数

//输入密码,错误三次就退出程序

#include <stdio.h>
#include <string.h>   //strcmp()函数的头文件
#include <windows.h>  //system()函数的头文件
int main()
{
	int i = 1;
	//假设正确密码是字符串“1234567”

		char password[20] = { 0 };

	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf("%s", password);
		system("cls");

		if (strcmp(password, "1234567") == 0)  //比较两个字符串,不能用==,要用strcmp()函数
		{
			printf("登录成功\n");
			break;
		}
	}
	if (i == 3)
	{
		printf("三次密码均错误,退出程序");
	}

	return 0;
}

6、写一个数字游戏,自动生成一个1-100之间的随机数

猜数字游戏的实现: 
    第一步:生成随机数 - rand() - "random 随意的"
        如果不先引用srand,rand()有最大值限制,只能返回0-32767之间的数字 ,且不够随机
       那么,要先调用srand先调整rand的生成器;

       需要给srand()一个整数,但因为想要rand输出随机的数字,因此必须给srand一个变化的数
       因此给srand输入 时间 !---。实际传递的是 *时间戳:由时间转换出的数字;
    
       获取时间戳-time函数-<time.h>// 给time()传一个空值NULL
       用unsigned int,将time的返回值,强制类型转化为srand需要的类型;

       如果将time()放在game()里面,那就要每玩一次游戏就要设置一次,不合适--->整个工程,time()只需要设置一次,不然不够随机--->因此把srand((unsigned int)time(NULL));放到主函数main()里面去;
       但此时随机数过大,超出1-100的要求范围,因此 取模%100,余数均为1-99,为了使范围为1-100,则+1;


       第二步:猜数字
          会才很多次,用while语句

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <time.h>

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

void game()
{
	//生成随机数
	int ret = rand() % 100 + 1;
	//printf("%d\n", ret);

	//猜数字
	int guess = 0;

	while (1)
	{
		printf("请猜数字:>");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else (guess = ret);
		{
			printf("恭喜猜对\n");
			break;
		}
	}
}
int main()
{
	int input = 0;

	srand((unsigned int)time(NULL));

	do
	{
		menu();  //打印菜单,menu函数不在库函数里面,需要上方viod 说明
		printf("请选择:>");

		scanf("%d", &input);

		switch (input)
		{
		case 1:
			game();
			//game();  //game 函数也是库函数里面没有的
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请重新选择\n");
			break;
		}
	} while (input);

	return 0;
}

【补】goto语句

 不可滥用,但是用于跳出多重嵌套语句很有效;

goto语句不可跨函数,只能在本函数内跳出;

比如://处理错误情况

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

error:
      if(disaster)  //处理错误情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值