【C语言】符号优先级

  一. 问题的引出

  今天看阿里的笔试题,看到一个非常有意思的题目,但是很容易出错。

  题目:如下函数,在32bit系统foo(2^31-3)的值是:

Int foo(int x)
{

return x&-x;

}

  解答:如果想要答对这道题目,首先要清楚C语言中符号的优先级别,负号(-)的优先级高于^,所以2^31-3=2^28,还有一个陷阱就是C语言中认为^为异或运算而不是幂函数,所以2^28=30,然后计算30 & -30得出结果。又因为计算机内存中的数据是以二进制的补码形式存在的,所以参与位运算的数都是以补码形式出现。所以需要把30和-30转换为补码之后再进行按位与运算,结果为2。我们还可以用程序看看执行过程中产生的x的值如下:

#include <iostream>
using namespace std;

int foo(int x){
    cout << "x = " << x << endl;
    return x & -x;
}

void main(){
    int res = 0;
    res = foo(2^31-3);
    cout << "res = " << res << endl;
}

  二. 字符的优先级


优先级


运算符


名称或含义


使用形式


结合方向


说明


1


[]


数组下标


数组名[常量表达式]


左到右


()


圆括号


(表达式)/函数名(形参表)


.


成员选择(对象)


对象.成员名


->


成员选择(指针)


对象指针->成员名


2


-


负号运算符


-表达式


右到左


单目运算符


(类型)


强制类型转换


(数据类型)表达式


++


自增运算符


++变量名/变量名++


单目运算符


--


自减运算符


--变量名/变量名--


单目运算符


*


取值运算符


*指针变量


单目运算符


&


取地址运算符


&变量名


单目运算符


!


逻辑非运算符


!表达式


单目运算符


~


按位取反运算符


~表达式


单目运算符


sizeof


长度运算符


sizeof(表达式)


3


/



表达式/表达式


左到右


双目运算符


*



表达式*表达式


双目运算符


%


余数(取模)


整型表达式/整型表达式


双目运算符


4


+



表达式+表达式


左到右


双目运算符


-



表达式-表达式


双目运算符


5


<<


左移


变量<<表达式


左到右


双目运算符


>>


右移


变量>>表达式


双目运算符


6


>


大于


表达式>表达式


左到右


双目运算符


>=


大于等于


表达式>=表达式


双目运算符


<


小于


表达式<表达式


双目运算符


<=


小于等于


表达式<=表达式


双目运算符


7


==


等于


表达式==表达式


左到右


双目运算符


!=


不等于


表达式!= 表达式


双目运算符


8


&


按位与


表达式&表达式


左到右


双目运算符


9


^


按位异或


表达式^表达式


左到右


双目运算符


10


|


按位或


表达式|表达式


左到右


双目运算符


11


&&


逻辑与


表达式&&表达式


左到右


双目运算符


12


||


逻辑或


表达式||表达式


左到右


双目运算符


13


?:


条件运算符


表达式1? 表达式2:表达式3


右到左


三目运算符


14


=


赋值运算符


变量=表达式


右到左


/=


除后赋值


变量/=表达式


*=


乘后赋值


变量*=表达式


%=


取模后赋值


变量%=表达式


+=


加后赋值


变量+=表达式


-=


减后赋值


变量-=表达式


<<=


左移后赋值


变量<<=表达式


>>=


右移后赋值


变量>>=表达式


&=


按位与后赋值


变量&=表达式


^=


按位异或后赋值


变量^=表达式


|=


按位或后赋值


变量|=表达式


15


,


逗号运算符


表达式,表达式,…


左到右


从左向右顺序运算

  说明:同一优先级的运算符,运算次序由结合方向所决定。

  三. 优先级口诀

  括号成员第一;         括号运算符[]() 成员运算符.  ->

  全体单目第二;         所有的单目运算符比如++ -- +(正) -(负) 指针运算*&

  乘除余三,加减四;      这个"余"是指取余运算即%

  移位五,关系六;       移位运算符:<< >> ,关系:> < >= <= 等

  等于(与)不等排第七;   即== !=

  位与异或和位或;       这几个都是位运算: 位与(&)异或(^)位或(|)

  "三分天下"八九十;

  逻辑或跟与;           逻辑运算符:|| 和 &&

  十二和十一;           注意顺序:优先级(||)  底于 优先级(&&)

  条件高于赋值,          三目运算符优先级排到 13 位只比赋值运算符和","高

  逗号运算级最低!       逗号运算符优先级最低

  参考资料

  [1] http://blog.chinaunix.net/uid-23577393-id-2733234.html

  [2] http://blog.csdn.net/zhlfox2006/article/details/11854799

  [3] http://www.aichengxu.com/article/c%E8%AF%AD%E8%A8%80/31501_11.html

