{ id : 'top-progress-bar', // 请勿修改该值 color : '#77b6ff', height : '2px', duration: 0.2, }

运算符与表达式

运算符的分类

根据不同的分类标准,我们可以将运算符分为两类。

  第一类是按照操作对象的多少进行划分的。我们有下面的表格:

一元运算符 二元运算符 三元运算符
+-正负号 +-加,减*/%乘,除,取余 ?:条件运算
++自加 <<>>左移,右移
--自减 &&||!与或非运算,^异或运算
!非 <>大于,小于
~按位取反 >=<=!=大于/小于等于,不等于
*指针运算符 =,&,|赋值按位,与,或
第二类是按照功能划分。我们可以分为以下内容
算术运算符 赋值运算符 逻辑运算符
-- -- --
+-加减 =赋值 &&与
*/乘除 +=/-=加等减等 ||或
%取余 *=//=乘等除等 !非
++自增 %=取余等 ==等于
--自减 &=,|=,^=,>>=,<<=位运算等 <<左移

表达式的分类

  根据运算符,我们可以把表达式分为以下几类:
  1、算术表达式
  算术表达式由算术运算符和控制运算优先级的括号组成,是进行算术运算的基本表达形式。

      (l+o+v+e)*521/1314.0;
      3.1415926*r;

  2、赋值运算符
  赋值运算符由赋值运算符,算术运算符和操作对象复合而成,最后以'='连接.

      变量=表达式或者数值//在定义时或者定义完成后初始化都可以
      eg:love=5211314;
      变量一=变量二=变量三=变量N=表达式或者值//只能在定义后初始化使用
      eg:l=o=v=e=1314;

  3、逻辑表达式
  一般由逻辑运算符和操作对象组合而成,属于C语言中进行逻辑判断的主要表达形式,也是条件控制语句中的常用的表达式。

      a&&b
      c||d&&m
      !x

  4、关系表达式
  关系表达式一般由关系运算符和操作对象组成,关系运算符也常用与条件控制语句复合使用。

      eg:love>1314
      m==n//注意:等于判断有两个等号

  5、逗号表达式
  逗号表达式有其他运算符和逗号组成,常用于变量定义和for循环中.

      int a,b,c;
      c=(a=3,b=5,a=a+b);

值得注意的是,逗号表达式的值总是等于最后一个表达式的值。
  6、复合表达式
  由其他表达式组成的表达式。

      love=521+b+(c=35/(d=7));

运算符的优先级与结合性

优先级 运算符 名称或含义 使用形式 结合方向 说明
1 [] 数组下标 数组名[常量表达式] 左到右
() 圆括号 (表达式)/函数名(形参表)
. 成员选择(对象) 对象.成员名
-> 成员选择(指针) 对象指针->成员名
++ 后置自增运算符 ++变量名 单目运算符
-- 后置自减运算符 --变量名 单目运算符
2 - 负号运算符 -表达式 右到左 单目运算符
(类型) 强制类型转换 (数据类型)表达式
++ 前置自增运算符 变量名++ 单目运算符
-- 前置自减运算符 变量名-- 单目运算符
* 取值运算符 *指针变量 单目运算符
& 取地址运算符 &变量名 单目运算符
! 逻辑非运算符 !表达式 单目运算符
~ 按位取反运算符 ~表达式 单目运算符
sizeof 长度运算符 sizeof(表达式)
3 / 表达式/表达式 左到右 双目运算符
* 表达式*表达式 双目运算符
% 余数(取模) 整型表达式/整型表达式 双目运算符
4 + 表达式+表达式 左到右 双目运算符
- 表达式-表达式 双目运算符
5 << 左移 变量<<表达式 左到右 双目运算符
>> 右移 变量>>表达式 双目运算符
6 > 大于 表达式>表达式 左到右 双目运算符
>= 大于等于 表达式>=表达式 双目运算符
< 小于 表达式<表达式 双目运算符
<= 小于等于 表达式<=表达式 双目运算符
7 == 等于 表达式==表达式 左到右 双目运算符
!= 不等于 表达式!= 表达式 双目运算符
8 & 按位与 表达式&表达式 左到右 双目运算符
9 ^ 按位异或 表达式^表达式 左到右 双目运算符
10 |按位或 表达式 表达式 左到右 双目运算符
11 && 逻辑与 表达式&&表达式 左到右 双目运算符
12 || 逻辑或 表达式||表达式 左到右 双目运算符
13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符
14 = 赋值运算符 变量=表达式 右到左
/= 除后赋值 变量/=表达式
*= 乘后赋值 变量*=表达式
%= 取模后赋值 变量%=表达式
+= 加后赋值 变量+=表达式
-= 减后赋值 变量-=表达式
<<= 左移后赋值 变量<<=表达式
>>= 右移后赋值 变量>>=表达式
&= 按位与后赋值 变量&=表达式
^= 按位异或后赋值 变量^=表达式
|= 按位或后赋值 变量|=表达式
15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算

  我们简单总结一下常用运算符优先级的记忆方法:

      括号前置自增减>非指针后置自增减>算术运算>关系运算(不等关系>等关系[==,!=])>逻辑运算>赋值运算>逗号运算
      除了第二级别为右结合,其余为左结合(注意区别没有运算结合性的问题).

运算符详解

  1、赋值运算符
  赋值运算符为:‘=’,我们要注意区别‘=’和‘==’的区别,前一个是赋值运算符属于赋值运算,后一个属于关系运算的等关系判断。‘=’并不是等于,而是赋值。
由于‘=’为二元运算符,所以至少需要两个操作数,对于‘=’左侧,我们称之为左值(l-value),并且约定左值必须是变量,常量和表达式不能作为左值.

      eg:a+1=2是错误的,
      5=a;也是错误的.

‘=’右侧为右值,对右值的要求没有左值这么高,他可以是常量,变量,甚至是表达式。
为保证赋值没有出现隐形错误,我们需要保证,赋值运算满足以下两个条件,左右类型相同或者,左精度高于右精度。
对于复合赋值运算符,我们可以通过这一个公式进行相应的转化:
a(fun)=c;=>a=a(fun)c;
不过为了保证程序的可读性与可移植性,一般情况下,我们不采用复合复制的做法,

  2、算术运算符
  这一个运算符,我们分为两部分,第一部分使我们所熟知的+,-,*这三个运算和我们在现实生活中的运算相差无几,另外,我们把/,%单独拿出来阐述.
  我们举一个栗子来说明一下这三个运算符:

      int a=2,b=3,c=5;
      float f=2.1;
      printf("%d,%d,%d",a+b,b-a,a*b);
      printf("%f,%f,%f",a*f,b*f,c&f);

输出结果请大家自己尝试.

  对于'/'与我们现实中唯一的我差别就是数据类型不同造成的误差,例如:3/2,不难算出,答案为1.5,但是计算机处理的时候,输出结果为1.这就是原因所在。
  造成这个问题的原因就在于两个int整型相除,得到的结果仍然为整型,造成了小数部位的舍弃,为了避免这种问题,我们一定要看清楚我们的运算是否类型一致.
当然处理这个问题,我们还有一个方法,就是强制类型转换。例如:3.0/2的结果就为1.5,(float)3/2的结果也为1.5.

  对于'%'运算,我们并不陌生,但是对于这个运算符,我们需要注意这些地方:
 1)'%'不能对实型进行运算,也就是浮点型(float、double)。
 2)'%'的实质为:(假设原数为n,取余的操作数为c)则n%c=n-floor(n/c)*c;
  其中floor为向下去整.
 3)%两边为正整数,那么结果为正整数或者0;
  %两边为负整数,那么结果为负整数或者0;
  %左侧为正整数,那么结果为正整数或者0;
  %左侧为负整数,那么结果为负整数或者0;

