【问题标题】:C pointers and || operatorsC 指针和 ||运营商
【发布时间】:2011-09-10 01:12:39
【问题描述】:

我只是想知道这是否是 C89 程序的“好”代码。

obj_ptr = (obj*) (ptr1 || ptr2);

基本上它的作用(至少在我计算机上的 GCC 中)将 obj_ptr 设置为 ptr1 如果 ptr1 != NULL 则设置为 ptr2 否则。

我环顾四周,看不出这是否正确,但从 || 的事实来看运算符必须将指针转换为整数,然后我必须将它们转换回来,这是一种不好的风格。

如果这是不好的风格或不可移植的,是否有更好的(希望)同样简洁的解决方案?

编辑:我主要关心我编写的代码是否可移植并且不依赖于未定义的行为。

我可能找到了一种更好的方法,它是可移植的,我认为它是“好风格”(除非你不喜欢 if 语句中的赋值)。

if(!(obj_ptr = ptr1))
    obj_ptr = ptr2;

【问题讨论】:

  • 不要追求简洁。那是70年代。寻找清晰易懂的(阅读:可维护的)。
  • 它不仅不便携,而且完全是错误的。
  • 是的,这是错误的。我需要停止黑客攻击并编写一些好的代码。

标签: c pointers casting logical-operators


【解决方案1】:

不,如果ptr1 不为NULL 或ptr2 不为NULL,则将obj_ptr 设置为1,否则设置0。您需要使用三元运算符:

obj_ptr = ptr1 ? ptr1 : ptr2;

【讨论】:

  • 我不这么认为。当我在我的计算机上编译它时,它不会将结果转换为 1。我认为这是因为在 C 中 true 被定义为任何非 0 的数字。
  • @Tnelsond:用%p 打印值,如果你没有得到0x1,我会很惊讶。
  • 但是如果ab 都为零,则a|| b 的结果应该为零,否则为1。您可能使用了有问题的编译器。
  • 所以你是说如果它们都不是 NULL 的结果是什么是未定义的行为?
  • || 的结果运算符不是指针。这是可怕的代码。
【解决方案2】:

好吧,它在 C++ 中肯定是无效的(两个操作数都被提升为bool)。我承认我不确定 C。

[更新] 好的,找到了,C99 规范第 6.5.14 节:

语义

||如果有任何一个操作数,则运算符应产生 1 比较不等于0;否则,它产生 0。结果的类型为 int。

所以|| 总是计算为 0 或 1。

表达该表达式的常用方法是:

obj_ptr = (ptr1 ? ptr1 : ptr2);

如果您确实需要 (obj *) 演员表,那么您很可能做错了什么。

【讨论】:

  • 在这种情况下你不需要演员表
  • @David:我认为它被包括在内是有充分理由的,但你是对的,它可能被包括在一个不好的原因:-)
  • 强制转换是我的代码所必需的,我的编译器抱怨,但我想我是在用指针做整数逻辑。
  • @Nemo:我真的很喜欢三元运算符,但我不喜欢在这种情况下我必须写两次 ptr1。
  • +1 表示“如果你真的需要 (obj *) 演员表,你很有可能做错了什么。”
【解决方案3】:

如果你不喜欢写两次ptr1,你可以使用宏:

#define or(a, b) (a ? a : b)

obj_ptr = or(ptr1, prt2);

【讨论】:

  • 那种宏绝对是对宏的滥用。它正在重塑语言并隐藏实际发生的事情。这是最无法维护的废话。
  • 这是一个有趣的解决方案,但如果 "a" 是一个函数调用,则会遭受不必要的开销。
  • 不要介意不必要的开销。一旦你不得不处理 50K+ 行代码,人们用这样可爱的宏来隐藏显而易见的东西,你就会明白它们是多么邪恶。
  • @Amardeep:你能找到关于“你发明的词”的问题吗?并添加你的?我喜欢它。
  • :) 我实际上同意@carey-gregory。因为我自己不会使用它,所以我不应该发布它。我会删除答案,但这似乎很糟糕。
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多