C 指针和 ||运营商
我只是想知道这是否是 C89 程序的“好”代码。
obj_ptr = (obj*) (ptr1 || ptr2);
本质上它的作用(至少在我的计算机上的 GCC 中)是如果 ptr1 != NULL 则将 obj_ptr 设置为 ptr1 ,否则设置为 ptr2 。
我环顾四周,看不出这是否正确,但根据 || 的事实来判断运算符必须将指针转换为整数,然后我必须将它们转换回来,这是一种不好的风格的暗示。
如果这是不好的风格或不可移植,是否有更好且(希望)同样简洁的解决方案?
编辑:我主要关心我编写的代码是否可移植并且不依赖于未定义的行为。
我可能找到了一种更好的方法,它是可移植的,并且我认为这是“良好的风格”(除非您不喜欢 if 语句中的赋值)。
if(!(obj_ptr = ptr1))
obj_ptr = ptr2;
I'm just wondering whether this is "good" code for a C89 program.
obj_ptr = (obj*) (ptr1 || ptr2);
Essentially what it does (atleast in GCC on my computer) is set obj_ptr as ptr1 if ptr1 != NULL and ptr2 otherwise.
I've looked around and I can't see whether this is proper, but judging by the fact that the || operator has to convert the pointers to integers and then I have to cast them back is a hint of bad style.
If this is bad style or unportable, and is there a better and (hopefully) equally as terse solution?
EDIT: My primary concern whether the code I have written is portable and doesn't rely on undefined behavior.
I may have found a better way which is portable and which I think is "good style" (unless you don't like assignment in if statements).
if(!(obj_ptr = ptr1))
obj_ptr = ptr2;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,如果
ptr1
不为 NULL 或ptr2
不为 NULL,它的作用是将obj_ptr
设置为1
,否则为0
。您需要使用三元运算符:No, what it does is set
obj_ptr
to1
if eitherptr1
is not NULL orptr2
is not NULL, and0
otherwise. You need to use the ternary operator:好吧,它在 C++ 中肯定是无效的(其中两个操作数都提升为
bool
)。我承认我对 C 不太确定。[更新] 好的,找到了,C99 规范第 6.5.14 节:
因此
||
的计算结果总是为 0 或 1。制定该表达式的常用方法是:
如果您确实需要 (obj *) 强制转换,那么您很可能做错了什么。
Well, it would definitely be invalid in C++ (where both operands are promoted to
bool
). I admit I am not sure about C.[Update] OK, found it, C99 spec section 6.5.14:
So
||
always evaluates either to 0 or to 1.The usual way to formulate that expression is:
If you actually need the (obj *) cast, there is a good chance you are doing something wrong.
如果你不喜欢写两次 ptr1 ,你可以使用宏:
if you don't like writing ptr1 twice, you can use a macro: