目录
C语句可分为以下五类:
1. 表达式语句
2. 函数调用语句
3. 控制语句
4. 复合语句
5. 空语句
这里主要讲控制语句
控制语句
用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:
1. 条件判断语句也叫分支语句:
if语句、switch语句
2. 循环执行语句:
do while语句、while语句、for语句
3. 转向语句:
break语句、goto语句、continue语句、return语句
第一类 分支语句(选择结构)
if语句
单分支:
if(表达式)
语句;
多分支:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else 语句3;
注意:
if语句只能控制一条语句
除非加一个{},一对{}构成的成分叫代码块
//代码1
if (condition)
{
return x;
}
return y;
代码一相当于省略了else,与代码二实际意义相同
//代码2
if(condition)
{
return x;
}
else
{
return y;
}
switch语句
用于多分支的情况
switch(整型表达式)
{
case 整形常量表达式:
语句;
}
具体使用
#include <stdio.h>
int main()
{
int day = 0;
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;
}
break语句
实际效果是把语句列表划分为不同的分支部分
若有重复输出,比如输入1-5,输出的是“weekday”、输入6-7,输出“weekend”
#include <stdio.h>
//switch代码演示
int main()
{
int day = 0;
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday\n");
break;
case 6:
case 7:
printf("weekend\n");
break;
}
return 0;
}
default:
写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行
所以,每个switch语句中只能出现一条default子句
但是它可以出现在语句列表的任何位置,效果相同
练习
#include <stdio.h>
int main()
{
int day = 0;
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday\n");
break;
case 6:
case 7:
printf("weekend\n");
break;
}
return 0;
}
第二类 循环语句
while循环
while(表达式)
循环语句;
while循环中的continue
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;//当i=5时,跳过本次循环后面的代码,直接去第5行判断部分,看是否进行下一次循环
printf("%d ", i);
i = i+1;
}
return 0;
}
输出1 2 3 4
只要遇到continue,跳过一次循环
若把i++放置if前
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
i = i+1;
if(i == 5)
continue;
printf("%d ", i);
}
return 0;
}
输出2 3 4 6 7 8 9 10 11
while循环中的break
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
break;//当i=5时,跳出循环
printf("%d ", i);
i = i+1;
}
return 0;
}
输出 1 2 3 4
只要遇到break,中止循环
getchar
getchar 是一个C语言的标准库函数,用于从标准输入(通常是键盘)获取一个字符。它会等待用户输入一个字符,并返回该字符的ASCII码值
getchar()函数不接受任何参数,并返回一个int类型的值,表示读取的字符。如果读取成功,返回字符的ASCII码值;如果到达文件末尾(EOF),则返回特殊值EOF(通常为-1)
需要注意的是,getchar()函数每次只能读取一个字符。如果你需要读取多个字符或一行文本,可以使用fgets()函数或其他更适合的输入函数。
举例:
#include <stdio.h>
int main()
{
int c;
c = getchar();//输入一个字符
putchar(c);//输出输入的字符
return 0;
}
在示例中,我们首先调用getchar()函数获取用户输入的字符,将其保存在变量c中。然后,我们使用putchar()函数将读取到的字符打印出来
使用getchar完成多组输入
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)//判断是否读到正确字符
putchar(ch);
return 0;
}
windows系统里按ctrl+Z再按回车,即可使得getchar返回EOF,使其停止
只打印数字字符,跳过其他字符
#include <stdio.h>
int main()
{
char ch = '\0';
while ((ch = getchar()) != EOF)
{
if (ch < ‘0’ || ch > ‘9’)
continue;
putchar(ch);
}
return 0;
}
此代码只打印0~9的数字符,其他的都不打印
这里的代码适当的修改是可以用来清理缓冲区的
数组名本来就是地址,使用scanf时可以不用&
#include <stdio.h>
int main()
{
char password[20];
printf("请输入密码:");
scanf("%s",password);
printf("请确认(Y/N)");
int ch=getchar();
if('Y==ch')
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
错误:
还未确认便输出确认失败
原因:
1、scanf和getchar不是在键盘上读取数据,而是在缓冲区进行读取
2、运行时,scanf函数发现缓冲区没有数据,就等待用户输入,当你输入123qqq\n(回车),scanf拿走缓冲区的123qqq,此时还剩一个\n
3、此时getchar去获取数据,发现缓冲区有数据\n,便读取了,ch里是\n,不等于Y,所以直接输出确认失败
方案:
让第三步里getchar读取数据的时候,缓冲区为空,清空缓冲区,拿走\n
#include <stdio.h>
int main()
{
char password[20];
printf("请输入密码:");
scanf("%s", password);
getchar();//处理\n
printf("请确认(Y/N):");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
若换一种情况则还会出错:
需考虑到scanf函数在读取字符串时,遇到空格就不再读取
此时缓冲区为:123 qqq\n
scanf拿走了:123
getchar拿走一个字符就返回
第二个getchar读取到别的字符,判断后就打印确认失败了
解决方法:
写一个关于getchar的循环,使每次只能拿走一个字符的getchar多次拿走剩余字符,直到缓冲区为空
#include <stdio.h>
int main()
{
char password[20];
printf("请输入密码:");
scanf("%s", password);//scanf函数读取字符时,遇到空格不再读取
int ch = 0;
while ((ch = getchar()) != '\n')
{//此处大括号可以省略
;//空语句,为了保证形式上不出错误
}
printf("请确认(Y/N):");
ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
for循环
for(循环; 判断; 调整)
循环语句;
在for循环中
如果遇到continue,会跳过后面的代码,直接跳去循环的调整部分,和while循环中的continue有区别
如果遇到break,则立即终止循环,和while循环中的break用法相同
建议:
不可在for 循环体内修改循环变量,防止 for 循环失去控制
一些for循环的变种
部分省略
#include <stdio.h>
int main()
{
for(;;) //for循环中的初始化部分,判断部分,调整部分是可以省略的
{
printf("hehe\n");
}
return 0;
}
若省略初始化部分,则主循环内的第一次次循环走完后,再进入次循环,次循环的变量仍为上次的值,并未初始化。
若省略判断部分,很可能导致循环不终止
多个变量控制循环
#include <stdio.h>
int x, y;
for (x = 0, y = 0; x<2 && y<5; ++x, y++)
{
printf("hehe\n");
}
return 0;
}
注意
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++)
k++;
return 0;
}
此代码判断部分使用了赋值,即将k赋值为0,为假,则不进入循环
do-while循环
do
{
循环语句;
}
while(表达式);
循环至少执行一次
break 和continue 与在while循环中一模一样
break终止循环,continue跳过本次循环后面的代码,重新开始下一次循环
练习
计算n的阶乘
#include<stdio.h>
int main()
{
int n = 0,i,s=1;
//输入n
scanf("%d", &n);
//循环产生1~n的数字
for (i = 1; i <= n; i++)
{
s = s * i;
}
printf("%d", s);
return 0;
}
计算1!+2!+3!+...+10!
//方法一
#include<stdio.h>
int main()
{
int n, i, s = 1,k=0;
for (n = 1; n <= 10;n++)
{
s = 1;//若无这一步,则s不能初始化,每次求新的阶乘的时候,都会累积上一次的阶乘
for (i = 1; i <= n; i++)
{
s = s * i;
}
k = k + s;
}
printf("%d", k);
return 0;
}
//方法二
#include<stdio.h>
int main()
{
int n, s, k;
for (n = 1; n <= 10; n++)
{
s *= n;
k += s;
}
return 0;
}
在一个有序数组中查找具体的某个数字n
//方法一
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }, k , i;
int f = 0;
scanf("%d", &k);
for (i = 0; i <= 10;i++)//遍历
{
if(arr[i]==k)
{
printf("找到了,下标是%d\n", i);
f = 1;
break;
}
}
if (f == 0)
printf("没找到\n");
return 0;
}
猜数字游戏实现
//猜数字游戏实现
//电脑随机生成一个1到100之间的数字
// 用户猜数字
// 如果猜小了,就输出猜小了
// 如果猜大了,就输出猜大了
// 如果猜对了,就输出恭喜你,游戏结束
void menu()
{
printf("******************************************************\n");
printf("****************** 1、play *********************\n");
printf("****************** 0、exit *********************\n");
printf("******************************************************\n");
}
void game()
{
//1、生成1到100的随机数
//rand函数生成的伪随机数,范围是0到RAND_MAX(32767)
//生成随机数之前,要使用srand函数设置随机数的生成器
//time函数可以返回一个时间戳,后面是指针,此处返回一个空指针
//时间戳1970年1月1日至当前时间的总秒数
// srand((unsigned int)time(NULL));//srand和rand函数需要头文件#include<stdlib.h>
//time函数需要头文件#include<time.h>
//此处若用srand,则每一次生成随机数时,若操作过快,则数字会出现相近或者相同的情况
int ret = rand() % 100+1;//任何数字取余100得到的值都为0到99
printf("%d\n", ret);
//2、猜数字
while (1)
{
int guess;
printf("请猜数字:\n");
scanf("%d", &guess);
if (guess < ret)
printf("猜小了");
else if (guess > ret)
printf("猜大了");
else
{
printf("恭喜你,猜对了");
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//放在此处,会使得时间戳永远为开始的那一刻,不会出现因操作过快导致的问题
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始猜数字游戏\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);//input不为0,则判断为真,返回循环
return 0;
}
也可以不用goto语句,使用循环同样可以达到相同的效果
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");//开始倒计时关机
while (1)
{
printf("你的电脑将在一分钟后关机,如果输入“我是猪”,则取消关机");
scanf("%s", &input);
if (strcmp(input, "我是猪") == 0)
{
system("shutdown -a");//取消关机
printf("你很配合,已经取消关机\n");
break;
}
}
return 0;
}