我们写代码的时候应该养成好习惯,函数,if,switch,while,for...,写了这些东西之后,请马上将一对大括号打好。
c语言的三种基本结构:
1 顺序结构:代码从上到下依次执行
2 分支结构:判断真假进入不同的分支
3 循环结构:为了进行代码的复用
假设我想求1 + 2 + 3 + ..... + 100
根据我们的顺序结构来说
int i = 1;
int sum = 0;
sum += i;
i++;
sum += i;
i++;
sum += i;
i++;
sum += i;
i++;
...
弄一百次就出来了,上面的代码很多都是重复,因此我需要将其复用,让他们实现循环 ---- 这个东西就是我们的循环结构。
在c语言里面有四种结构实现循环
1 goto语句
2 do while
3 while
4 for
goto语句:
它的本质是无条件的实现地址的跳转,可以将指令地址跳转到我想去执行的指令地址上面去
这里仅仅是做地址的跳转,跳转中间包含的这些代码不属于代码块,他们是同一个级别的,因此不能重定义
while(1) //每循环一次都会进入这个代码块出去代码块一次里面就可以实现变量的定义
{
int a = 10; //每循环一次,这个a都会定义一次,释放一次,因此你这么写是没有问题
}
goto不能像代码块里面一样定义这个变量
goto的语法:
goto 你的目标地址; 也就是当你的代码执行到这里的时候,就会无条件的往你的目标地址上面跳转
目标地址(名字): -> 标记我们的目标地址
eg:
int main()
{
int a;
int b;
loop: //这个loop标识的是它下面的那条指令的地址
a ++;
b += a;
goto loop; //当这个代码执行的时候就会往这个loop这里去
//这样就实现了 a++ b += a这两条指令的无限循环
}
无条件跳转实现的是无限循环,而更多的时候我是希望有条件跳转的,一般我们会和if switch..搭配实现这个有限循环
int main()
{
int a = 0;
int b = 0;
loop: //这个loop标识的是它下面的那条指令的地址
a ++;
b += a;
//我希望有条件跳转
if(a < 100)
goto loop; //当它小于100的时候才会跳转
}
上面的goto和我们的代码属于同一个级别,那么里面就不能实现重定义了
错误示例:
int main()
{
loop: //这个loop标识的是它下面的那条指令的地址
int a = 0;
int b = 0; //这么写就有问题了 a b重定义了
a ++;
b += a;
//我希望有条件跳转
if(a < 100)
goto loop;//当它小于100的时候才会跳转
}
goto到目标地址的这一节不能定义变量
练习:
求100以内所有的奇数的和 ,用goto
参考代码:
#include<stdio.h>
int main()
{
int i = 1;
int sum = 0;
loop:
sum = sum + i;
i = i + 2;
if (i < 100)
{
goto loop;
}
printf("%d\n", sum);
return 0;
}
goto语句很厉害,但是当这个东西乱用之后会有很大的问题,会让我们的代码的可读性变得很差,不便于维护,因此能少用就少用。
使用这个语句一般就两种人:愣头青和技术大牛。
while循环语句
语法构成:
while(表达式)
{
循环体;
}
当表达式的值为真的时候,则执行循环体,直到表达式的值为假,退出循环,循环体属于代码块,所以定义变量没有问题的,当while下面没有大括号的时候只认下面第一句,while这些复合型语句后面自己也可以打一个;号,这个时候自己本身成为一个语句。
if(a = b);
while(1);//这里实现了死循环
所以小伙伴们有时候敲代码感觉逻辑也没问题啊,为什么就是和想的不一样呢,可能就是这些细节出问题了,一定多加留意哦。
if(key1 == 0)
{
while(key1 == 0); //51操作里面的一个判断按键的电平
}
while在执行循环的时候执行顺序为先判断表达式的值,如果为真则执行循环体,为假则退出循环,循环体执行完毕之后在判断表达式,依此类推。
练习:
还记得上次的判断水仙花数了吗,今天请你找出所有的水仙花数
用while实现
参考代码:
#include <stdio.h>
int main()
{
int i = 100;//三位数 100开始
while(i < 1000)
{
//得到这个数的个十百位
int gewei = i % 10;
int shiwei = i / 10 % 10;
int baiwei = i / 100 % 10;
//判断是否是水仙花数 立方和与它本身去比较 相等就是 不等就不是
if(gewei * gewei * gewei + shiwei * shiwei * shiwei + baiwei * baiwei * baiwei == i)
{
printf("%d\t",i);
}
i++;
}
printf("\n");//最后换一个行
return 0;
}
do while语法:
do
循环体
while(表达式);
循环体只会认一句,所以要记得打上大括号
do
{
循环体
}
while(表达式);
这个do while的循环和while的用法一样,只是有一点点区别:while是先判断表达式的值,再执行循环体,都是表达式的值为真执行循环体
for循环语句 语法:
for(表达式1;表达式2;表达式3)
{
循环体;
}
执行规则:
当走到for循环的时候,先做表达式1,
然后再判断表达式2,如果为真,则执行循环体
然后再做表达式3;然后再判断表达式2,为真继续执行循环
循环体做完,再执行表达式3;然后再做表达式2....
直到表达式2为假为止,退出循环
for循环里面的三个表达式都可以不用写,但是两个 ; ;一个都不能少,你就算一个表达式不写,都没有问题,但是必须要写上 ; ;
for( ; ;) 等效于 while(1)
当省掉表达式2之后,条件横成立,for与while没有什么区别,自己喜欢用哪个就用哪个,更多的时候是看怎么方便怎么使用。
for(;;i++)
{
a = 10;
}
while(1)
{
a = 10;
i++;
}
两个i++执行的顺序都是一样的,平时看不出什么不同,但是在continue的时候有区别
break和continue
break;当代码执行到这个break之后,它就会退出包含它的那一层循环
①while()
{
②while()
{
③break;
}
④break;
}
③号退出的是② ④号退出的是①
一般我们都会让他们有条件的退出
if(表达式)
{
break;
}
continue:结束本次循环,开始下一次循环
eg:
int i = 1;
while(i < 100) //我们做奇数的和
{
if(i % 2 == 0) //当遇到偶数之后我们需要退出这次循环 开始下一次
{
i++;
continue;
}
sum += i;
i++;
}
for(;i < 100;i++)//我们做奇数的和
{
//当遇到偶数之后我们需要退出这次循环 开始下一次
if(i % 2 == 0)
{
continue; //这个continue不会影响i++的执行
}
sum += i;
}
看到这里,就你知道上面提到的continue在for与while的区别
练习:
判断一个数是否是质数
质数:除了1 和它本身,没有其它的数将其整除,为了提高效率我们只需要除到它的一半就可以了
int i;
int j = 2;
scanf("%d",&i);
while(j <= i / 2)//除到它的一半就可以了
{
//找到能将其整除的那个数
if(i % j == 0)//说明能整除 那么这个玩意儿就不是质数
{
//你已经知道它是质数了 就没有必要往下面走了
printf("%d 不是质数\n",i);
break;
}
//没有整除的情况下你就要往下面继续尝试
j++;
}
//什么时候说明它是质数
//如果是质数 那么上面的if就永远进不去
//那么就不会被break
//说明这个j一直在递增
//它的退出为while为假了退出的
if(j > i / 2)
{
printf("%d 是质数\n",i);
}
自己写代码实现1000以内所有的质数的输出,开一个保存这个1000以内的质数的数组,只需要拿小与这个数的二分之一的质数去除就可以了,如果都不能整除,那么这个数就是质数,请将这个代码整理出来。