操作符(2)

发布于:2022-12-15 ⋅ 阅读:(387) ⋅ 点赞:(0)

目录

6.关系操作符

7.逻辑操作符

8.条件操作符

9.逗号表达式

10.下标引用,函数调用和结构成员访问

11.表达式求值

11.1.隐式类型转化

11.2.算数转换

11.3.操作符的属性


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这种表达式,无法确定唯一的计算路径,会产生错误的结果

在我们平时编写代码时,应避免这种写法,无法确定优先级的情况下,合理使用()


网站公告

今日签到

点亮在社区的每一天
去签到