目录
练习1.3:判断一个数是否为奇数(c语言里面1为真,0为假)
5.1 do while循环(先执行一次,在判断要不要循环)
练习5:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。
练习7:写一个关机程序,只要程序运行起来,电脑就在1分钟内关机,如果输入:一键三连,就取消关机。
C语言是(结构化的)程序设计语言:
其中,控制语句(控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。)
1.条件判断语句也叫分支语句: if语句、switch语句;
⒉.循环执行语句: do while语句、while语句、for语句;
3.转向语句: break语句、goto语句、continue语句、return语句。
1.1 if语句
#include <stdio.h>
int main()
{
if(表达式)
{
语句列表1;
}
else //不是if,就是else
{
语句列表2;
}
return 0;
}
if实现多分支
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("青少年\n");
printf("好好学习\n");
}
else if (age >= 18 && age < 30) //else if跟if一样判断
{
printf("青年\n");
}
else if (age >= 30 && age < 50)
{
printf("中年\n");
}
else if (age >= 50 && age < 80)
{
printf("中老年\n");
}
else if (age >= 80 && age < 100)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
return 0;
}
这里推荐一本书:《高质量的C-C++编程》,有助于形成良好的代码风格
练习1.2:以下代码输出结果是什么?
int main()
{
int a=0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
解释:没有输出,因为else是跟最近的if语句匹配 ,a==1判断为假,下面判断没进去
练习1.3:判断一个数是否为奇数(c语言里面1为真,0为假)
int main()
{
int n = 0;
scanf("%d", &n);
//if (n % 2 != 0) 一种写法
//if (n % 2 == 1) 一种写法
//if(1 == n%2) 一种写法
if(n%2) //n%2的结果是1,c语言里面1为真,0为假
{
printf("奇数\n");
}
return 0;
}
练习1.4:打印1~100之间的奇数
int main()
{ //第一种写法,更高效
int i = 1;
while (i <= 100)
{
printf("%d ", i);
i=i+2;
}
//第二种写法
//while (i <= 100)
//{
// //对i进行判断,是奇数才打印
// if(i%2 == 1)
// printf("%d ", i);
// i++;
//}
return 0;
}
2.1:switch语句
switch (整形表达式)
{
语句项;(case语句)
}
例如:
case (整型常量表达式):
语句;
(我想输入1,应该是打印星期一,但实际输出什么?)
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期1\n");
case 2:
printf("星期2\n");
case 3:
printf("星期3\n");
case 4:
printf("星期4\n");
case 5:
printf("星期5\n");
case 6:
printf("星期6\n");
case 7:
printf("星期天\n");
return 0;
}
输入1,却打印了星期一到星期日,跟我们想要的结果不一致,是因为我们缺少了break
break语句实际是把语句划分为不同的分支部分,遇到break当前循环停止
2.2 default子句
如果表达的值与所有的case标签的值都不匹配怎么办?结构就是所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误
如果你并不想忽略不匹配所有标签的表达式的值时该怎么办?你可以在语句列表中增加一条default子句,把下面的标签
default:
写在任何一个case标签可以出现的位置。
int main()
{
int day = 0;
scanf("%d", &day);//3
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;
}
注:switch允许嵌套使用
3.1 循环语句while
当条件满足的情况下,if语句后的语句执行,否则不执行。但是这个语句只会执行一次。
while语句便可以实现循环
while(表达式)
{
循环语句; //再返回表达式判断
}
int main()
{
int i = 1;
while (i<=10)
{
if (5 == i)
continue;
printf("%d ", i);
i++;
}
return 0;
}
代码死循环,continue意思是跳过此次循环continue后面的代码
在while循环中,break是这一次循环完后直接结束循环,永久终止循环
getchar的用法
char a = getchar(); X错误的写法
//getchar读取一个字符,但是却不能放到char类型数据里面,是因为getchar读取失败后会返回EOF
//EOF就是-1,char类型存不下-1
int a = getchar(); √正确的写法
//如果读取到一个字符,此时返回的便是该字符的ASICC码值
写一个代码,输入密码后确认密码
int main()
{
char ch = 0;
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);
printf("请确认密码(Y/N):>");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
结果却是这样,连YES输入都没有输入就确认失败
解释:scanf和getchar是从缓冲区拿数据,等待键盘输入数据,键盘上输入123456回车(回车被解析为\n),scanf拿走了\n之前的数据(123456),此时缓冲区还有\n这个数据,getchar再去缓冲区拿,发现还有一个\n,拿走判断,确认失败
这时我们就要清理缓冲区
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);
int tmp = 0;
while ((tmp = getchar()) != '\n')//利用getchar把缓冲区字符读取掉不使用,到\n前全清理
{
;//继续读
}
printf("请确认密码(Y/N):>");
int ch = getchar();
if ('Y' == ch)
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
4.1 for循环
for(表达式1;表达式2;表达式3)
表达式1为初始化部分,用于初始化循环变量的。
表达式2为条件判断部分,用于判断循环时候终止。
表达式3为调整部分.用干循环条件的调整.
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for (i = 0; i <=9; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
for循环的continue(跳过此次循环continue后面的代码,来到调整部分,再去判断)
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (5 == i)
continue;
printf("%d ", i);
}
return 0;
}
练习:以下代码循环多少次
解释:死循环,表达式2判断部分是一个=,表示赋值,把k赋值成0
5.1 do while循环(先执行一次,在判断要不要循环)
do
循环语句;
while(表达式)
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
if (i == 5)
continue;
} while (i<=10);
return 0;
}
练习1:计算n的阶乘
int main()
{
int n = 0;
//输入
scanf("%d", &n);//
//产生1~n的数字
int i = 0;
int ret = 1;
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
printf("%d\n", ret);
return 0;
}
练习2:计算n个阶乘数字相加(1!+2!+3!...)
int main()
{
int n = 0;
//产生1~n的数字
int i = 0;
int ret = 1;
int sum = 0;
//1!+2!+3! = 1+2+6 = 9
for (n = 1; n <= 10; n++)
{
ret = ret * n;
sum = sum + ret;
}
printf("%d\n", sum);//9
return 0;
}
练习3:在一个有序数组中查找具体的某个数字n(二分查找)
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;//要查找的数字
//查找k //40 / 4
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组长度,sizeof求的是字节
int left = 0;//左下标
int right = sz-1;//右下标 //数组下标第一个从0开始,减一后才是最右边元素下标
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;
}
中间值=right的一半除2加left (优化平均值求法)
练习4:编写代码,演示多个字符从两端移动,向中间汇聚
#include <string.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
char arr1[] = "welcome to bit!!!!!!";
char arr2[] = "####################";
int left = 0;
int right = strlen(arr1) - 1;strlen求的是数组\0之前的长度,用sizeof求则要-2
//int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
while (left<=right)
{
arr2[left] = arr1[left];//交换元素
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000);//单位是毫秒,意味1s后再执行
system("cls");//执行系统命令,cls是清理屏幕显示
left++;
right--;
}
printf("%s\n", arr2);
return 0;
}
练习5:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。
两个字符串的比较是不能使用== 应该使用strcmp
第一个字符串大于第二个字符串,返回>0
第一个字符串等于第二个字符串等于,返回0
第一个字符串小于第二个字符串,返回<0
int main()
{
int i = 0;
char password[20] = { 0 };
//假设正确的密码是"abcdef"
for (i = 0; i < 3; i++)//三次机会
{
printf("请输入密码:>");
scanf("%s", password);
if (strcmp(password, "abcdef") == 0)
{
printf("密码正确\n");
break;//跳出循环,程序结束
}
else
{
printf("密码错误,重新输入\n");
}
}
//1,2
if (i == 3)
{
printf("三次密码均输入错误,退出程序\n");
}
return 0;
}
练习6:猜数字游戏
游戏需要生成随机数,C语言提供了rand库函数
写好主体,然后去写一个生成随机数的game函数时,会发现两次随机数生成是一样的.
#include <string.h>
void menu()
{
printf("*******************\n");
printf("****** 1.play *****\n");
printf("****** 0.exit *****\n");
printf("*******************\n");
}
void game()
{
int ret=rand();
printf("%d\n",ret);
}
int main()
{
int input = 0;
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;
}
调用rand函数前,需要调用srand函数来设置随机数生成
电脑上的时间一直在发生变化(时间戳),我们把电脑上的时间传给srand即可
C语言提供了一个函数time,返回一个时间戳
void game()
{
srand((unsigned int)time(NULL));//time强制类型转换unsigned int类型,也满足srand类型
int ret=rand(); //不需要用指针储存,直接传空指针
printf("%d\n",ret);
}
随机数还是不够随机,是因为我们频繁调用srand设置起点
只需要在程序调用时,运行一次即可
要生成1-100之间的数字
void game()
{
int guess = 0;
// 生成一个随机数
int ret = rand()%100+1;//任何数字%100结果是0-99,加1变成1-100
//printf("%d\n", ret);
最终代码成果
#include <string.h>
void menu()
{
printf("*******************\n");
printf("****** 1.play *****\n");
printf("****** 0.exit *****\n");
printf("*******************\n");
}
void game()
{
int guess = 0;
//1. 生成一个随机数
int ret = rand()%100+1;//1-100
//printf("%d\n", ret);
//2. 猜数字
while (1)
{
printf("猜数字:>\n");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\n");
}
else
{
printf("恭喜你,猜对了\n");
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("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
练习7:写一个关机程序,只要程序运行起来,电脑就在1分钟内关机,如果输入:一键三连,就取消关机。
#include <stdlib.h>
#include <string.h>
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的
while (1)
{
printf("请注意,你的电脑在1分钟内关机,如果输入:一键三连,就取消关机\n");
scanf("%s", input);
//判断
if (strcmp(input, "一键三连") == 0)
{
system("shutdown -a");//取消关机
break;
}
}
return 0;
}