> 文章列表 > 【C语言】分支语句和循环语句(下)

【C语言】分支语句和循环语句(下)

【C语言】分支语句和循环语句(下)

【C语言】分支语句和循环语句(下)

  • 1.for循环
    • 1.2 语法
    • 1.3 break和continue在for循环中
    • 1.4 for语句的循环控制变量
    • 1.5 一些for循环的变种
    • 1.6一道笔试题
  • 2. do……while()循环
    • 2.1 do语句的语法
    • 2.2 do语句的特点
    • 2.3 do while循环中的break和continue
  • 3.练习

所属专栏:C语言
博主首页:初阳785
代码托管:chuyang785
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!

1.for循环

1.2 语法

for(表达式1; 表达式2; 表达式3)
循环语句;
  • 表达式1
    表达式1为初始化部分,用于初始化循环变量的。
  • 表达式2
    表达式2为条件判断部分,用于判断循环时候终止。
  • 表达式3
    表达式3为调整部分,用于循环条件的调整。

例如:

#include <stdio.h>
int main()
{int i = 0;//for(i=1(初始化); i<=10(判断部分); i++(调整部分))for(i=1; i<=10; i++){printf("%d ", i);}return 0;
}

上面就会打印1-10。

for循环的流程图:
在这里插入图片描述
我们对比一下while:

int i = 0;
//实现相同的功能,使用while
i=1;//初始化部分
while(i<=10)//判断部分
{printf("hehe\\n");i = i+1;//调整部分
}
//实现相同的功能,使用while
for(i=1; i<=10; i++)
{printf("hehe\\n");
}

可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。

1.3 break和continue在for循环中

我们一串代码:

#include <stdio.h>
int main()
{int i = 0;for (i = 1; i <= 10; i++){if (5 == i)break;printf("%d ", i);}

这个结果是什么呢?
在这里插入图片描述
我们看到了当i==5的时候就跳出程序了,和while是一样的。

那如果我们改成continue会怎么样呢?
在这里插入图片描述
我们看到他并没有打印5,当i==5的时候就跳过了。

所以这里的break和continue是一样的,遇到break直接跳出循环,遇到continue跳过这个节点开始下一个节点。

1.4 for语句的循环控制变量

建议:

  1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
  2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。

就比如:

#include <stdio.h>
int main()
{int i = 0;for(i=1; i<=10; i++){printf("%d ", i);i=5;}return 0;
}

对于第一点:
如果你想上面那样i=5的话就会出现错误,这样的话就陷入了死循环,每次你打印完后i=5,i就永远到不了10就会一直循环下去,这样就出错了。

对于第二点:
这个点主要是针对数组,因为我们的数组下标是从0开始的。

#include <stdio.h>
int main()
{int arr[5]={1,2,3,4,5};int i=0;for(i=0;i<5;i++){printf("%d",arr[i]);}return 0;
}

这里我们取值的范围是i=0;i<5即:0 1 2 3 4,刚好是数组的下标,这样子的话就会更方便的定义数组,防止后续因下标问题出现一系列的问题。

1.5 一些for循环的变种

#include <stdio.h>
int main()
{//代码1for(;;){printf("hehe\\n");}//for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。

我们看上面一串代码它执行的结果是什么呢?
答案是死循环。
因为我们的初始化部分,条件部分以及调整部分都是空,也就是说没有谁限制for循环,那么for循环就可以为所欲为,就会一直循环下去停不下来 。

  //代码2int i = 0;int j = 0;//这里打印多少个hehe?for(i=0; i<10; i++){for(j=0; j<10; j++){printf("hehe\\n");}}
    //代码3int i = 0;int j = 0;//如果省略掉初始化部分,这里打印多少个hehe?for(; i<10; i++){for(; j<10; j++){printf("hehe\\n");}}

我们先看代码2,两给for循环嵌套,打印100个hehe。
但是如果我们省略吊我们的初始部分会怎么样?
在这里插入图片描述
会发现他只打印了10个hehe并没有打印100个hehe。
但我们进入for循环的时候i和j在外部初始化为0,进入后初始值是0,后面经过i++,和j++后由于我们for循环没有初始化部分所以i和j都会又累加效果所以当j++到4的时候它的条件语句就不会通过也就是说它不会在进入第二个for循环中打印hehe了。

同时我们的for循环里面的表达式可以是多个的:

#include <stdio.h>
int main()
{//代码4-使用多余一个变量控制循环int x, y;for (x = 0, y = 0; x<2 && y<5; ++x, y++){printf("hehe\\n");}return 0;}

1.6一道笔试题

//请问循环要循环多少次?
#include <stdio.h>
int main()
{int i = 0;int k = 0;for(i =0,k=0; k=0; i++,k++)k++;return 0;
}

这里循环0次。
因为这里我们的初始化部分i=0,k=0;而我们条件部分是k=0是一个赋值操作,这个时候k就等于0,0为假就跳出循环。

2. do……while()循环

2.1 do语句的语法

do循环语句;
while(条件表达式);

2.2 do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用。

#include <stdio.h>
int main()
{int i = 1;do{printf("%d ", i);i=i+1;}while(i<=10);return 0;
}

这里我们同样可以打印出1-10;

2.3 do while循环中的break和continue

#include <stdio.h>
int main()
{int i = 1;do{if(i==5)break;printf("%d ", i);i=i+1;}while(i<=10);return 0;
}

在这里插入图片描述
同样是跳过了5;

#include <stdio.h>
int main()
{int i = 1;do{if (i == 5)continue;printf("%d ", i);i = i + 1;} while (i <= 10);return 0;
}

在这里插入图片描述
我们发现死循环了,那是因为我们continue是回到头部,这个时候就不进行我们的条件语句i++
所以i就一直等于5为真就一直打印下去了。

3.练习

  1. 计算n的阶乘。
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int i = 0;int sum = 1;for (i = 1; i <= n; i++){sum = sum * i;}printf("%d", sum);return 0;
}
  1. 计算1!+2!+……10!阶乘的和。
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int i = 0;int j = 0;int sum2 = 0;for (j = 1; j <= n; j++){int sum = 1;for (i = 1; i <= j; i++){sum = sum * i;}sum2 += sum;}printf("%d", sum2);return 0;
}

优化

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int i = 0;int j = 0;int sum2 = 0;for (j = 1; j <= n; j++){sum = sum * j;sum2 += sum;}printf("%d", sum2);return 0;
}
  1. 在一个有序的数组中查找具体的某个数字n。