时间: 2024-12-13 03:16:28

【C语言】符号优先级的相关文章

C语言符号优先级

优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -> 成员选择(指针) 对象指针->成员名 2 - 负号运算符 -表达式 右到左 单目运算符 (类型) 强制类型转换 (数据类型)表达式 ++ 自增运算符 ++变量名/变量名++ 单目运算符 -- 自减运算符 --变量名/变量名-- 单目运算符 * 取值运算符 *指针变量 单目运算符 & 取地址运算符 &

C语言运算符优先级存在的问题

C语言中的符号重载(C专家编程,2.3误做之过,P38) 优先级问题 表达式 人们可能误以为的结果 实际结果 .的优先级高于* ->操作符用于消除这个问题 *p.f p所指对象的字段f (*p).f 对p取f偏移,作为指针,然后进行解除引用操作 *(p.f) []高于* int *ap[] ap是个指向int数组的指针 int (*ap)[] ap是个元素为int指针的数组 int *(ap[]) 函数()高于* int *fp() fp是个函数指针,所指函数返回int int(*fp)() f

JS-补充-json,符号优先级

====JSON.parse JSON.parse(text,callback(k,v)) 方法解析一个JSON字符串 返回值:对象(对应的text文本) 参数: text要解析的json字符串 callback(k,v)可选的回调函数//规定了原始值在被返回之前如何被解析改造 //例1: JSON.parse('{}');              // {} JSON.parse('true');            // true JSON.parse('"foo"');   

C 语言运算符优先级

每当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖! C语言运算符优先级 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- -> 成员选择(指针) 对象指针->成员名 -- 2 - 负号运算符 -表达式 右到左 单目运算符 ~ 按位取反运算符 ~表达式 ++ 自增运算符 +

C语言运算符优先级

C语言运算符优先级 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- -> 成员选择(指针) 对象指针->成员名 -- 2 - 负号运算符 -表达式 右到左 单目运算符 ~ 按位取反运算符 ~表达式 ++ 自增运算符 ++变量名/变量名++ -- 自减运算符 --变量名/变量名-- * 取值运算符 *指针变量 & 取地址运算符 &

c语言操作符优先级

运算符 结合性 () [] -> . 自左至右 ! ~ ++ -- - (type) * & sizeof 自右至左 * / % 自左至右 + - 自左至右 << >> 自左至右 < <= > >= 自左至右 == != 自左至右 & 自左至右 ^ 自左至右 | 自左至右 && 自左至右 ||  自左至右 ?: 自右至左 = 自右至左 , 自左至右 1.优先级最高的并不是真正意义上的运算符,包括数组下标,函数调用操作符和

被C语言操作符优先级坑了

今天有一个枚举的题目的代码是这样的: 重点在于maxXor这个函数的实现,枚举两个数字,其中maxr保存了最大值的 i 异或 j , 可是这个程序执行结果大大出乎意外-_-. 然后就把 i 异或 j 的结果临时保存在int,进行比较,程序正确的执行了.原来是被操作符优先级坑到了.位操作的优先级比比较操作符的优先级更低. #include <map> #include <set> #include <list> #include <cmath> #includ

C语言运算符优先级列表(超级详细的---转载加自己习题)

转载于:http://www.jb51.net/article/37282.htm 每当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖! C语言运算符优先级 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- -> 成员选择(指针) 对象指针->成员名 -- 2 - 负号运算

C语言运算符优先级及结合性

今天去翻了下C语言运算符的优先级和结合性,发现当初学习的时候就没认真记住,惭愧.发现一篇讲得不错的文章,编辑了下转来供以后翻阅. C语言运算符优先级表(由上至下,优先级依次递减) 运算符 结合性 () [] -> . 自左向右 ! ~ ++ -- - (type) * & sizeof 自右向左 * / % 自左向右 + - 自左向右 << >> 自左向右 < <= > >= 自左向右 == != 自左向右 & 自左向右 ^ 自左向右