一 运算符
1 运算符及分类
运算符是特定的算术或者逻辑符号。
1)按功能分类
算术运算符、关系运算符、逻辑运算符和按位运算符。
2)按操作数的个数分类
单目运算符、双目运算符和三目运算符。
2 运算符的优先级
运算符的优先级分15等级,1级最高,15级最低。
表达式中,优先级高的的先于低的运算,优先级相同的时候,按照运算符的结合性运算。
3 运算符的结合性
左结合:多个同级优先级的运算符,从左向右运算。比如 算数运算符。
右结合:与左结合相反,比如赋值运算符。
4 表达式
表达式:将同类型的数据(常量,变量和函数等)用运算符按照一定规则连接起来的式子。表达式一定有返回值。
表达式后加分号,构成表达式语句。
1)表达式分类
算术表达式、关系表达式和逻辑表达式。
5 常用运算符
1) 算数运算符(左结合):+ - * / %
操作数为int型时,结果取整,如果有一个为实数类型,结果为双精度实数。
m/n 取余的时候结构正负性取决于 m。
2)赋值运算符(右结合) =
作用:把等号右侧的值赋值给左侧的变量。
变量=值(或表达式);
注意:等号左侧一定是变量,不能是表达式。
3) 复合赋值运算符 += ……
先运算后赋值。
a + = 3 作用和 a=a+3;作用一样
4) 自增自减运算符 i++; i--;++i;--i;
前缀表达式 ++i; --I; i++;作用和 i=i+1;一样
先让变量i自增自减,之后用自增自减之后的i值作为表达式的值
后缀表达式 i++; i--;
先用i值作为表达式的值,之后i的值再自增自减
5) sizeof运算符)
作用:给出操作数的存储大小。单位(字节)
用法: sizeof(数据类型/常量/变量/结构体)
注意:sizeof不是函数,编译时进行
6) 逗号运算符
作用:把两个表达式连接到一起,形成逗号表达式。
求值过程:分别求每个表达式的值,以最后的表达式的值作为整个表达式的值。
例 Int a=4,b=6,c=7;
Int result =(a+1,b+1,c+1);逐个求值 最后把c+1的值赋值给result。
逗号表达式不注重求值的结果,注重求值过程中哪些变量的值发生了变化。
7) 关系运算符(左结合)> 、<、>=、<=、==、!=
所有的数值都有真假性,非0即真,只有0为假。
关系运算符的返回值只有0和1.
8) 逻辑运算符 (或)||、&&(与)、(非)!
或(左结合):两个表达式只要有一个真值,整个表达式的值就为真。
短路或:前一个表达式的值为真,后面表达式就不进行判断了
例
int x=y=1;
Int result= ++x || ++y;
此时 x值为2 y值为1 result的值为1(真)。
与(左结合):两个表达式的值都为真,整个表达式的值才为真。
短路与:前一个表达式的值为假,后面表达式就不进行判断了
例 int x=1,y=2;
Intresult = x>y && x++ > y++;
此时x值为1,y值为2 result值为0(假)。
非(右结合):非真即假,非假即真。
9) 三目运算符(右结合) ? :
条件表达式? 表达式1:表达式2
如果条件表达式的值为真,表达式1的值为整个表达式的值。
如果条件表达式的值为假,表达式2的值为整个表达式的值。
注意:? 和:是成对出现。
例 取a和b中较大值赋值给result。
int a=5,b=6
int result = a>b? a:b;
取a、b和c中较大值赋值给result。
int a=5,b=6,c=7;
nt result=a>b?a:b>c?b:c
二 程序结构
程序结构的分类
顺序、 分支和循环
1分支结构(if-else)
1)if-的使用形式
如果条件为真执行语句块1,否则跳过。
If(常量/变量/表达式){
语句块1;
}
2) if –else形式
如果条件为真执行语句块1,为假执行语句块2。
If(常量/变量/表达式){
语句块1;
}else{
语句块2;
}
3)if-else 嵌套形式
if(常量/变量/表达式){
if(常量/变量/表达式){
语句块1;
}else{
语句块2
}
}else{
语句块3
}
4) if语句高级用法
逐次判断if的条件 如果条件为真,执行当前语句块,执行完结束,否则判断下一个if条件,如果条件为真,执行当前语句块。依次执行,如果条件都不为真执行最后的else里的语句块。
if(常量/变量/表达式)}{
语句块1;
}else if(常量/变量/表达式){
语句块2;
}else if(常量/变量/表达式){
语句块3;
}
5) If语句的使用注意事项
a, if(常量/变量/表达式); 无论真假,都不执行。
b, if后如果只有一句话。则可以省略大括号
if(常量/变量/表达式)
语句;
c, 永真式和永假式
永真式 if(1)
永假式 if(0)
d,if语句中return
一个函数中,可以有多个return语句,但只执行一个。
在一个函数中,执行return之后,return之后的语句不会执行。
e , if的作用域
作用域为if之后的大括号开始到大括号结束。
f ,作用于紊乱。
if(条件)
int num=10; //报错
if(条件){
int num=10; // 不会报错。
}
g 大括号的匹配
避免匹配麻烦,不要省略大括号。
2 分支结构(switch)
首先计算表达式的值。并逐个与其后的常量表达式的值进行比较,当表达式的值与常量表达式的值相等时,执行其后的语句,执行完毕后break跳出switch语句。。
1)使用形式:
switch(表达式){
case 常量表达式1:
语句1;
break;
case 常量表达式2:
语句2;
break;
……
default:语句n+1;
}
2)注意
a , case具有向下穿透作用,执行完当前case后语句时,如果语句后没有break程序将继续向下执行之后case后的语句,直到遇到break或者执行到语句末为止。
b, 可以用在不同常量表达式对应的语句块相同时使用。
c, switch语句的表达式类型
可以是整型常量(5);可以是整型变量();可以是转换为整类型的表达式(‘a’);还可以是返回值为整形的表达式(5+4)。
d, case后的值只能是常量(1)或者常量表达式(8+8)
e ,default位置可以放在任意位置
f , case可以穿透到default语句。
h ,default语句如果放在最后是可以省略break 如果不是最后不可以省略。
3)case穿透应用举例
<span style="font-size:14px;">/**
* 根据传入年份和月份返回该年该月的天数
*
* @param year 年份
* @param month 月份
*
* @return 该年该月的天数
* 月份为 1、3、5、7、8、10和12 时为31
* 月份为 2、4、6、9和11 时为30
* 闰年2月时29 平年2月28
*/
int getDaysInMonth(int year,int month){
int days=0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days=31;
break;
case 4:
case 6:
case 9:
case 11:
days=30;
break;
case 2:
//判断当前年份是否是闰年
if(isLeapYear(year)) {
days=29;
}else {
days=28;
};
break;
default:
break;
}
return days;
}</span>
3 if分支结构和switch分支转换
如果分支比较多且无法穷尽的时候尽量使用if。
如果分支不是很多,但是使用if代码量比较大是时候可以使用switch。
switch比较清晰条理,if注意嵌套。
if和switch之间的转换举例
<span style="font-size:14px;">/*
main.c
8、 输入一个整数score代表分数,根据分数输出等级A-E (C语言编程题)
A:90~100
B:80~89
C:70~79
D:60~69
E:0~60
*/
#include<stdio.h>
voidgetLevelBySwitch(int score);
voidgetLevelByIfElse(int score);
intmain(int argc, const char * argv[]) {
int score=0;
printf("请输入一个0-100之间的分数\n");
scanf("%d",&score);
if (score>100||score<10) {
printf("你输入的分数有误 \n");
}else{
getLevelBySwitch(score);
getLevelByIfElse(score);
}
return 0;
}
/**
* 通过switch进行判断
*
* @paramscore 分数
*/
voidgetLevelBySwitch(int score){
printf("getLevelBySwitch \n");
int flag=score/10;
switch (flag) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:printf("你的成绩:%d, 等级:%c \n",score,'E'); //case 为 0、1、2、3、4、5的时候成绩等级是一样的,利用case的穿透作用,
//直接在case为5的时候进行输出结果。
break;
case 6:printf("你的成绩:%d, 等级:%c \n",score,'D');
break;
case 7:printf("你的成绩:%d, 等级:%c \n",score,'C');
break;
case 8:printf("你的成绩:%d, 等级:%c \n",score,'B');
break;
case 9:
case 10:printf("你的成绩:%d,等级:%c \n",score,'A');//case 为 9和10 的时候情况和上面一样。
break;
default:
break;
}
}
/**
* 通过if else进行判断
*
* @param score 分数
*/
voidgetLevelByIfElse(int score){
printf("getLevelByIfElse \n");
if (score>89) {
printf("你的成绩:%d, 等级:%c \n",score,'A');
}else if (score>79){
printf("你的成绩:%d, 等级:%c \n",score,'B');
}else if(score>69){
printf("你的成绩:%d, 等级:%c \n",score,'C');
}else if (score>59){
printf("你的成绩:%d, 等级:%c \n",score,'D');
}else {
printf("你的成绩:%d, 等级:%c \n",score,'E');
}
}</span>
4 循环结构(while)
循环结构的特点:先判断循环条件,当给定的条件成立时,反复执行某程序段,循环一次判断一次条件,直到条件不成立为为止。给定的条件称为循环条件,反复执行的程序称为循环体。
1)while的格式
while(条件表达式){
循环体;
}
例
计算1+2+3+……+100的值
int i=0;<span style="white-space:pre"> </span>
int sum=0;
// 循环控制条件
while(i<=100){
sum+=I; //大括号内为循环体
i++; //改变i最终使得循环控制条件为假
}
2) 注意
while循环结构的条件
a ,循环控制条件 b 循环体 c 跳出循环的条件(否则会构成死循环)
b ,当一个变量与一个常量进行关系比较时通常把常量写在前面 while(1==a) 3) while后的语句只有一句话时可以省略大括号。
while(i++<=100) sum+=i;
3)while作用域:从while后的大括号开始,到大括号结束。
5 循环结构(do-while)
1) do-while格式
do{
循环体;
}while(循环条件)
2)while和do-while区别
while是当型循环,先判断循环条件,当条件成立时,才执行循环体。
do-while是直到型循环,先执行循环体,再判断循环条件,直到循环条件不成立。
do-while循环不管循环条件是否成立,循环体都会先执行一次
6 循环结构(for)
可以使用域循环次数明确的情况,也可以使用于循环次数不确定的情况。完全可以替代while语句。
1)for循环格式
for(表达式1; 表达式2;表达式3){
循环体;
}
表达式1为循环变量初始化表达式,定义循环变量或者赋初值。如果之前定义了可以省略。
表达式2 为条件表达式,表达式成立时执行循环体,如果循环体中有跳出循环的条件语句,可以省略。
表达式3 循环变量控制表达式,没次执行之后,变量进行更改。可以写在循环体中。
2) 循环嵌套
例
打印9-9乘法表
/*
main.c
9-9乘法表
利用for循环嵌套打印9-9乘法表
*/
#include<stdio.h>
intmain(int argc, const char * argv[]) {
//控制乘数i从1到9
for (int i=1; i<10; i++) {
//控制被乘数j从1到i
for (int j=1; j<=i; j++) {
//打印乘数,被乘数和积
printf("%d * %d =%d\t",i,j,i*j);
}
printf("\n");
}
return 0;
}
3) break 关键字及break语句
break可以用在循环中,用来跳出循环,break用在switch中可以跳出switch而执行switch之后的语句。break在循环中只能向外跳出一层。
4) continue
结束本次循环,继续下次循环。