1、运算符的分类
主要分为三大类:算术运算符、 关系运算符、逻辑运算符、按位运算符。
运算符根据参与运算的操作数的个数分为:
单目运算:只有一个操作数 如 : i++
双目运算:有两个操作数 如 : a+b
三目预算:C语言中唯一的一个,也称为问号表达式 a>b ? 1 : 0
2、运算符的结合性
C语言中各运算符的结合性分为两种:
左结合性(自左至右),如算术运算符,表达式x-y+z;
右结合性(自右至左),如赋值运算符,表达式x=y=z;
3、运算符的优先级
优先级【高到低】:
第一级:圆括号【()】、下标运算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】
第二级:逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++ –】、负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】
第三级:乘法运算符【*】、除法运算符【/】、取余运算符【%】
第四级:加法运算符【+】、减法运算符【-】
第五级:左移动运算符【<<】、右移动运算符【>>】
第六级:关系运算符【< > <= >= 】
第七级:等于运算符【==】、不等于运算符【!=】
第八级:按位与运算符【&】
第九级:按位异或运算符【^】
第十级:按位或运算符【|】
第十一级:逻辑与运算符【&&】
第十二级:逻辑或运算符【||】
第十三级:条件运算符【?:】
第十四级:赋值运算符【= += -= *= /= %= >>= <<.= &= |= ^=】
第十五级:逗号运算符【,】
4、不同类型运算符介绍
4.1、算术运算符
+ 加法运算符
减法运算符,或负值运算符
* 乘法运算符
/ 除法运算符
% 模运算符,或称取余运算符,要求%两侧均为整
4.2、赋值运算符
简单的赋值运算符 = :int a = 10;
复合赋值运算符
+= 加赋值运算符。如a += 3+1,等价于 a = a +(3+1)
-= 减赋值运算符。如a -= 3+1,等价于 a = a -(3+1)
= 乘赋值运算符。如a = 3+1,等价于 a = a *(3+1)
/= 除赋值运算符。如a /= 3+1,等价于 a = a /(3+1)
%= 取余赋值运算符。如a %= 3+1,等价于 a = a %(3+1)
注意:取余运算必须是整数。
4.3、sizeof运算符
1)sizeof的概念
sizeof是C语言的一种单目操作符,如C语言的其他操作符++、–等。它并不是函 数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式 或括在括号内的类型名。操作数的存储大小由操作数的类型决定。
2)siziof几种形式
2.1 sizeof(type);
int main(){
int size =0;
size = sizeof(int);
printf(“size=%d”,size);
}
2.2 sizeof(常量)
int main(){
int size =0;
size = sizeof(3.14);
printf(“size=%d”,size);
}
2.3 sizeof(变量)
int main(){
int size =0;
float f1 = 1.2f;
size = sizeof(f1);
printf(“size=%d”,size);
}
4.4、逗号运算符
把两个表达式连接起来组成一个表达式,称为逗号表达式。
其一般形式为:表达式1, 表达式2,如a = (a+b,c+2);
其求值过程是分别求两个表达式的值,并以表达式2的值作为整个逗号表达式的值。
int main(){
int a=2,b=4,c=6,x,y;
y = (x = a+b,a+c,b+c);
printf(“y=%d”,y);
}
//y=12;
4.5、关系运算符
< 小于运算符
<= 小于等于运算符
大于运算符
= 大于等于运算符
== 等于运算符
!= 不等于运算符
关系运算符都是双目运算符,其结合性均为左结合。
4.6、逻辑运算符
&& 逻辑与运算符
|| 逻辑或运算符
! 逻辑非运算符
注意:
1)逻辑运算的结果也只有两个:成立就为”真”,返回1;不成立就为”假”,返回0
2)短路 与短路:&& 只要第一个条件表达为假那么后面的条件表达就不参与运算了 或短路:|| 只要第一个条件表达式为真那么后面的条件表达式就不参与运算了
4.7、三目运算符
三目表达式的一般形式为:表达式1? 表达式2: 表达式3,它等于:if(a>b) max=a; else max=b;
int main(){
int a=2,b=4,x;
x = a>b?a:b;
printf(“x=%d”,x);
}
//x=4;
关于三目运算符的理解
#include<stdio.h>
int main(int argc, const char * argv[]) {
int a = 3,b = 4 ,result = 0;
result = a>b?10:100;
result = !a?b:a;
printf("result = %d\n",result);
return 0;
}
其实就是真与假的关系,表达式为真(1),执行前面语句,表达式为假(0)执行后面的语句,!a为假(0),故执行后面语句,取a的值,输出结果即为3。
4.8、关于取余运算
1)参与运算的必须是整数,不然会报错
m%n 求余,相当于m/n 获取余数
(1)n等于0 无意义
(2)m等于0 结果为0
(3)m>n 正常求余 如:8%3 = 2
(4)m
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 3,b = 5,result1 = 0,result2 = 0;
// 3/4 + 6/6
result1 = (a++)+(++b); //9
printf("a = %d,b = %d,result1 = %d\n",a,b,result1);
// 5/5 + 6/5
result2 = (++a)+(a++);
printf("a = %d,result2 = %d\n",a,result2);
return 0;
}
return 0;
}
其中在理解计算result2的时候出了一点小差错,result=(++a)+(a++);a=4,最开始理解为,5+4与计算的结果不符合,后来仔细分析了下,自己理解有误,++a中,a值先自加,为5,表达式的值也为5,a++中,这个时候容易出错了,现在a的值已经变为6,表达式的值为5,所以表达式最后的值为10,理解的时候忽略了运算顺序,而不是a同时自加,按照求和运算,从左至右的顺序,使得a值基数发生变化,这一题目应用了自增的运算,同时还有求和,注意运算的优先级。
4.9 算术运算中类型的转换问题
1、类型转换问题
类型转换分为:隐式数据类型转换 和显示数据类型转换
自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。
1)自动转换(隐式转换):
1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转 成long型后再进行运算。
3)所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成 double型,再作运算。
4)char型和short型参与运算时,必须先转换成int型。
5)在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
自动转换遵循以下规则:
char/short →int→unsigned→long→double
例子:
int i=1;
i=i+9.801
按照隐式处理方式,在处理i=i+9.801时,首先i转换为double型,然后进行相加,结果为double 型,再将double型转换为整型赋给I
强制类型转换是通过类型转换运算来实现的。
2)强制类型转换(显示转换):
其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。
其一般形式为: (类型说明符) (表达式)
(float) a;
/* 把a转换为实型 */ (int)(x+y);
/* 把x+y的结果转换为整型 */
int i=1;
i=i+(int)9.801
这时直接将9.801转换成整型,然后与i相加,再把结果赋给i。这样可把二次转换简化为一次转换。
1)类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y 则成了把x转换成int型之后再与y相加了。
2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。
在使用强制转换时应注意以下问题:
1)类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y 则成了把x转换成int型之后再与y相加了。
2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。
在
4.10 关于sizeof运算符
sizeof是C语言的一种单目操作符,如C语言的其他操作符++、–等。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。
用法:sizeof(常量/变量)
1)用于数据类型
sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。
2)用于常量(可以省略括号)
intsize = sizeof(1); size = sizeof(1.1); size = sizeof(1.1f); size = sizeof(‘a’); //4
当sizeof后面的操作数是常量或是变量那么后面小阔号是可以省略的
size = sizeof1;
3)用于变量(可以省略括号)
sizeof使用形式:sizeof(var_name)或sizeofvar_name 变量名可以不用括号括住。如sizeof(var_name),sizeofvar_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。
chara;
size = sizeof(a);
size = sizeofa;
sizeof的使用方法
1)用于数据类型
sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 10,result1=0, result2=0, result3=0, result4=0;
float f1 = 2.3f;
double d1 = 2.3;
char ch = 'a';
result1 = sizeof(a);
result2 = sizeof(f1);
result3 = sizeof(d1);
result4 = sizeof(ch);
printf("result1 = %d,result2 = %d,result3 = %d,result4 = %d\n",result1,result2,result3,result4);
return 0;
}
用来计算数据类型所占用的字节数。
4.11 逻辑运算符的短路问题
与短路:&&
只要第一个条件表达为假那么后面的条件表达就不参与运算了
或短路:||
只要第一个条件表达式为真那么后面的条件表达式就不参与运算了
#include <stdio.h>
int main(int argc, const char * argv[]) {
int a = 3,b = 4,result = 0;
int x,y,z;
x = y = z =0;
// 1 && 1 && 1
result = a && b && 5; //1
// 0 || 0 || 1
// 0 || 1
result = !a || !b || a; //1
// 1 || 0 && 0
// 1 || (0 && 0)
result = a>2 || b<4 && a>5;
// ++x || (++y && z++) x = 1,y=1,z=1;
// 1 || 1 && 1
result = ++x || ++y && z++;
// result ? x,y,z
printf("result = %d\n",result);
printf("x = %d,y = %d,z = %d\n",x,y,z);
return 0;
}
总结:
运算符是告诉编译程序执行特定算术或逻辑操作的符号。
按照功能划分:算术运算符、关系运算符与逻辑运算符、按位运算符。
运算符根据参与运算的操作数的个数分为:
单目运算、双目运算、三目运算
单目运算:只有一个操作数如: i++ ! sizeof
双目运算:有两个操作数如: a+b
三目运算符:C语言中唯一的一个,也称为问号表达式a>b ? 1: 0
//———优先级与结合性———–//
优先级:15级在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。
结合性: C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。
小技巧加括号
特点:
什么样数据类型相互运算结果还是什么数据类型
//———算术运算符———–//
结合性:从左到右
优先级:
(1) * / % 优先级大于+ -
(2) 优先级相同则左结合计算
求余运算符
2)运算结果的正负性取决于第一个运算数,跟后面的运算数无关
//———类型转换———–//
类型转换分为:隐式数据类型转换(自动转换) 和显示数据类型转换(强制装换–强转)(类型说明符) (表达式)
显示类型转换的方法是在被转换对象(或表达式)前加类型标识符,其格式是: (类型标识符)表达式
在使用强制转换时应注意以下问题:
1)类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y 则成了把x转换成int型之后再与y相加了。
2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。
//———表达式———–//
将同类型的数据(如常量、变量、函数等),用运算符号按一定的规则连接起来的、有意义的式子称为表达式。
例如:算术表达式、逻辑表达式、字符表达式等。
表达式可以是常量也可以是变量或算式,在表达式中又可分为:算术表达式、逻辑表达式和字符串表达式。
表达式的特点:
表达式是一个意义的式子,所以一定有返回值
//———赋值表达式———–//
赋值运算符记为“=”,由“=”连接的式子称为赋值表达式。
其一般形式为: 变量=表达式
“=”定义为运算符,从而组成赋值表达式。
凡是表达式可以出现的地方均可出现赋值表达式。
//———赋值表达式语句———–//
在赋值表达式后面添加一个分号,构成了一个语句,称为赋值语句。
//———复合赋值表达式语句———–//
在赋值符“=”之前加上其它二目运算符可构成复合赋值符。
赋值运算符优先级排名14位,仅仅高于“,”运算符。
//———自增自减运算符———–//
1)前缀表达式:++x, –x; 其中x表示变量名,先完成变量的自增自减1运算,再用x的值作为表
达式的值;即“先变后用”,也就是变量的值先变,再用变量的值参与运算。
2)后缀表达式:x++, x–; 先用x的当前值作为表达式的值,再进行自增自减1运算。即“先用
后变”,也就是先用变量的值参与运算,变量的值再进行自增自减变化。
注意:不管“++”在前还是在后,最后变量的值都会+1
3)自增、自减运算只能用于单个变量,只要是标准类型的变量,不管是整型、实型,还是字符型变量等,但不能用于表达式或常量。
优先级很高右结合
学习心得:通过本章小结的只是了解了运算符的概念及运算,各类运算符的规则及其注意要点,对以后编程算法思想有很大的帮助,特别是逻辑表达式,自增自减的运算,在后面的学习中会广泛要用到,要充分理解其中的思想并灵活应用。