分支语句
if
1.基本语法:
if(表达式)
语句
如果表达式为真则执行语句,如果表达式为假则不执行语句。
·C语言中非0为真,0为假。
2.else
if(表达式)
语句1
else(表达式)
语句2
如果if语句为真则执行语句1,如果if语句为假则执行语句2。
3.if和else都默认控制后面的一条语句,若想控制更多的语句,需要在后面加代码块{}。
例如:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18) //if 后使⽤{} 控制多条语句-这个块也叫:程序块,或者复合语句
{
printf("成年了\n");
printf("可以交⼥朋友了\n");
}
return 0;
}
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)//if 后使⽤{} 控制多条语句-这个块也叫:程序块,或者复合语句
{printf("成年了\n");
printf("可以交⼥朋友了\n");}
else //else 后使⽤{}控制多条语句-这个块也叫:程序块,或者复合语句
{
printf("未成年\n");
printf("不可以早恋哦\n");
}
return 0;
}
4.嵌套if语句
例如:
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输⼊的数字是0\n");
else if(num > 0) //这⾥的if 相当于嵌套在els语句中,形成了嵌套结构
printf("输⼊的数字是正数\n");
else
printf("输⼊的数字是负数\n");
return 0;
}
·if语句按顺序读取if、else if,读取到真时则后面的else if短路(C语言逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。)。
例如:
if(month >= 3 && month <= 5)
//当month<3时,month不会再和5比较以提高效率。
//像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进⾏计算的运算称为短路求值。
5.悬空else问题(else的匹配问题)
·如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的 if 匹配。
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
·上述代码的结果为什么也不打印。
·如果想第一个if和else匹配,可以这样修改代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
switch
·switch和if语句一样是分支语句,和if相同,switch会决定程序进入语句的入口,但和if不同的是:if语句只执行对应入口的语句而switch语句则会按顺序执行剩下的所有语句,要想switch和if语句一样则需要break
1.基本用法
switch (expression) {
case value1: statement
case value2: statement
default: statement
}
上⾯代码中,根据表达式 expression 不同的值,执行相应的case 分支。如果找不到对应的值,就执行 default 分支。(注意:default不一定要写,且它的位置随意不一定再case后面)
2.• switch 后的 expression 必须是整型表达式(可以是变量)。
• case 后的值,必须是整形常量表达式。
•case和后面的值间隔着一个空格。
3.在case后面一般要加break,但也非绝对。
例如:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{case 1:
printf("星期⼀\n");
break;
case 2:
printf("星期⼆\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
}
return 0;
}
另一种写法:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("⼯作⽇\n");
break;
case 6:
case 7:
printf("休息⽇\n");
break;
}
return 0;
}
显然下面的代码更加整洁且效率更高。
·还有的情况就是输入的值不是int 1到7,这时我们可以在后面加
default:
printf("输⼊错误\n");
break;
当输入的值为其他的整数以后,就会显示输入错误。
循环语句
while
while(a)
//语句或者{语句}
当a为非0时,语句或者代码块内的语句会循环执行,若无中止,则会进入死循环
例如:
输入一个正的整数,逆序打印这个整数的每⼀位
例如:
输⼊:1234,输出:4 3 2 1
输⼊:521,输出:1 2 5
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
while(n)
{
printf("%d ", n%10);//不断求余获得个位数
n /= 10;//去掉个位数
}
return 0;
}
·多组输入:运用while的循环我们可以实现多组输入,具体方法如下,
#include <stdio.h>
int main()
{
int iq = 0;
while (scanf("%d", &iq) != EOF)
{
if (iq >= 140)
printf("Genius\n");
}
return 0;
}
for
for循环时三种循环语句中最常用的。其基本语法为for(初始化;判断;调整)
例如:
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}
·第一次进入for循环时,i被初始化为,然后开始进行判断i是否<=10,显然i<=10,所以执行下方代码块的内容,执行完毕后再去到调整语句,让i++,若干次后当i++后i等于11,则跳出循环。
···while和for循环本质上大差不差,
但是相对while的分散来说,for的初始化、判断、调整都更加集中,也便于维护。
do while
基本语法
do
语句;
while(表达式);
即先执行后判断,也就是最少执行一次循环体,这个循环语句是三种循环中用的最少的。
break、continue和goto
在循环语句中break和continue是非常重要的。
• break 的作用是用于永久的终止循环,只要 break 被执行,直接就会跳出循环,继续往后执行。
• continue 的作用是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所差异的。
先举例说明continue在while和for中的区别
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
printf("%d ", i);
i = i+1;
}
return 0;
}
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;
printf("%d ", i);
}
return 0;
}
· 第一个代码中当i等于5后,就执行continue,直接跳过continue的代码,去循环的判断的地方因为这里跳过了i = i+1,所以i⼀直为5,程序陷入和死循环。
·第二个代码中这里continue跳过了后边的打印,来到了i++的调整部分,所以程序不会进入死循环。
·这也是for优于while的一点。
·上述while想不死循环,可以将调整语句置于if前,但可能与理想结果有所偏差。
• goto语句可以实现在同一个函数内跳转到设置好的标号处。
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next:
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
上述打印结果将会是hehe 跳过了haha的打印。
goto语句使用不当会导致程序紊乱,它的优点在于容易跳出多层循环嵌套。
循环嵌套
例题解析:找出100~200之间的素数,并打印在屏幕上。
#include <stdio.h>
int main()
{
int i = 0;
//循环产⽣100~200的数字
for(i=100; i<=200; i++)
{
//判断i是否为素数
//循环产⽣2~i-1之间的数字
int j = 0;
int flag = 1;//假设i是素数
for(j=2; j<i; j++)
{
if(i % j == 0)
{flag = 0;
break;}
}
if(flag == 1)
printf("%d ", i);
}
return 0;
}
上述代码就使用了多层循环嵌套,但j<i的话效率不高,可以略作优化.
#include <math.h>
#include <stdio.h>
int main()
{
int i = 0;
int count = 0;
for (i = 101; i <= 200; i += 2)
{
int j = 0;
int flag = 1;//假设i是素数
for (j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
sqrt是开平方的意思,该函数为库函数,要运用的话需要引用头文件math.h。
操作符
关系操作符
C 语言用于比较的表达式,称为 “关系表达式”(relationalexpression),里面使用的运算符就称
为“关系运算符”(relational operator),主要有下面6个。
1.> 大于运算符;26…<小于运算符;3.==相等运算符;4.!=不相等运算符;5.>=大于等于运算符;<=小于等于运算符
·注意!!关系表达式通常返回 0 或 1 ,表示真假。
也就是说关系运算符最好不要连续使用
5<10<7//该式子返回值为1,
上述代码先比较5和10,因为5<10所以返回值为1,再比较1和7,因为1<7所以返回值为1。(即关系运算符的判断顺序为从左到右)
·此外要注意的是:==不等同于=,等于是赋值
int a=5;
if(a=3)
printf("hello");
上述代码最终会打印hello,因为if判断里面是a赋值了3,而3是非0的所以为真。所以为避免将==打成=,敲代码时往往将常量写在左边。
if(3==a)//因为3=a时不可能的,不能对常量赋值
这样就可以大大减少敲错代码的概率。
逻辑操作符
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。
1.! :逻辑取反运算符(改变单个表达式的真假);
2.&& :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假);
3.|| :或运算符,就是或者的意思(两侧至少有⼀个表达式为真,则为真,否则为假)。
使用示范:
#include <stdio.h>
//代码1
int main()
{
int year = 0;
scanf("%d", &year);
if(year%4==0 && year%100!=0)
printf("是闰年\n");
else if(year%400==0)
printf("是闰年\n");
return 0;
}
//代码2
int main()
{
int year = 0;
scanf("%d", &year);
if((year%4==0 && year%100!=0) || (year%400==0))
printf("是闰年\n");
return 0;
}