分支和循环
C语言是结构化程序设计语言(顺序结构、选择结构、循环结构)
1 操作符
1.1 关系操作符
关系表达式中使用的运算符{ >,<,>=,<=,==,!=}
- 相等==和赋值=不一样,防止出现错误→把变量写在等号的右边
if (3==x) ... //正确
if (3=x)... //报错
- 多个关系运算符不宜连用
i<j<k //即(i<j)<k
1.2 逻辑操作符
1.2.1 !取反
若flag为假,就执行语句1(但flag真假未知)
if(!flag) //flag为真,即!flag为假,则不执行;
{
语句1 //!flag为真,则flag为假,执行语句1
}
1.2.2 &&与——双目操作符
两边都真,整个表达式才为真
1.2.3 || 或——双目操作符
两边都假,才为假
1.2.4 短路
逻辑运算符先对左侧表达式求值。
若左边满足条件就不对右边求值的情况——短路
根据左操作数结果就知道整个表达式结果,不对右操作数计算的运算——短路求值
2 分支结构(选择结构)
2.1 if语句
//if语句
if (表达式)
语句 //表达式为真则执行
//if...else语句
if (表达式)
语句1
else
语句2
- if、else默认只控制一条语句,要控制多条语句时,用{}括起来
- 嵌套if
else if不满足前面情况
if (a<18)
printf("少年\n");
else if(a<=30)
printf("青年\n"); //18≤a≤30
else if(a<=50)
printf("中年\n"); //30<a≤50
else if(a<=70)
printf("老年\n"); //50<a≤70
else
printf("老寿星\n"); //a>70
- 悬空else——else和最接近的if匹配
2.2 switch语句
2.2.1 基本结构
- 判断条件有多个结果
switch (整形表达式){ //字符类型的ASCⅡ码值也是整型,故也可以
case value1:
statement
case value2:
statement
default:
statement
}
- case后的值必须为整形常量表达式
- case和后面的数字间必须有空格
- 每个case语句中代码执行完成后,加上break才可跳出switch语句,否则继续往下执行其他case
int n=0
switch (n%3) //n%3为整型
{
case 0: //为整型常量,不可写为n!!
printf("整除余数为0\n");
break; //跳出循环
case 1:
printf("余数为1\n");
break;
case 2:
printf("余数为2\n");
break;
}
2.2.2 switch中的break
- 起分支效果
不加break则符合情况的case后,所有case的命令都执行。(如上面那个程序,输入7,没有break则会输出“余数是1”和“余数是2” - 不是每个 case 语句都得有break
2.2.3 switch中的default
case 语句和 default 语句是没有顺序要求
3 循环结构
3.1 while循环
while (表达式) //满足则一直循环
循环体
3.2 for循环
for (循环变量初始化 ; 循环结束条件的判断 ; 循环变量的调整)
循环体;
3.3 do-while循环
循环体至少执行一次
do{
循环体;
}while(表达式); //表达式结果为假(0)则结束循环
3.4 break语句
- 跳出整个循环
3.5 continue语句
- 跳出本次循环
- 循环的调整最好放在continue前面,不然可能会造成死循环【最好用for语句】
int i=1; while(i<=10) { if(i==5) continue; //i等于5后,执行continue printf("%d",i); i=i+1; //i==5时被跳过,i一直为5,死循环 }
3.6 循环的嵌套
练习:找出100~200之间的素数,并打印在屏幕上。(素数只能被1和本身整除的数字)
#include <stdio.h>
#include <math.h> //sqrt()的头文件
int main()
{
int i = 0;
//循环产⽣100~200的数字
for(i=101;i<200;i+=2) //因为100以上的偶数不会是质数,这样速度更快
{
//判断i是否为素数——假设法
//循环产⽣2~i-1之间的数字j
int j = 0;
int flag = 1;//假设i是素数
for(j=2;j<=sqrt(i);j++) //只需要看i-1的一半,因为i=a+b中a、b一定有一个<=√i
{
if(i%j==0)
{
flag=0; //i能被j整除,则不是素数
break; //一个j能被整除已经说明问题,i不是素数,去测下一个i+
}
}
if(flag==1) //循环之后flag仍然等于0
printf("%d",i);
}
return 0;
}
3.7 goto语句
同一个函数内,跳到设置好的标号处
{
printf("123");
goto next:
printf("asd"); //被跳过
next:
printf("跳过了asd");
}
4 猜字谜游戏设计
4.1 随机数生成
4.1.1 rand函数——生成伪随机数
头文件#include <stdlib.h>
printf("%d\n",rand());
每次运行程序产生的随机数序列是一样的,因为rand函数生成随机数的默认种子是1
要生成不同的随机数,就要让种子是变化的
4.1.2 srand函数——初始化随机数的生成器
void srand (unsigned int seed); //seed是种子
调用rand函数前先调用srand函数
srand函数在程序中调用一次就够了
给srand的种子随机,则rand可以生成随机数
4.1.3 time函数——获得程序运行时间
#include <time.h>
time_t time (time_t*timer);
- 将程序运行时间作为种子
- time函数返回的这个时间差叫时间戳,即1970年1月1日0时0分0秒到现在程序运行时间之间的差值
- 返回的类型是time_t类型,time_t本质就是int/long long类型
- 参数timer如果是空指针:只返回这个时间的差值
time(NULL);//调⽤time函数返回时间戳,这⾥没有接收返回值
- 参数timer如果是非空指针:函数也会将返回的差值放在timer指向的内存中带回去
4.1.4 随机数范围设置
a+rand()%(b-a+1); //范围在a~b
4.2 猜数字游戏实现
4.2.1 无限次猜数直到猜对
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game()
{
int r = rand()%100+1; //生成随机数
int guess=0;
while(1) //死循环,一直猜到正确然后跳出循环
{
printf("请猜数字>:");
scanf("%d", &guess);
if(guess < r)
{
printf("猜⼩了\n");
}
else if(guess > r)
{
printf("猜⼤了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
void menu()
{
printf("**************************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("**************************\n");
}
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("选择错误,重新选择\n");
break;
}
}while(input); //为假则结束
return 0;
}
4.2.2 次数限制
//只用修改game部分
void game()
{
int r=rand()%100+1;
int guess=0;
int count=5; //5次机会
while (count) //count变成假(0)则结束循环
{
printf("|n你还有%d次机会\n",count);
count--; //循环一次count减少一次,机会越来越少
原game的while部分
}
if (count==0)
{
printf("你失败了,正确值是:%d\n",r);
}
}
5 多组输入
while(scanf("%d",&a)==1) //要停止多组输入则按CTRL+z(vs内多按几次)
或
while(scanf("%d",&a)!=EOF)