目录
6.关系操作符
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
关系操作符是双目操作符,,用来比较俩个操作数的大小关系
字符串判断相等:"abcdef" == "abcd",比较的是俩个字符串首元素的地址
一般strcmp函数专门用来比较字符串的的大小,比较的是对应位置上字符的大小,不是比较字符串长度,以下为strcmp函数的功能表
str1[ ] = "appld"
str2[ ] = "apple"
strcmp函数比较的是对应位置上字符的大小,前四个字符相同,第五个字符在str1中为d,在str2 中为e,d的ASCII码值为100,e的ASCII码值为101,所以返回-1,第一个不匹配的字符在str1中的值比在str2中的值小
7.逻辑操作符
&& | 逻辑与 |
|| | 逻辑或 |
注意区分按位与,按位或,逻辑与和逻辑或只关心真假
分析:
i = a++ && ++b && d++;
因为a=0,为假,所以后边不执行,只执行a++
所以i=0,a=1;
i = a++ || ++b || d++;因为a=1,为真,所以后边不执行,执行a++
所以i=1,a=2;
综上:i=1,a=2,b=2,c=3,d=4;
8.条件操作符
exp1 ?exp2 :exp3 | 判断表达式1,为真执行表达式2,为假执行表达式3 |
a > b ? a : b
如果a>b,输出a,否则输出b
9.逗号表达式
exp1,exp2,...,expN | 表达式的结果是最后一个表达式的结果 |
10.下标引用,函数调用和结构成员访问
[ ] | 下标引用 |
() | 函数调用 |
—> | 结构成员访问 |
下标引用操作符:
用于数组的下标引用,例:arr[3]
[ ]只是一个操作符,有俩个操作数
函数调用操作符:
用于函数调用,例:Add(5,4)
函数调用操作符有三个操作数,至少有一个函数名
结构成员访问:
访问一个结构体的成员,一般有俩种写法:结构体.成员 或 结构体—>成员
11.表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定
同样,有些表达式的操作数在求值的过程中可能需要转换成其他类型
11.1.隐式类型转化
C的整形算数运算总是至少以缺省整形类型的精度来进行
为了获得这个精度,表达式中的字符和短整形操作数在使用之前被转化为普通整形,这种转化称为整形提升
整形提升的意义:表达式的整形运算要在CPU的相应运算器件内执行,CPU内整形运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器长度
即使俩个char类型相加,在CPU执行时实际上也要先转化为CPU内整形操作数的标准长度
通用CPU是难以直接实现俩个8比特字节直接相加运算,所以,表达式中各种长度可能小于int长度的整型值,都必须先转化为int或unsigned int,然后才能送进CPU去执行运算
举个栗子:
//char c1 = 3;
//00000000 00000000 00000000 00000011
//截断为8个比特位:00000011
//char c2 = 127;
//00000000 00000000 00000000 01111111
//截断为8个比特位:01111111
//char c3 = c1+c2;
//整形提升:按照变量的数据类型的符号位来提升的,正数高位补0,负数高位补1
c1:00000000 00000000 00000000 00000011
c2:00000000 00000000 00000000 01111111
c3:00000000 00000000 00000000 10000010
//截断:10000010
//整形提升:11111111 11111111 11111111 10000010(补码)
11111111 11111111 11111111 10000001(反码)
10000000 00000000 00000000 01111110(原码) -126
printf(“%d\n”,c3);
//打印整形 -126
注意:
1.unsigned int == int
2.unsigned short == short
3.unsigned char == char(大多数编译器)
11.2.算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行,下面的操作体系为寻常算数转换
- long double
- double
- float
- unsigned long int
- long int
- unsigned int
- int
以上操作数的类型由上到下级别依次降低,如果某个操作数的类型在上面的列表中排名较低,那么首先转换为另一个排名较高的类型后执行运算
注意:
算数转换要合理,不然会存在潜在的问题
例:
float f = 3.14;
int num = f;
//隐式转换,会产生精度丢失
11.3.操作符的属性
复杂表达式求值的影响因素
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序
是否控制求值顺序:&& || exp?exp:exp ,注意这四个操作符控制求值顺序
例:0&&1 当&&的第一个操作数为假时,整个表达式结果就为假,后边表达式不会执行
两个相邻的操作符先执行哪一个,取决于它们的优先级,如果优先级相同,取决于它们的结合性
int a = 1;
int b = 2;
int c = 3;
int d = a + b*c;
int e = a + b + c;
在表达式d = a + b*c中,因为*比+的优先级高,所以先计算b*c,结果再和a相加
在表达式e = a + b + c中,都是加法,优先级相同,所以看结合性,+的结合性是从左往右,所以依次从左往右依次计算即可
注意:
像 a*b + c*d +e*f 和 c+ --c这种表达式,无法确定唯一的计算路径,会产生错误的结果
在我们平时编写代码时,应避免这种写法,无法确定优先级的情况下,合理使用()