GCC中的C条件运算符
来自“21世纪C”示例10.8GCC中的C条件运算符,c,conditional,C,Conditional,来自“21世纪C”示例10.8 typedef struct { double width, height; } size_s; size_s width_height(char *papertype){ return !strcasecmp(papertype, "A4") ? (size_s) {.width=210, .height=297} : !strcasecmp(papertype, "Letter") ? (size_s) {.width=216, .height=27
typedef struct {
double width, height;
} size_s;
size_s width_height(char *papertype){
return
!strcasecmp(papertype, "A4") ? (size_s) {.width=210, .height=297}
: !strcasecmp(papertype, "Letter") ? (size_s) {.width=216, .height=279}
: !strcasecmp(papertype, "Legal") ? (size_s) {.width=216, .height=356}
: (size_s) {.width=NAN, .height=NAN};
}
试图在WINAVR和GCC中使用此样式
(a_t_g.value.ax > xx) ?
{ leds |= rpr; //roll positive red
leds &= ~rpa; //clear amber
flag |= flagrdd; //set the flag for any red
}
: (a_t_g.value.ax < -xx) ?
{ leds |= rnr; //roll negative red
leds &= ~rna; //clear amber
flag |= flagrdd; //set the flag for any red
}
:{}
(a\t\u g.value.ax>xx)?
{led |=rpr;//滚动正红色
LED&=~rpa;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
}
:(a_t_g.value.ax<-xx)?
{leds |=rnr;//滚动负红色
LED&=~rna;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
}
:{}
这将导致错误:在“{”标记之前应该有表达式
GCC不能处理这个问题,还是我做错了什么?
在这种风格中,如何处理最后的donothing呢?条件运算符的格式是
condition? value_if_true : value_if_false;
原始格式是什么样子的
condition ? value1 : condition2 ? value2 : condition3 ? value3 : last_value;
在表达式中,缺少:last_值部分
您需要重新查看表达式以添加此值。三元?:
运算符用于表达式中。两个分支都需要是一个带值的表达式;空块没有意义。请注意,在表达式中使用复合块是一个GCC扩展,这里没有理由使用它
实现此功能的方法是使用普通的if
和else
if (a_t_g.value.ax > xx) {
leds |= rpr; //roll positive red
leds &= ~rpa; //clear amber
flag |= flagrdd; //set the flag for any red
}
else if (a_t_g.value.ax < -xx) {
leds |= rnr; //roll negative red
leds &= ~rna; //clear amber
flag |= flagrdd; //set the flag for any red
}
if(a\t\u g.value.ax>xx){
LED |=rpr;//滚动正红色
LED&=~rpa;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
}
否则如果(a_t_g.value.ax<-xx){
LED |=rnr;//滚动负红色
LED&=~rna;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
}
?:
运算符不支持不返回任何内容的块,因此您必须在代码中返回某些内容
(a_t_g.value.ax > xx) ?
({ leds |= rpr; //roll positive red
leds &= ~rpa; //clear amber
flag |= flagrdd; //set the flag for any red
})
: (a_t_g.value.ax < -xx) ?
({ leds |= rnr; //roll negative red
leds &= ~rna; //clear amber
flag |= flagrdd; //set the flag for any red
})
:({})
(a\t\u g.value.ax>xx)?
({led |=rpr;//滚动正红色
LED&=~rpa;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
})
:(a_t_g.value.ax<-xx)?
({led |=rnr;//滚动负红色
LED&=~rna;//清除琥珀色
flag |=flagrdd;//设置任何红色的标志
})
:({})
您可以在块周围使用()
,就像我在上述代码中使用的那样,使此代码正常工作。引用的代码包括:
return ... ? (size_s) {.width=210, .height=297} ! ...
这不是“语句表达式”GCC扩展。它是一个C99指定的初始值设定项,它创建了一个大小的实例,其宽度和高度成员分别初始化为210和297。(如果结构中有其他成员,它们将被初始化为0。)需要显式cast(size_s)
,因为不可能猜测初始值设定项应用到的对象的类型。这是一种所有C99编译器都必须识别的完全合法的语法
那根本不是我们的“同一风格”
这是试图使用GCC“语句表达式”扩展名。但是,该扩展名要求用括号括起带括号的块,因此“正确”的写入方式是:
(a_t_g.value.ax > xx) ? ({ leds |= rpr; ... }) ... : ({});
GCC不会对此抱怨,尽管许多其他编译器也会。除非你知道没有人会尝试用GCC以外的编译器编译你的代码——这是一个危险的假设——你应该避免使用GCC扩展,特别是在这样的情况下,三元运算符的值被忽略了——这样就可以se({})
,其类型为void
。如果以if
语句的正常方式编写此代码,将更加优雅易读。谢谢大家的回复。现在我已经明白了,我已经学会了。
读完这本书后,我想尝试一下这个例子。
然后我用一些if..else工作代码替换了条件运算符。
我也很好奇是否可以忽略其他部分。显然不是。
我不知道GCC的扩展。作者引用了C99。
当然,每个人都知道if..else,但另一方面,作者的代码提供了一个整洁的表,并且是C99安全的。
当protothreads的使用限制了switch语句的使用时,这将是另一个可以使用的工具。
谢谢你请展示相关代码的一部分。在三元运算符中使用空语句是无效的,因为它需要计算为有效的RHS值。但如果没有完整的代码,则不清楚你真正想做什么,因此不可能给出确切的建议。应该用第因此,我相信(这将是条件?({statement;}):({statement;})
)。但我同意这确实应该是一个if
语句。一个好习惯是编写易于阅读的代码。谢谢大家的回复。我学到了更多。读完这本书后(作者Ben Klemens),我对此很好奇,我以前从未见过。我也很好奇这样一个条件列表是否可以包含“不做任何事情”部分。显然不是。实际上作者mainlt写的是wwindows编程。我只是简单地编写了一些工作if..else代码并尝试采用这种风格。感谢您指出GCC扩展。St如果使用protothreads限制switch语句的使用,那么这种样式可能会很有用。再次感谢大家。
(a_t_g.value.ax > xx) ? ({ leds |= rpr; ... }) ... : ({});