目录
1. 表达式
用运算符将运算对象连接起来的式子,这种式子称为表达式(常量也是一种表达式)。如下代码所示:
x = 10;
x = y;
sum = x + y
......
2. 运算符
运算符是数据运算的一种操作规则,对数据操作的一种方式。
(1)操作数:运算符操作的对象称为操作数;
(2)优先级:指的是不同的运算符同时出现的时候,运算符先后计算顺序;
(3)结合性:当运算符得优先级相同得时候,不同运算符同时出现得时候,运算符先后计算得顺序;
- 右结合:从右往左
- 左结合:从左往右
(4)按照操作对象的多少可分为单目运算、双目运算、三目运算。
- 单目运算符:运算符操作数得个数为1个 ++a a-- &a
- 双目运算符:运算符得操作数得个数为2个 a + b a=b
- 三目运算符:运算符得操作数得个数为3个,条件运算符,唯一得三目运算符 ?:
- 优先级:单目运算符 > 双目运算符 > 三目运算符
- 三目运算符:运算符得操作数得个数为3个,条件运算符,唯一得三目运算符 ?:
- 双目运算符:运算符得操作数得个数为2个 a + b a=b
2.1. 运算符分类
(1)特殊运算符:[](下标运算符)、()(圆括号)、->(指向结构体成员运算符)、.(结构体成员运算符)。
- 优先级:第一优先级
- 结合性:从左到右
(2)算术运算符:+(加)、-(减)、*(乘)、/(除)、%(求余)。
规则:
1)对于除法运算符,如果两边都是整型数据,最终结果会取整;如果两边有一边是实型数据,最终的结果会保留准确值
10 / 4 ----> int / int ---- int 计算结果 取整
10.0 / 4 ----> double / int ---- double 计算结果 保留准确值
2)对于取余运算符,要求两边必须为整型数据
- 优先级:(* / %) >(+ -)
- 结合性:从左到右
(3)关系运算符:> 、>= 、< 、<= 、== 、!=。
- 优先级:(> >= < <= ) > (== !=)
- 结合性:从左到右
(4)逻辑运算符:&&(与)、||(或)、!(非);返回逻辑值,“真”值用1表示,“假”值用0表示。
1.逻辑表达式值:
1)逻辑值:数据是非零值,则逻辑值为真,如果数据为零值则逻辑值为假
2)逻辑表达式的结果值:逻辑值为真,逻辑表达式的值为1;逻辑值为假,逻辑表达式的结果为0
2.逻辑与 &&
1)表达式: 表达式1 && 表达式2
2)规则:全真为真,有假为假
3)原理: 如果表达式1的逻辑值为假,则程序不会去执行逻辑表达式2,整个逻辑&&表达式的值为假;
如果表达式1的值为真,则接着计算表达式2的值,表达式2值为真,整体为真对应的数值为1;表达式2值为假,整体为假对应的数值为0
3.逻辑或 ||
1)表达式: 表达式1 || 表达式2
2)规则:有真为真,全假为假
3)原理: 如果表达式1的逻辑值为真则程序不会去执行逻辑表达式2,整个逻辑||表达式的值为真
如果表达式1的值为假,则继续计算出表达式2的值,为真,整体为真;如果表达式为假,则整体为假。
4.逻辑非 !
1)表达式: !表达式
2)规则:真变假,假变真
3)原理:先计算表达式的值,如果为非零值,则逻辑值为真,则逻辑非表达式的值为假
!0 -- 1
!907 -0
- 优先级:! ---> && ---> ||
- 结合性: !从右到左;&& ||:从左到右
(5)按位运算符,此运算符在嵌入式系统中运用比较广泛;使用位运算符需要将数据转换为二进制,再进行运算。
- 按位取反~:0变1,1变0;
规则: 0 变1 , 1 变0
unsigned char ch = 0X67; //0110 0111
ch = ~ch : //1001 1000
unsigned int b = 0X89; //0000 0000 0000 0000 0000 0000 1000 1001
b = ~b //1111 1111 1111 1111 1111 1111 0111 0110
- 按位左移<< 和 右移>>;
规则:整体左移,高位溢出,低位补零
unsigned char ch = 0X67; //0110 0111
ch = ch << 3; // 0110 0111 << 3
// 0 0111 000
左移:如:0000 1010 << 3 ---> 0101 000;高位溢出,地位补0;
右移:如:有符号数:1001 1101 >> 3 ---> 1111 0011;
无符号数:1101 0011 >> 3 ---> 0001 1010。
即有符号数右移,低位溢出,高位补符号位;无符号数右移,低位溢出,高位补0.
- 按位与&:x & 0 == 0(清零)、x & 1 == x(保持某位不变);
规则:有0为0,全1为1
unsigned int a = 0x78; //0111 1000
unsigned int b = 0x89; //1000 1001
a & b ==> 0000 1000
- 按位异或^:x ^ 1 == -x (相同位0,不同为1);
规则:相同为0,不同为1
1^1 = 0;
1^0 = 1;
0^0 = 0;
0^1 = 1;
- 按位或|:x | 0 == x(保持某位不变)、x | 1 == 1(置1);
规则:有1为1,全0为0
unsigned int a = 0x78; //0111 1000
unsigned int b = 0x89; //1000 1001
a | b ==> 1111 1001
- 结合性:~从右到左;其他从左到右;
(6)自增自减运算符:自增/自减单独使用时,前后置大小一样。
- 自增:++;
- 前置自增:++q;p先自加1,后参与运算;
- 后置自增:q++;p先参与运算,后自加1;
- 自减:-- (跟自增同理)。
#include<stdio.h>
int main()
{
int a = 1,b ;
int c = 1,d ;
b = ++a; // a = a + 1; b = a
d = c++; // d = c; c = c + 1;
printf("a = %d,b = %d\n",a,b);
printf("c = %d,d = %d\n",c,d);
//如果单独使用自增减运算符,而不参与其他表达式的计算
//不管是前置还是后置,最终都会发生加1或者减1的操作
a++; //a = a + 1;
++a; //a = a + 1;
//后置自增, 是在一条语句结束之后(通常以分号作为判断的依据)自增
a = 10;
if(a++ > 9)
{
printf("if语句内: a = %d\n",a);
}
printf("if语句外: a = %d\n",a);
a = 10, b =20, c = 30; //逗号表达式
printf("%d, %d, %d\n",a+=10,b+=10,a+b+c);
//20 30 60 从右往左
//a+=10 ---> a = a + 10;
//b+=10 ---> b = b + 10
return 0;
}
(7)赋值运算符:=、+=、-+、/=、*=、%=、&=、|=、^=、<<=、>>=。
例如:
1. 格式: 变量名 = 表达式; 先计算表达的值,然后在赋值给左边的变量。
int a ;
a = 799; 或 a = 10 / 4;
2. 注意: 只能对变量进行赋值,左边必须是变量
a+b = 10 //错误
3. 说明:
1) 一般进行同类型赋值,左边的变量的类型和右边表达式所得结果的类型保持一致
int a ; a = 10 / 4; //int = int
2) 左边变量的类型和右边表达式所得结果的类型不一致,则在赋值的过程中发生数据类型的转换
转换为左边变量的类型为主
int b ; b = 10.43 + 30; //int = double 取整
double x; x = b = 10.43 + 30; //double = int = double
3) 基本数据类型和构造数据类型不能相互赋值,
- 结合性:从右到左
(8)条件运算符:(条件表达式)?表达式1 :表达式2;C语言中唯一的三目运算符。
执行原理:先计算条件表达式,如果条件成立,则表达式1的值是整个条件表达式的值,如果条件不成立,则表达式2的值是整个条件表达式的值。
1. 已知int x ,y;寻找两个变量中的最大值
if(x > y)
{
max = x;
}
else
{
max = y;
}
等换:max = (x > y)? x:y
2. 已知 x,y,z,求三个变量中的最大值
if(x > y && x > z)
{
max = x;
}
else if(y > x && y > z)
{
max = y;
}
else
{
max = z;
}
等换:
max = (x > y)? x:y
max = (max < z )?z:max
(9)指针运算符:*(取值)、&(取地址)。
(10)求字节运算符:sizeof();用于计算数据类型所占的字节数。
(11)逗号运算符:,;优先级最低;从右到左。