大家好啊!欢迎来到我的博客。这里是困了电视剧,今天我将分享我对选择和循环相关知识的理解,如有疏漏欢迎大家在评论区中指正,如果对你有帮助还请一键三连,话不多说,直接上家伙!
首先在学习选择和循环语句之前我们要先了解一个知识——C语言是一种结构化的程序设计语言,其用于结构化程序设计的三种基本结构是:顺序结构、选择结构和循环结构。
顺序结构是程序设计中较为简单的,只要按照解决问题的顺序写出相应的语句即可,按自上而下的执行顺序依次执行。而选择结构和循环结构的直观体现则是我们平时在编程中常用的if,while等相关语句。
回归正题,由于选择结构和循环结构都需要依据一定的条件来选择执行的路径,那么当我们在使用他们的时候就一定要用到一个具有判断功能的语句,这种语句在不同的编程语言中都会有细微的差别,在C语言中,c99之前,C语言用0和非0的数字来实现判断功能,其中0表示错,非0表示对。比如下段代码:
#include
int main() {
if (0) {
printf("0是对\n");
}
if (1) {
printf("1是对\n");
}
if (-1) {
printf("负数表示对\n");
}
if (5) {
printf("5表示对\n");
}
if (5.0) {
printf("浮点数表示对\n");
}
return 0;
}
其执行结果为:
c99中,C语言引入了布尔类型,即通过true和false来表示对和错以实现判断的功能。
选择结构中还有switch-case语句,只不过由于if的功能比较强大,在大多数情况下,switch-case语句都很难有出场的机会,只能说生不逢时呀!
switch-case语句的使用如下列代码所示:
#include
int main() {
int i;
switch (i)
{
case 1:
case 2:
case 3:
...
default:
}
return 0;
}
这时候,可能有同学会问了,这个switch后面的()是什么都能加的吗?这又是一个考点,switch后面只能加整型和枚举类型,其他的不能加否则会报错。而case后面只能加整型常量表达式。
现在考各位同学们一个小细节,既然switch后面的括号只能根整型和枚举类型,那char型的变量放在后面的括号中会不会报错呢。
答案是:不会报错。这时候可能就有同学会问了——不是说switch后面只能根整型和枚举类型的吗,为什么我跟一个字符型变量他也能编译通过呢?这也是一个小细节,在编译器中,字符的表示基于ASCII码对照表,所以在计算机眼中,char型变量也是一个“整型”变量。
平时我们在看到别人的switch-case代码时会发现一个现象,那就是在每一个case后都会跟一个break,这又是为啥?不要着急,我们先来些一段代码跑跑试试:
#include
int main() {
int i = 1;
switch (i)
{
case 1:
printf("执行了1\n");
case 2:
printf("执行了2\n");
case 3:
printf("执行了3\n");
default:
printf("执行结束\n");
}
return 0;
}
这是我不加break的代码,我的本意是想只执行case1中的命令。他的运行结果如下:
咦?为什么所有命令都执行了呢?现在我再在每一个case后面加一个break:
#include
int main() {
int i = 1;
switch (i)
{
case 1:
printf("执行了1\n");
break;
case 2:
printf("执行了2\n");
break;
case 3:
printf("执行了3\n");
break;
default:
printf("执行结束\n");
break;
}
return 0;
}
其结果就变成:
这是怎么回事呢,为什么我加上了一个break就只执行了case1的命令呢?哦,原来,每一个case是一个入口,程序通过case入口进入语句执行命令,如果没有break,程序会一直往下执行,直到遇到break(类似出口)或执行完毕。
关于default:default和case并没有先后顺序之分,他们谁在前谁在后不影响程序执行功能。
进阶小拓展:同学们先来看一段代码:
#include
#include
int main() {
char password[20] = { 0 };
printf("请输入密码:");
scanf("%s", password);
printf("请确认(Y/N)");
int ch = getchar();
if (ch == 'Y') {
printf("确认成功\n");
}
else {
printf("确认失败\n");
}
return 0;
}
在这段代码中我想设立一段密码,然后输入Y或N确认密码,这是我的运行结果:
可以发现,我还没有输入Y或N他就报出了确认失败的字样,这是为什么呢?
答案就在于这个getchar()函数,在我们执行输入(scanf)指令时,编译器会从我们键盘的缓冲区进行读的操作,我们在键盘上敲得所有东西会先放入键盘的缓冲区,这时有趣 的现象出现了,我们在输入完密码后会打一个回车键来表示我们的密码输入完成了,进入下一条命令,这时键盘的缓冲区的样子为:
前面的所有1被password这一字符串读取,但是此时键盘的缓冲区并不是空空如也的,他还有一个\n转义字符在里面,此时ch=getchar把这个转义字符读取了,即我的ch被赋上了\n的值,由于其不是Y所以输出了错误。这时许多小白都会犯的错误(包括我),只要做如下改进即可:
#include
#include
int main() {
char password[20] = { 0 };
printf("请输入密码:");
scanf("%s", password);
printf("请确认(Y/N)");
//在ch前面加上一个getchar把键盘的缓冲区吸收干净,然后在进行赋值
getchar();
int ch = getchar();
if (ch == 'Y') {
printf("确认成功\n");
}
else {
printf("确认失败\n");
}
return 0;
}
完美。
现在我们来看循环结构,相关的循环语句我们常用的有while;do...while;for(;;)等语句。
第一个知识点:
在for的语句中,for(表达式1;表达式2;表达式3)中,三个表达式都可以进行省略,他们不是强求要加上的,但正所谓一个程序员要想写bug谁都拦不住他,这样写在某些情况下确实可能会更加简洁一下,但是,他也使程序在可读性和日后的维护上的设置了许多障碍。
第二个知识点:
同学们在平常写代码的过程中经常会遇到一个问题,那就是我的循环判断条件和我需要输入的东西有关怎么办,就比如我要计算两个数的和,当输入两个数的都为-1或其他情况时,循环结束,不再进行计算,我们有两种解决方法。
//第一种方法
#include
int main() {
while (1) {
int a, b;
scanf("%d %d", &a,&b);
//利用break
if (a == -1 && b == -1) {
break;
}
printf("%d\n", a + b);
}
return 0;
}
//第二种方法
#include
int main() {
int a, b;
//利用scanf的返回值
//当输入ctrl+z是停止
while (scanf("%d %d", &a, &b)!=EOF) {
if (a == -1 && b == -1) {
break;
}
printf("%d\n", a + b);
}
return 0;
}
最后一个:goto语句
#include
int main() {
int a = 0;
start:
scanf("%d", &a);
printf("%d\n", a);
goto start;
return 0;
}
这是一个死循环,goto语句会到达我所设置的任意一个位置并从那里重新开始执行,如果位置在goto语句之前则很容易写成一个死循环,所以goto语句虽然好用,但不建议各位同学在平常的编码中使用,它会大大提高日后代码维护的难度,所以,慎重使用!
以上,就是我对于循环和选择的理解,欢迎各位同学学习和补充!