#include <stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;int k = 5;int flag=0;for (i = 0; i < 10; i++){if (arr[i] == k){printf("找到了,下标是%d", i);flag=1;}}if(flag==0)printf("没找到");return 0;
}

二分查找法(折半查找法)

int main()
{int arr[] = {1,2,3,4,5,6,7,8,9,10};int left = 0;int right = sizeof(arr)/sizeof(arr[0])-1;//sizeof是计算的字节数,这里sizeof(arr)是计算这个数组的字节数我们除于首元素的大小就得到了数组的个数。int key = 7;int mid = 0;while(left<=right){mid = (left+right)/2;if(arr[mid]>key){right = mid-1;}else if(arr[mid] < key){left = mid+1;}elsebreak;}if(left <= right)printf("找到了,下标是%d\\n", mid);elseprintf("找不到\\n");
}
  1. 编写代码,演示多个字符从两端移动,向中间汇聚。
#include <stdio.h>
#include <string.h>
int main()
{char s1[] = "*********************";char s2[] = "abcdefghijklmnopqrstu";int left = 0;int right =strlen(s2) - 1;printf("%s\\n", s1);while (left <= right){s1[left] = s2[left];s1[right] = s2[right];printf("%s\\n", s1);left++;right--;}return 0;
}

优化:
如果我们想要子我们的显示屏上展示出动态的效果该怎么办呢?

#include <stdio.h>
#include <string.h>
#include<windows.h>
int main()
{char s1[] = "*********************";char s2[] = "abcdefghijklmnopqrstu";int left = 0;int right =strlen(s2) - 1;printf("%s\\n", s1);while (left <= right){s1[left] = s2[left];s1[right] = s2[right];printf("%s\\n", s1);Sleep(1000);system("cls");left++;right--;}printf("%s",s2);return 0;
}

这里介绍三个个函数:
1.Sleep()睡眠函数,单位毫秒。头文件#include<windows.h>
2…system(“cls”) // system函数是可执行命令,cls是清理屏幕的命令
3.strlen计算字符串长度的函数,头文件#include<string.h>

这里要注意的是我们计算字符串的长度的时候不能用sizeof计算,因为我们字符串是包含了\\0的但是字符串长度是不计算\\0 的,而我们的sizeof是会把\\0 的大小计算进去的。

  1. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。
#include <stdio.h>
#include <string.h>
int main()
{int i = 0;int flag=0;char password[20] = { 0 };for (i = 0; i < 3; i++){printf("输入密码");scanf("%s", password);if (strcmp(password, "123456") == 0){printf("登录成功\\n");flag=1;}else{printf("密码错误\\n");}}if(flag=0){printf("退出程序");}return 0;
}

这里又得引入一个函数:字符串比较函数。
当我们比较两个字符串是否相等的时候不能直接用等号判断,而是要用专门的字符串比较函数
strcmp(exp1,exp2)头文件是#include<string.h>
他的特点是:
如果exp1==exp2,返回0;
如果exp1>exp2,返回大于0的数;
如果exp1<exp2,返回小于0的数;