前言
“光说不练假把式”,C语言分支和循环语句有很多值得反复揣摩、有趣的实例,并且其中有很多意想不到的坑,让我们一探究竟!!!
一、分支结构
if, else if, switch语句用于实现分支结构,switch…case语句用于一般用于实现多分支,相较于if…else更简洁。
二、循环结构
关键字for, while, do…while都能实现循环结构,但用的多的还是for循环。其实用for实现的循环用while语句也能实现,区别在于while语句的变量初始化、判断语句、变量调整语句较分散,而for循环将三者简洁地结合成一条语句,使用更加方便,因此for循环使用较多。
当然while循环也有for循环不可代替之处,具体如何选择根据实际情况。笔者在此多介绍for循环实例,后文有while的应用。
1.for循环
实例一-九九乘法表
代码如下(示例):
#include <stdio.h>
int main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
printf("%d*%d=%d\t",j,i,i*j);
printf("\n");
}
return 0;
}
注意观察规律,九九乘法表每一行乘号左边的数字从左往右是从1增加到行数,右边是行数,即每一行变化的是左边,右边的数随着列变化而增加,用i控制列,j控制行,行列对应的变量要搞清楚!
实例二-求素数——代码优化
代码如下(示例):
#include <stdio.h>
int main()
{
for (int i = 100; i <= 200; i++)
{
int flag = 1;
for (int j = 2; j < sqrt(i); j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag==1)
printf("%d ", i);
}
return 0;
}
代码优化,此处用的是j < sqrt(i)
,而不是j<i
,效率更高,其实我们在写代码的时候精益求精,不仅要解决问题,也要思考如何更高效的解决问题!
实例三-求1-100中数字9的出现次数——“逻辑错误”坑!
代码如下(示例):
int main()
{
int sum = 0;
for (int i = 1; i <= 99; i++)
{
if (i % 10 == 9)
sum++;
if (i / 10 == 9)
sum++;
}
printf("%d\n", sum);
return 0;
}
此处如果使用语句
if(i % 10 == 9 || i / 10 == 9)
sum++;
代替
if (i % 10 == 9)
sum++;
if (i / 10 == 9)
sum++;`
输出结果是19,正确结果是20.原因是将99中两个9算成了一个,然而第一个判断语句计算的是个位的9,第二个判断语句计算的是十位的9,如果用逻辑或,逻辑都不正确!!!
警示我们在写代码的时候千万不能偷懒,逻辑一定要清晰!!!
2.while
实例一-求最小公约数——变量值交换
int m = 0;
int n = 0;
int temp = 0;
scanf("%d %d", &m, &n);
if (m < n)
{
temp = n;
n = m;
m = temp;
}
while (m % n)
{
temp = m % n;
m = n;
n = temp;
}
printf("%d\n", n);
变量值交换的方法,引入中间值,保证逻辑清晰,不要丢失变量值;
m=n
,即谁的值不要了,先将另一个变量的值赋给谁。
实例二-关机程序
char input[20] = { 0 };
system("shutdown -s -t 60");
while (1)
{
printf("请注意,您的电脑将在一分钟后关机,如需取消,请输入:我是猪\n");
scanf("%s", input);
if (strcmp(input, "我是猪") == 0)
{
system("shutdown -a");
break;
}
}
system("...")
system用于执行系统命令,shutdown -s -t X(秒数)
,电脑将在X秒后关机;
shutdown -a
取消关机,这两条语句放在system中均可执行。system在“命令提示符”窗口中也能直接使用。
3.do…while
实例一-猜数字游戏
do…while循环使用较少,一般适用于无需判断至少循环一次的循环体,此处结合分支语句if, switch, 循环语句while和函数等内容实现猜数字游戏。
代码如下(示例):
#include <stdio.h>
#include <math.h>
#include <string.h>
void menu()
{
printf("*********************************\n");
printf("******* 1: play 0: exit *******\n");
printf("*********************************\n");
}
void game()
{
int guess = 0;
int count = 5;
int r = rand() % 100 + 1;
while (1)
{
printf("你还有%d次机会,", count);
printf("请猜数字>:");
scanf("%d", &guess);
if (guess > r)
printf("猜大了\n");
else if (guess < r)
printf("猜小了\n");
else
{
printf("恭喜你,猜对了\n");
break;
}
count--;
if (count == 0)
{
printf("5次机会已用完,游戏结束,正确答案是%d\n\n", r);
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");
//此处input可能为字符串,但不可能考虑到所有情况,就像程序总有Debug
break;
}
} while (input);
return 0;
}
Tips:
1.变量初始化:
在VS中局部变量必须初始化,全局变量如未初始化,系统默认初始化为0.
局部变量(Local variables)指在程序中只在特定过程或函数中可以访问的变量。不能在特定过程或函数之外访问;
2.见微知著,程序的设计:
在程序设计中,会有用户界面菜单、游戏过程设计,包括次数限制等。
在写程序时,先搭建大的框架,比如“菜单-游戏过程-…”,再搭建分支,比如游戏过程的实现框架;以及进行优化,加入次数的限制或其他。
总结
将学到的知识内化-输出,加深印象,这就是写博客的意义吧。在写代码的时候踩了不少坑,代码复现的时候会出现忘了的情况,回头看源码,思考为什么这样写?我为什么没想到?甚至是能够想到代码相似的应用场景,这样日复一日,何愁无进步?以及思考源码如何进行优化,前提保证逻辑正确!