3、++,--运算符
  我们分为两类,三个板块,分别问前缀和后缀以及二者的对比及运算的影响。
  前缀:++a、--b特点是先运算在使用。

  例如:
      int a=5;
      printf("%d",++a);
      //结果为6

容易想到,--运算符也是如此。
  后缀:a++,b--的特点是先使用后自增

  例如:
      int a=5;
      printf("%d",a++);
      //结果为5;

对比:

项目 前缀 后缀
优先级
操作对象 合法的左值 合法的左值
结合性 左结合 右结合

 4、关系运算符和关系表达式
  1)运算结果为bool值,即0/1
  2)结合性为自左向右
  3)优先级:不等相关关系大于等相关关系.

      int a=3,b=4,c=5,d;
      d=b>a>c;
      printf("%d",d);

请读者思考这个问题的答案结果是多少,这也是在考试中经常设置的一个坑。

 5、逻辑运算符
  1)逻辑与&&,特点:二者全为真,则表达式为真。
  2)逻辑或||,特点:二者全为假,则表达式为假、
  3)逻辑非!,特点,真假呼唤,真变假,假变真.

注意,逻辑运算具有短路特性,只有前面一个无法确认整个表达式的值时,才会判断下一个。
例如:与如果前为假。那么根据定义,表达式的值必定为假,所以后面的表达式就不需要计算了,同样或也具有短路特性,如果前面为真,那么就不会判断后面的表达式的值。

      int a=0,b=0,c=0;
      c=++a||b++;
      printf("%d,%d,%d",a,b,c);

请大家完成这一个练习.
此外,我们需要记住一个经常使用的判断闰年的程序,核心代码如下:

      if((year%4==0)&&(year%100!=0)||(year%400==0)return 1;

对于位运算符,我们在这里先不做深究。
不过,我们在这里给出一个交换变量的程序,供大家品鉴:

      int a=2,b=3;
      a=a^b;
      b=b^a;
      a=a^b;
      /*
        如果不用异或运算,我们还可以这样写:
        a=a+b;
        b=a-b;
        a=a-b;
      */
      printf("%d,%d",a,b);
  Thanks!
posted @ 2021-01-16 17:31  星空Dreamer  阅读(689)  评论(0)    收藏  举报