学习C(五)
循环结构:
循环的目的:
提高代码的重用性:在需要多次重复执行同一段代码的时候,我们可以使用循环去解决,代码中逻辑相同,数据不同,我们在循环中可以将不同的数据,使用循环变量来代替。将循环变量的范围设置成需要的值。(循环变量的范围指在一整次的循环中,该变量能够取到的值。如果超出该值,循环需要结束)
循环语句:for语句
语法 for(表达式1;表达式2;表达式3){
逻辑;
}
表达式1:循环的准备条件
通常情况为循环变量的初始值,如果循环变量在之前已经初始完毕,则此处可以省略不写。但是之后的一个分号不能省
表达式2:循环的进入条件
满足该条件(也就是意味着表达式2成立),则执行一次“逻辑”,执行完成后,会再次判断“表达式2”是否成立。一直到“表达式2”不成立为止,则整个for循环语句结束
为了使该循环不会变成死循环(也就是说,该循环能够正常的结束然后执行剩余的代码),循环条件必须在某一个点会不成立。为了达到这个目的,通常情况下,循环条件必须与循环变量挂钩,并且循环条件的改变方式,必须使得循环条件逐渐趋近与不满足
表达式3:循环变量的改变方式
什么是循环变量:随着每一次循环,都会发生改变的量,称为循环变量
那么此时,循环变量初始值就是循环变量在一整次的循环中能够取到最小/大值。有循环变量参与的循环条件,能够计算出循环变量在该整次的循环能够取到的最大/小值
循环语句中嵌套判断语句:
循环中嵌套判断语句:
针对取值范围内的所有数据的遍历,有时候并不需要所有数据都参与运算,而只需有特定一些数据进行运算,则此时,可以在循环中嵌套判断,对每一个被访问到的数据判断是否需要参与运算,如果需要,则在判断语句中,让该数据参与运算。
说白了就是使用判断语句去筛选取值范围内需要的数据
判断语句的条件触发思路在循环中也很重要:
有些时候,用户并不会准确的知道每一次循环中,到底有哪些数据参与了运算。此时,我们就可以使用条件触发的思路来解决问题。
如果该数据参与了运算,则在判断语句中将条件触发,然后在判断语句外判断条件是否触发。
循环语句中break的使用:
break既然能够跳出循环,那么break就自然的不能直接放在循环语句中。所以,我们应该将break放到判断语句中,该判断语句通常用来判断循环是否需要意外中断。然后我们在循环的外部去判断这次循环是自然的结束的还是意外中断的,我们就能知道,该次循环内部的判断是否被执行过
#include<stdio.h>
int main(){
/*printf("1\n");
printf("2\n");
printf("3\n");
printf("4\n");
printf("5\n");*/
int i = 0;
for(i=1;i<=5;i++){//这个案例中,循环变量i在一整次的循环中能够取到的值的范围就是1~5
//循环的本质其实就是通过设置循环变量的取值范围,然后在该范围内对所有的数进行遍历访问。
//什么叫遍历访问:按照从先到后的顺序,对每一个数据有且只有1次访问
printf("%d\n",i);
}
return 0;
}
#include<stdio.h>
int main(){
int i = 0;
for(i=1;i<=10;i++){
if(i%2==1){
printf("%d ",i);
}
}
printf("\n");
return 0;
}
#include<stdio.h>
/*
关于循环中的条件触发
*/
int main(){
//要求,键盘上输入一个数,判断从1到该数,是否存在能够被21整除的数
int n = 0;
scanf("%d",&n);
while(getchar()!='\n');
int i = 0;
int flag = 0;//触发点
for(i=1;i<=n;i++){
if(i%21==0){
flag = 1;
}
}
if(flag == 1){
printf("1~%d之间存在能被21整除的数\n",n);
}else{
printf("不存在\n");
}
return 0;
}
#include<stdio.h>
/*
关于循环中的意外中断情况
*/
int main(){
//要求,键盘上输入一个数,判断从1到该数,是否存在能够被21整除的数
int n = 0;
scanf("%d",&n);
while(getchar()!='\n');
int i = 0;
for(i=1;i<=n;i++){
if(i%21==0){
break;
}
}
if(i==n+1){
printf("不存在\n");
}else{
printf("1~%d之间存在能被21整除的数\n",n);
}
return 0;
}
#include<stdio.h>
/*
例如:键盘输入123456
输出654321
*/
int main(){
int num = 0;
int res = 0;
scanf("%d",&num);//12345
while(getchar()!='\n');
int i = 0;
for(i=num;i>0;i/=10){
res = i%10 + res*10;
}
printf("%d\n",res);
return 0;
}
练习1 阶乘
/*
计算:1+3+5+...+101
计算:5!
计算:1!+2!+3!+4!(使用循环)
*/
#include<stdio.h>
int main(){
int i = 0,j = 0;
int res = 0;
for(i=1;i<102;i+=2){
res = res + i;
}
printf("%d\n",res);
res = 1;
for(i=1;i<=5;i++){
res = res * i;
}
printf("%d\n",res);
int res1 = 0;
int res2 = 1;
for(i=1;i<=4;i++){
res2 = 1;
for(j=1;j<=i;j++){
res2 = res2 * j;
}
res1 = res1 + res2;
}
printf("%d\n",res1);
return 0;
}
注意整体思维,就是把循环体看做一个整体,先做循环体在做循环变量
练习2 最大公约数和最小公倍数
#include<stdio.h>
/*
从键盘输入2个数,分别输出这两个数的最大公约数和最小公倍数
最大公约数:从理论最大公约数开始向下查找他们的公约数,找到的第一个公约数就是最大公约数
*/
int main(){
int x = 0,y = 0;//6,8
scanf("%d %d",&x,&y);
while(getchar()!='\n');
int i = 0;
i = (x<y)?x:y;
for(;x%i!=0 || y%i!=0;i--);
printf("%d和%d的最大公约数为:%d\n",x,y,i);
i = (x>y)?x:y;
for(;i%x!=0 || i%y!=0;i++);
printf("%d和%d的最小公倍数为:%d\n",x,y,i);
return 0;
}
练习3 回文数
#include<stdio.h>
/*
从键盘输入一个数,判断他是否是回文数
回文数:12321,123321,32123,321123,12121,121121是回文数,12345 不是回文数
*/
int main(){
int num = 0;
int res = 0;
scanf("%d",&num);//12345
while(getchar()!='\n');
int i = 0;
for(i=num;i>0;i/=10){
res = i%10 + res*10;
}
if(res == num){
printf("%d是回文数\n",res);
}
return 0;
}
练习4 1/1-1/3+1/5-1/7…计算前20项
#include<stdio.h>
/*
计算:1/1-1/3+1/5-1/7...计算前20项
*/
int main(){
double i = 0;
double res = 0;
int j = 1;
for(i=0;i<4;i++){
res = res + 1/(i*2+1)*j;
j = -j;
}
printf("%lf\n",res);
return 0;
}
练习5 质数
/*
使用循环->条件触发的 设计思路解决问题:
例如说,求一个数是否存在数字3。
通过循环,将每一位数字取出,然后将取出的数与3比较,如果相等则触发条件/循环意外中断
循环外部,判断条件是否触发/循环是否意外中断来判断是否存在3
*/
#include<stdio.h>
/*
设计一个循环逻辑用来判断一个数是否为质数
并且使用该逻辑,求出1~100之中所有质数的和
*/
int main(){
int num = 0;
int res = 0;
int i = 0;
for(num=2;num<=100;num++){
for(i=2;i<num;i++){
if(num%i==0){
break;//意外中断意味着存在num之外的其他约数,也就是说num不是质数
}
}
if(i==num){
//进入这个if代表num是质数
res = res + num;
}
}
printf("%d\n",res);
return 0;
}
练习6 完数
/*
使用循环->条件触发的 设计思路解决问题:
例如说,求一个数是否存在数字3。
通过循环,将每一位数字取出,然后将取出的数与3比较,如果相等则触发条件/循环意外中断
循环外部,判断条件是否触发/循环是否意外中断来判断是否存在3
*/
#include<stdio.h>
/*
设计一个循环逻辑用来判断一个数是否为完数
并且使用该逻辑,输出1到10000之内所有的完数
完数:除去本身之外所有约数之和等于本身。例如6,他的约数有1,2,3,6,去掉本身之后剩余的约数为1,2,3, 由于1+2+3=6,所以6就是完数
*/
int main(){
int i = 0;
int num = 0;
int res = 0;
for(num=2;num<=10000;num++){
res = 0;
for(i=1;i<num;i++){
if(num%i==0){
res = res + i;
}
}
if(res == num){
printf("%d ",num);
}
}
printf("\n");
return 0;
}
练习7 水仙花数
/*
使用循环->条件触发的 设计思路解决问题:
例如说,求一个数是否存在数字3。
通过循环,将每一位数字取出,然后将取出的数与3比较,如果相等则触发条件/循环意外中断
循环外部,判断条件是否触发/循环是否意外中断来判断是否存在3
*/
#include<stdio.h>
#include<math.h>
/*
设计一个循环逻辑用来判断一个数是否为水仙花数
并且使用该逻辑,输出所有水仙花数
水仙花数:是一个三位数,他的每一位的立方之和等于本身,例如153:1^3+5^3+3^3 = 1+125+27 = 153,所以153是水仙花数
*/
int main(){
int i = 0;
int num = 0;
int res = 0;
for(num=100;num<1000;num++){
res = 0;
for(i=num;i>0;i/=10){
res = res + pow(i%10,3);
}
if(res == num){
printf("%d ",num);
}
}
printf("\n");
return 0;
}
练习8 转换成二进制数
#include<stdio.h>
#include<math.h>
/*
从键盘输入一个数,将他转换成二进制的形式输出,也就是说如果输入的是10,则输出的就是1010
*/
int main(){
int num = 0;//输入的十进制数
int retval = 0;//累加值
int rest = 0;//短除法中每一次的余数
int count = 0;//统计当前循环次数的计数器
scanf("%d",&num);
while(getchar()!='\n');
for(;num>0;num/=2){
rest = num % 2;
if(rest == 1){
retval = retval + rest*pow(10,count);
}
count++;
}
printf("%d\n",retval);
return 0;
}
练习9 2+22+222+…+n个2的值
/*
计算:2+22+222+...+n个2的值
当然2可以从键盘输入任何一个数,n必须要从键盘输入
*/
#include<stdio.h>
int main(){
int i = 0;//循环变量
int m = 2;//固定值
int n = 0;//n项
int res = 0;//n项之和
int val = 0;//单独计算的每一项的值
scanf("%d",&n);
while(getchar()!='\n');
for(i=0;i<n;i++){
val = val*10 + m;
res = res + val;
}
printf("%d\n",res);
return 0;
}
练习10 斐波那契数列
#include<stdio.h>
/*
编写一个逻辑,实现功能:输入一个数n,将他作为斐波那契数列的第n项,然后输出该项的值
斐波那契数列:1,1,2,3,5,8,13...
*/
int main(){
int i = 0;
int n = 0;
int f1 = 1;
int f2 = 1;
int fn = 1;
/*
1 1 2 3 5 8
f1 f2 fn
f1 f2 fn
f1 f2 fn
*/
scanf("%d",&n);
while(getchar()!='\n');
for(i=3;i<=n;i++){
fn = f1 + f2;
f1 = f2;
f2 = fn;
}
printf("%d\n",fn);
return 0;
}