几个经典bug
1、悬挂else
#include<stdio.h>
int main()
{
char isRain,isFree;
printf("今天是否有空?(Y/N)\n");
scanf("%c",&isFree);
getchar();
printf("今天是否下雨?(Y/N)\n");
scanf("%c",&isRain);
if(isFree=='Y')
if(isRain=='Y')
{
printf("记得带伞哦\n");
}
else --else默认是跟着最近的if的,所以这里如果输入Y,N的话,结果就是“女神没空”,那就错了
{
printf("女神没空!\n");
}
return 0;
改正:
#include<stdio.h>
int main()
{
char isRain,isFree;
printf("今天是否有空?(Y/N)\n");
scanf("%c",&isFree);
getchar(); --这里如果没有getchar,那么输入Y然后回车,就算做两 个字符,所以用getchar过滤掉回车接收第二个输入
printf("今天是否下雨?(Y/N)\n");
scanf("%c",&isRain);
if(isFree=='Y')
{
if(isRain=='Y')
{
printf("记得带伞哦\n");
}
}
else --遇if、else加{}
{
printf("女神没空!\n");
}
return 0;
2、关于等号的问题
#include<stdio.h>
int main()
{
char hasBF;
printf("小花你有男朋友吗?(Y or N)\n");
scanf("%c",hasBF);
if(hasBF=='Y') --这里是“==”(表示等于)而不是“=”(表示赋值)
{
printf("那祝福你们咯\n");
}
else
{
printf("那我们在一起吧!\n");
}
return 0;
}
循环结构
1、while语句
-
格式:
while(表达式) --(非零),那么循环体就会一直执行
循环体
例1:计算1+2+3+......100=?
#include<stdio.h>
int main()
{
int i=1,sum=0;
while(i<=100)
{
sum=sum+i;
i=i+1;
}
printf("1+2+3+......+100=%d\n",sum);
return 0;
}
例2:统计从键盘输入的一行英文句子的字符个数
#include<stdio.h>
int main()
{
int count=0;
printf("请输入英文句子:\n");
while(getchar()!='\n')
{
count=count+1;
}
printf("该英文句子的字符个数是:%d",count);
return 0;
}
注:getchar--从标准输入流中获取字符|<stdio.h>
2、do...while语句
-
格式:
do
循环体
while(表达式);
--不管三七二十一,先执行循环体然后 再判断表达式的逻辑值——真,在执行一次,假,跳出循环
--注意while后面的分号别漏了
-
优越性:比如说验证用户密码时
while语句:
do...while语句
3、循环的基本结构
-
初始化计数器
-
循环条件
-
更新计数器
对于while语句来说,这三个步骤分布在循环的不同部分,那么如果能放在一起的话,调试,修改就方便了很多,for语句应运而生
4、for语句
-
格式
for(表达式1;表达式2;表达式3)
循环体
三个表达式用分号隔开,其中:
-
表达式1是循环初始化
-
表达式2是循环条件
-
表达式3是循环调整
例1:
#include<stdio.h>
int main()
{
int count;
for(count=0;count<10;count++)
{
printf("淦!\n");
}
return 0;
}
例2:判断一个数是否为素数
-
素数就是质数,指在大于1的自然数中,除了1和此数自身外,无法被其他自然数整除的数
-
迭代法从2到num/2所有整数是否能被整除(num为待测试的数),如果没有出现能被整除的数,那么他就是素数
#include<stdio.h>
int main()
{
int i,num;
_Bool flag=1;
printf("请输入一个整数:\n");
scanf("%d",&num);
for(i=2;i<=num/2;i++)
{
if(num%i==0)
{
flag=0;
}
}
if(flag)
{
printf("%d是素数\n",num);
}
else
{
printf("%d不是素数\n",num);
}
return 0;
}
5、灵活的for语句
-
表达式1,表达式2和表达式3可以按照需要进行省略(但分号不能省略)
——for( ;表达式2;表达式3)
——for(表达式1;表达式2;)
——for(表达式1; ;)
——for( ; ;) --就是while(1)
{
......
}死循环
——......
-
表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式(即用逗号分隔多个表达式)
-
C99新标准允许在for语句的表达式1中定义变量
——for(int i=0;i<100;i++)
但注意仅在这个循环之内这个定义才起作用
6、循环嵌套
-
执行顺序是从内到外
例1:
#include<stdio.h>
int main()
{
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("i=%d j=%d\n",i,j);
}
}
return 0;
}
例2:打印九九乘法表
#include<stdio.h>
int main()
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
printf("%d*%d=%-2d ",i,j,i*j);
}
putchar('\n');
}
return 0;
}
7、循环的辅助语句
(1)break语句
-
break语句--可以极大的提高效率
例1:
#include<stdio.h>
int main()
{
int i,num;
_Bool flag=1;
printf("请输入一个整数:\n");
scanf("%d",&num);
for(i=2;i<=num/2;i++)
{
if(num%i==0)
{
flag=0;
break;
}
}
if(flag)
{
printf("%d是素数\n",num);
}
else
{
printf("%d不是素数\n",num);
}
return 0;
}
如果输入的数极大,比如说1亿,那么for循环就会被执行4999,9998次;那事实上第一次循环就已经判断出1亿不是素数了,因此直接加一个break跳出循环就好了
-
break语句只是跳出当前的循环
例2:
#include<stdio.h>
int main()
{
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<3;j++)
{
if(j==3)
{
break;
}
}
if(j==3)
{
break;
}
}
printf("i=%d j=%d\n",i,j);
return 0;
}
运行结果:i=o j=3
(2)continue语句
-
当满足某个条件时,直接跳过本轮循环的内容,开始下一个循环
例:将键盘输入的‘C’屏蔽掉
#include<stdio.h>
int main()
{
int ch;
while((ch=getchar())!='\n')
{
if(ch=='C')
{
continue; --当键盘输入的字符中有'C'时,不执行putchar(ch),直接进行下一次循环
}
putchar(ch);
}
putchar('\n');
return 0;
}
-
continue语句和break语句是一样的,即只能作用于一层循环
-
注意continue在for语句和while中的区别
#include<stdio.h>
int main()
{
int i;
for(i=0;i<100;i++)
{
if(i%2)
{
continue;
}
}
return 0;
}
——i=0,i%2=0,continue不会执行,i++;
——i=1,i%2=1,continue执行,直接跳转到i++
——......
如果把这个程序改成while语句怎么改呢
#include<stdio.h>
int main()
{
int i;
i=0;
while(i<100)
{
if(i%2)
{
continue;
}
i++;
}
return 0;
}
这就错了,因为continue后面的i++不会执行,程序进入死循环
——i=0,0%2=0,continue不会执行,i=i+1=1;
——i=1,1%2=1,执行continue,那么i++不会执行;
——i=1,1%2=1......程序进入死循环