三目运算符“?:”省略中间操作数的分析
2015-03-31 19:31
316 查看
/*
* Author: Godbach
* Blog:http://blog.chinaunix.net/u/33048/index.html
* 本文欢迎自由转载,但请标明出处,并保证本文的完整性。
*/
内核代码sch_fifo.c中函数fifo_init的代码如下:
其中第6行代码:
这里发现使用了三目运算符,但是又省略的中间的操作数。这是什么用法呢?网上发帖问了别的朋友,得到链接http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Conditionals.html#Conditionals上介绍少,内容如下:
原来 x ? : y 就是 x ? x : y。
但是,通常情况下用 x ? : y 替换x ? x : y看起来并不是很友好,至少我看着觉得有些别扭。根据上面的分析,在某些情况下,在表达式x为宏定义的时候,使用x ? : y 代替x ? x : y,可以避免有些宏定义产生的边界效应。请看下面的实例代码:
该程序执行的结果如下:
从这个结果可以看出来,表达式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时就取本身的值,也可以使用这种方式,节省了代码的长度。
原帖:http://blog.chinaunix.net/uid-10167808-id-26005.html
* 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; }
其中第6行代码:
u32 limit = sch->dev->tx_queue_len ? : 1;
这里发现使用了三目运算符,但是又省略的中间的操作数。这是什么用法呢?网上发帖问了别的朋友,得到链接http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Conditionals.html#Conditionals上介绍少,内容如下:
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 ? : y has the value of xif that is nonzero; otherwise, the value of y. This example is perfectly equivalent to x ? x : y In 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为宏定义的时候,使用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 |
这也就是“?:”省略中间操作数的用途。当然,如果像表达式u32 limit = sch->dev->tx_queue_len ? : 1中第1个操作数表达方法比较长时,而又想当期不为0时就取本身的值,也可以使用这种方式,节省了代码的长度。
原帖:http://blog.chinaunix.net/uid-10167808-id-26005.html
相关文章推荐
- 三目运算符“?:”省略中间操作数的分析
- 【转】三目运算符“?:”省略中间操作数的分析
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作数
- 三目运算符“?:”省略中间操作的特殊用法及举例
- JS中三目运算符和if else的区别分析与示例
- 两个数不通过中间变量交换值的原理分析!
- [置顶] 算术表达式的语法和语义分析(算符优先分析方法生成三元式的中间代码)
- JS中三目运算符和if else的区别分析与示例
- 1014-32-首页13-cell的结构分析---导航栏中间title位置的按钮的尺寸设置---setFrame----
- C语言求三个数的中间值(三目运算符)
- 递归调用实例分析2.在函数中间的递归与在函数尾部的递归
- 运用异或运算实现两个数不通过中间变量交换值的原理分析
- JS中三目运算符和if else的区别分析与示例
- 算法分析-查找单链表中的倒数第k个元素和中间元素
- GCC源码分析(三)——中间语言
- Java编程:用三目运算符和交换两种方法求三个数中的中间数字。
- 辛星分析html中间name和id 差额
- 语义分析和中间代码生成——哈工大编译原理课程(三)