操作符认识 -- 全攻略
*/ --------------------------------------------------------------------------------------*/ 出自: 快乐编程 https://hi.bccn.net/108519
*/ 作者: neverTheSame E-mail:zhaoxufeng9997@ QQ:475818502
*/ 时间: 2008-6-1
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
操作符认识 -- 全攻略
高级语言中提供了许多不同的操作符,这些操作符给程序设计带来极大地方便,同时给操作符之间的运算增加了很大的复杂性。
特别是在看其他程序员写的代码时,有些程序员为了体现自己的技术(当然,也有对程序设计的需要),对操作符的运用非常复杂。
因此,作为一名程序员就必要清楚认识操作符之间的关系。当然,在自己的程序设计中,为了提高程序的效率也有必要清楚
认识操作符之间的关系。
大家都知道:高级语言中为操作符分了不同的优先级别和结合方向。要知道操作符之间是怎么进行运算的,就必须了解它们之间
优先级及结合方式。
例如:void *fun(); 与 void (*fun)();
int *array[3];与 int (*array)[3];
(int*)struct_var.member;
(a+=b,(++b),a--) 的结果是什么?
-1*-2 是否正确,如果正确,结果又是什么?
...
下面,就为大家一一讲解。
步骤:
一、分清所有操作符的优先级,先从操作符优先级别最高的操作符入手。
二、当有二个以的操作符在同一优先级别上,就从该级别的操作符的结合方向入手。
三、重复步骤一和二,个个击破的方式来解决问题。
大家先看一下,C语言中的操作符优先级及结合方向列表:
----------------------------------------------------------------------------
| Priority OprCharacter OprObjNUM CombDirectory
----------------------------------------------------------------------------
| ()
| []
| 1 -> From Left To Right
| .
|---------------------------------------------------------------------------
| !
| ~
| ++
| --
| 2 - 1 From Right To Left
| (Force TYPE Converted)
| *(Pointer)
| &
| sizeof
|---------------------------------------------------------------------------
| *(Multiply)
| 3 / 2 From Left To Right
| %
|---------------------------------------------------------------------------
| 4 + 2 From Left To Right
| -
|---------------------------------------------------------------------------
| 5 << 2
| >>
|---------------------------------------------------------------------------
| <
| <=
| 6 > 2 From Left To Right
| >=
|---------------------------------------------------------------------------
| 7 == 2 From Left To Right
| !=
|---------------------------------------------------------------------------
| 8 & 2 From Left To Right
|---------------------------------------------------------------------------
| 9 ^ 2 From Left To Right
|---------------------------------------------------------------------------
| 10 | 2 From Left To Right
|---------------------------------------------------------------------------
| 11 && 2 From Left To Right
|---------------------------------------------------------------------------
| 12 || 2 From Left To Right
|---------------------------------------------------------------------------
| 13 ? : 3 From Right To Left
|---------------------------------------------------------------------------
| =
| +=
| -=
| *=
| /=
| 14 %= From Right To Left
| >>=
| <<=
| &=
| ^=
| |=
|---------------------------------------------------------------------------
| 15 , From Left To Right
|---------------------------------------------------------------------------
参照上表,我们来分析解决上面提供的问题。
1、void *fun(); 与 void (*fun)();
先分析一下“void *fun();”,从语句在可以了解到有二个操作符*、()。
()的优先级高于*,因此fun与()结合形成函数名,void与*结合形成函数的返回值类型为指向void类型的指针。
再分析“void (*fun)();”,从语句在可以了解到有二个操作符*、()。因()的优先级高于*,所以先运行与
()有关的操作。然而,语句在有二个()操作符,而()的结合方式是从左向右的方式,因此,先进行(*fun)的
操作而形成指针的形式,再与第二个()运算形成了指向函数的指针。
2、int *array[3];与 int (*array)[3];
先分析一下“int *array[];”,从语句在可以了解到有二个操作符*、[]。
[]的优先级高于*,array与[]结合形成了数组,再int与*结合就形成数组的元素为int*类型。
再分析“int (*array)[3];”,从语句在可以了解到有三个操作符*、()、[]。
()、[]的优先级高于*,而()、[]属于同一级别,这个级别结合方向是从左向右。
因此,首先作()内的操作:(*array),形成了一个指针,再与[]结合形成数组,再与int结合形成了数组元素为int型。
注意,这时的array指向的是一个指向含有3个整型数的一维指针,也就是array是一个指向p[3]的指针。
3、(int*)struct_var.member,从语句中可知,有二个操作符:强制类型转换符"(int*)"与成员操作符"."。
从表中我们可知成员操作符的优先级高于强制类型转换符。因此,先进行的是struct_var.member运算,再
进行强制类型转换,相当于(int*)(struct_var.member)。
4、(a+=b,(++b),a--),从表达中我们可以看出有'()'、'+='、'++'、'--'、','操作符。从中这么多的操作符中我们怎么了解表达式的运算呢?
是不是先执行"(++b)"里的内容呢?答案:不是。因为最外面的括号内是一个逗号运算符,而"(++b)"是逗号运算符内部操作符,因此先按
照逗号操作符的结合方式从左至右。如果你不相信你可以这样做:(a+=b,(printf("a=%d\n",a)),(++b),a--),验证一下结果。了解到这里
我相信大家就可以很容易写出表达式的运算结果。
5、-1*-2,这个表达式是否正确定呢?答案:正确。从表达式中可以看出有'-'、'*'这个两个操作符。从表可以看出'-'的优先级高于'*'。
因此,-1*-2就相当于(-1)*(-2)。这样表达式很明显正确。
建议:大家在进行很复杂的操作符运算的时侯,建议用括号将相关操作分隔,如(int*)struct_var.member--》(int*)(struct_var.member)。
在编程中,我建议大家不要采用很复杂的操作符来进行运算,即使使用很复杂的操作符来运算,也要用括号将其分隔开来,以便阅读。