【转】三目运算符“?:”省略中间操作数的分析
2011-03-23 11:04
323 查看
/*
* Author: Godbach
* Blog:http://blog.chinaunix.net/u/33048/index.html
* 本文欢迎自由转载,但请标明出处,并保证本文的完整性。
*/
内核代码sch_fifo.c中函数fifo_init的代码如下:
其中加粗的一行代码:
这里发现使用了三目运算符,但是又省略的中间的操作数。这是什么用法呢?网上发帖问了别的朋友,得到链接http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Conditionals.html#Conditionals上介绍少,内容如下:
A side effect is a result of an operator, expression, statement, or function that persists even after the operator, expression, statement, or function has finished being evaluated.
原来 x ? : y 就是 x ? x : y。
但是,通常情况下用 x ? : y 替换x ? x : y看起来并不是很友好,至少我看着觉得有些别扭。根据上面的分析,在某些情况下,在表达式x为宏定义的时候,使用x ? : y 代替x ? x : y,可以避免有些宏定义产生的边界效应。请看下面的实例代码:
该程序执行的结果如下:
从这个结果可以看出来,
* Author: Godbach
* Blog:http://blog.chinaunix.net/u/33048/index.html
* 本文欢迎自由转载,但请标明出处,并保证本文的完整性。
*/
内核代码sch_fifo.c中函数fifo_init的代码如下:
static int fifo_init(struct Qdisc *sch, struct rtattr *opt) { struct fifo_sched_data *q = qdisc_priv(sch); if (opt == NULL) { u32 limit = sch->dev->tx_queue_len ? : 1; if (sch->ops == &bfifo_qdisc_ops) limit *= sch->dev->mtu; q->limit = limit; } else { struct tc_fifo_qopt *ctl = RTA_DATA(opt); if (RTA_PAYLOAD(opt) < sizeof(*ctl)) return -EINVAL; q->limit = ctl->limit; } return 0; } |
u32 limit = sch->dev->tx_queue_len ? : 1; |
Conditionals with Omitted OperandsThe middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.Therefore, the expression x ? : yhas the value of xif that is nonzero; otherwise, the value of y. This example is perfectly equivalent to x ? x : yIn this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it. |
原来 x ? : y 就是 x ? x : y。
但是,通常情况下用 x ? : y 替换x ? x : y看起来并不是很友好,至少我看着觉得有些别扭。根据上面的分析,在某些情况下,在表达式x为宏定义的时候,使用x ? : y 代替x ? x : y,可以避免有些宏定义产生的边界效应。请看下面的实例代码:
#include <stdio.h> #define INC(x) (++x) int main(int argc, char *argv[]) { int x = 0; int y = 0; y = INC(x) ? INC(x) : 3; printf("y=%d\n", y); x = 0; y = INC(x) ? : 3; printf("y=%d\n", y); return 0; } |
[root@localhost tmp]# ./a.out y=2 y=1 |
表达式y = INC(x) ? INC(x) : 3中宏INC(x)进行了两次扩展。因此,导致x被计算了两次,最终结果为2。而表达式
y = INC(x) ? : 3
仅对宏INC(x)进行了一次扩展,因此,最终的结果为1。 这也就是“?:”省略中间操作数的用途。当然,如果像表达式
u32 limit = sch->dev->tx_queue_len ? : 1
中第1个操作数表达方法比较长时,而又想当期不为0时就取本身的值,也可以使用这种方式,节省了代码的长度。
相关文章推荐
- 三目运算符“?:”省略中间操作数的分析
- 三目运算符“?:”省略中间操作数的分析
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作的特殊用法及举例
- 三目运算符"?:"的透彻分析
- 算法分析-查找单链表中的倒数第k个元素和中间元素
- 1014-32-首页13-cell的结构分析---导航栏中间title位置的按钮的尺寸设置---setFrame----
- 编译原理-词法分析-语法分析-语义分析生成中间代码-python版
- Hadoop如何组织中间数据的存储和传输(源码级分析)1
- Java8流Stream中间操作、终止操作运行流程源码分析
- 逻辑运算符 ||, && ,| 三目运算符 使用分析
- JS中三目运算符和if else的区别分析与示例
- php字符串过长中间省略
- Java8流Stream中间操作、终止操作运行流程源码分析
- php 三元操作符的简化使用 (中间省略一项)
- 选择路径 省略中间 ...
- Java编程:用三目运算符和交换两种方法求三个数中的中间数字。
- 可以在函数中间打点了,以分析bpf_prog_load函数为例