目录
前言
在C语言和单片机开发中,运算符是经常会用到的东西,学会运算符不仅可以让代码的可读性变好,也是成为高手必须要学会的东西,本篇文章我会详细介绍几个常用的运算符的使用方法。
1.1 算术运算符
+ - * / %
加减乘除与取余符号,其中需要注意的是除了 % 运算符外其他的运算符即适用于浮点型同时也适用于整数类型,而当 / 运算符的两个操作数都是整数时,它执行整数运算,其他情况下则执行浮点数除法(如果整数运算的任一操作数为负数,则运算结果由编译器决定),% 运算符只能将两个整数作为操作数,把左操作数除以右操作数,返回值为余数。
1.2 移位运算符
<< >>
移位运算符顾名思义就是将一位数左移或者右移,在左移位中,值最左边的数被丢弃,右边多出来的则用0补齐。
例如 a=0xE2<<3 此时a的值是0x18,我们从二进制的角度来分析0XE2(1110 0011)左移三位变成(0001 1000)左边三位被丢出去了,而右边填入0补位。
而右移位则分为逻辑运算和算数运算,左边移入的位由原先该值的符号位决定,如果运算之前的符号位为1则填入1,如果为0则填入0,这样能保证原数的正负形式不变,例如值10010110右移两位,逻辑运算的结果为00100101,但算数移位的结果为11100101,在左移中算数运算和逻辑运算是相同的,它们只是在右移中不同,而且只有当操作数为负数时才不一样
哈哈有没有人会想到移位负数的情况呢 例如 a << -5 难道结果会是右移五位吗,但结果是左移27位数,这类移位行为是未定义的行为,会发生什么是不可预测的,我们应该尽量避免这种行为。
1.3 位运算符
& | ^
这三个位运算符分别位 和& 或 | 异或^ 简单介绍一下,当两个位进行 和& 操作时,如果两个位都是1,则结果为1,否则结果为0,一假必假,当两个位进行 或 | 操作时两个位都是0,则结果为0,否则结果为1 ,一真必真,最后两个位进行 异或^ 运算时,如果两个位不同,结果为1,如果两个位相同则结果为0,1和0异或为1,0和0或者1和1异或为0,当执行位运算时要求操作数都为整数,假定变量a的二进制数为00101110,变量b的二进制值为01011011。a&b的结果为00001010,a|b的结果为01111111,a^b的结果为01110101
1.4 赋值操作
赋值只用一个等号表示,而等于用两个等号表示,由于赋值的优先级很低,通常是先进行运算之后再进行赋值操作,X=Y+3 通常是Y+3运算完之后再赋值给X
+= -= *= /= %=
<<= >>= &= ^= |=
以上叫做复合赋值符,我们只讨论+=一种运算符,其他的运算符与它非常相似只是各自的功能不同而已,a += x 我们可以理解为 a = a + (x) 注意括号,它们确保表达式在完成加法之前先保证后面的值被完整求值,即使它内部包含着优先级低于加法的运算符
复合赋值运算符的优点在于它使源码的可读性与书写更加容易,更方便判断,基于这些理由也应该多使用复合赋值运算符。
1.5 单目运算符与关系运算符
~ -- + * !
++ - & sizeof (数据类型)
让我们来逐个介绍单目运算符如何使用
首先 !运算符是对它的操作数进行逻辑反操作,如果操作数为真,则结果为假,例如变量a的值为0,则a = !a 则a变量的结果为 1,这个操作符实际上产生一个整数结果,0或1
而 ~ 运算符则是按位取反,操作数原先的1变成0,0变成1,例如变量a的值为00101101,则a =~ a的结果为11010010
在单片机开发中需要某些变量在高低电平中切换来达到我们想要的效果,而这时候我们哪种运算才是正确切换高低电平的行为呢 变量a为0,a = !a , a = ~a 答案是第一种,第一种只针对于1和0之间的切换,而第二种的结果是 11111111 从二进制切换成十进制显然不是1
+ 与 - 就是正常的数学运算中的加减,不多赘述了
&运算符是产生它操作数的地址,例如,下面的语句声明了一个整型变量和一个指向整型变量的指针,接着&运算符取变量a的地址,并把它赋值给指针变量
int a,*b;
......
b = &a;
这个例子说明了如何把一个现有的变量的地址赋值给一个指针变量
*运算符是间接访问运算符,它与指针一起使用,用于访问指针所指向的值,在前面的例子中的赋值操作完成后,表达式b的值是变量a的地址,但表达式*b的值则是变量a的值
sizeof它可以认为成一个关键字,但实际上他是一个运算符,它的作用是判断操作数的类型长度,以字节为单位,操作数既可以是个表达式,也可以是两边加上括号的类型名,举两个例子
sizeof (int) sizeof x
第一个表达式返回整型变量的字节数,第二个表达式则返回变量x所占的字节数、
(类型)运算符则被成为强制类型转换,适用于两个整数变量相除,赋值给另外一个整形变量,但小数点后面的几位保留不下来了,就可以将赋值的左值强制类型转换成浮点型用于保存小数点,也可以利用强制类型转换将浮点型四舍五入成整数类型 (float)a 就将这个变量a变成浮点类型了
++与--就非常简单了,当a++时,先取a的值再进行加一的操作,而++a则是先对a进行加一,再取a的值,--也是同理
然后我们的单目运算符就介绍完了,接下来介绍关系运算符
< > <= >= != ==
前四个功能一看便知,用来比大小的,而 != 则是C语言中“不等于”的表达形式,=为赋值操作,那什么为等于操作呢,答案就是两个等于号 ==,需要提醒一下,关系运算符的运算结果只会是0和1,他们通常用于if或者while语句中,作为测值表达式请记住他们的工作方式
1.6 逻辑运算符
逻辑运算符有 && 和 || ,这两个运算符看上去有点类似位运算符,但他们的具体操作却大相径庭,&&两个操作数为真他才为真,||当它两个操作数为假时他才为假,在单片机开发中通常在if或者while中卡一个条件使用,但他们的意思是差不多的,来判断两个表达式是不是符合要求,if(a==0 && b==1),这就是判断两个值是不是都符合条件,就不用写两个if语句了,另外一个也是同理
1.7 优先级
C语言的运算和现实中的四则运算一样都是存在优先级的,在开发中一定要注意求值的顺序,优先级不用刻意的去记,但要注意好括号的使用,在你优先要求的值外面加上括号,有些优先级等使用多了自然就知道它比较靠后了,例如说赋值和逻辑运算,他们的优先级就属于最低的一档了