forum.jpg
运算符及优先级
在嵌入式Linux开发《C语言专题(三:运算符及优先级(1))》文章中介绍了算数运算符、关系运算符、逻辑运算符、赋值运算及优先级,本文继续介绍剩余的移位运算符、位运算符、单目元素符、条件运算符、逗号运算符及优先级。
(1)移位运算符:<<(左移运算符)、>>(右移运算符)就是将一个值的每一位向左或者向右移动 移位操作时要注意是算数移位还是逻辑移位。逻辑移位左移n位,则所有的位都向左移动n位,原来前n位丢弃,之后移入的后n位用0表示,相当于乘以2的n次方;逻辑移位右移n位,则所有的位都向右移动n位,原来的后n位丢弃,之后移入的前n位用0表示,相当于除以2的n次方。算数移位左移与逻辑移位左移一样,但是在操作数是负数时右移不一样,如果操作数是负数,右移n位时,则移入的前n位用1来填充而不是0,比如10101010(最高位为1代表是负数),又移2位后为11101010,保持原来是正负形。不过一般在嵌入式开发中用的比较多的是逻辑移位。如下图代码所示:
forum.jpg
移位运算符代码
(2)位运算符:&(位与)、|(位或)、^(位异或)对操作数的各个位进行位与、位或、位异或操作。要求操作数都为整型,并按位进行位操作。这个在嵌入式编程中非常重要。两个位进行&操作时,如果两位都为1,结果则为1,否则结果为0;两个位进行|操作时,如果两位都为0,结果则为0,否则结果为1;两个位进行^操作时,如果两位相同,结果则为0,否则结果为1,即不同为1,相同为0;下图以直观方式列出位运算符之间的结果。
forum.jpg
三种位运算符符
代码如下图所示:
forum.jpg
位运算符代码
内核中类似用法代码:if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000) csr12 |= 6;checksum = (checksum ^ (checksum >> 8)) & 0xff;
(3)单目元素符:只有一个操作数的运算符。有!(对操作数进行逻辑取反即:如果操作数为真,则结果为假,反之则为真;最终的结果只有0和1)、~(对整形操作数取反操作,比如原来为1的某一位,取反后为0,反之为1)、++(增值运算符)、--(减值预算符)、+(表示操作数为整数,加不加都可以)、-(表示操作数为负数)、&(表示操作数的地址)、*(间接访问运算符,与指针结合来访问指针所指向的值)、sizeof(以字节为单位计算操作符的类型长度,使用时可以加括号也可以不加)代码如下图所示:
forum.jpg
单目运算符代码
+和-很简单就是正数和负数,&和*的用法在指针部分我再讲解。sizeof的用法在文章中嵌入式Linux开发《C语言专题(二:有趣的基本数据类型)》有介绍。
(4)条件运算符:有3个操作数 用法:表达式1?表达式2:表达式3 如果各个表达式比较复杂的话,为了清晰最好加上括号:((表达式1)?(表达式2):(表达式3)) 首先计算表达式1的值,如果表达式1的值为真(非0值),那么表达式2的值就是就是整个条件语句的值,表达式3不用计算;如果表达式1的值为假,则表达式3的值就是整个条件语句的值,表达式2不用计算。如下图代码所示:
forum.jpg
条件运算符代码
内核中有这样的用法:unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1);
(5)逗号运算符:用法:表达式1,表达式2,...将2个或者多个表达式用逗号分割开,表达式自左向右逐个取值,整个表达式的值就是最后那个表达式的值。经常将这几个表达式用括号括起来。注意:我们在使用逗号表达式之前,看看使用逗号表达式后能否让程序在某方面表现很出色,如果可以就可以用,否则不用。笔试面试中曾遇到过这类计算。逗号运算符的优先级别在所有运算符中最低。如下图代码所示:
forum.jpg
逗号运算符代码