三元运算符和类型转换中的混淆

Vik*_*ram 7 c ternary-operator type-conversion void-pointers

我经历了这个问题 -

为什么结果:1 ? (int *)0 : (void *)0
与以下结果不同: 1 ? (int *)0 : (void *)1

它有何不同?它应该是0(int*)0.
如何查看结果?
我们可以在哪里使用这种表达方式?

eff*_*ffe 19

唯一的区别在于类型:第一个返回a int *,第二个返回a void *.

从C11标准,§6.5.15 条件运算符,6:

如果第二个和第三个操作数都是指针,或者一个是空指针常量而另一个是指针,则结果类型是指向使用两个操作数引用的类型的所有类型限定符限定的类型的指针.此外,如果两个操作数都是兼容类型的指针或兼容类型的不同限定版本,则结果类型是指向复合类型的适当限定版本的指针; 如果一个操作数是空指针常量,则结果具有另一个操作数的类型 ; 否则,一个操作数是指向void或合格版本的指针void,在这种情况下,结果类型是指向适当限定版本的指针void.

(强调我的)

请记住,指向non的指针void不能是空指针常量,而只是空指针.C11§6.3.2.3 指针,3:

值为0的整型常量表达式或此类表达式转换为类型void *称为空指针常量.66)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.

66)宏NULL<stddef.h>(和其他标题)中定义为空指针常量; 见7.19.

所以在这里:

1 ? (int *) 0 : (void *) 0
Run Code Online (Sandbox Code Playgroud)

(int *) 0只是一个空指针,(void *) 0而是一个空指针常量,所以结果有类型int *(" 如果一个操作数是一个空指针常量,结果具有另一个操作数的类型 ").

在这里:

1 ? (int *) 0 : (void *) 1
Run Code Online (Sandbox Code Playgroud)

没有空指针常数(仅一个空指针,第一个),所以结果具有复合型void *(" 如果两个操作数都是指针兼容的类型或兼容的类型的不同合格版本,则结果类型是指向合适类型的合适版本 ").

结果有不同的类型,但它们都是空指针.另请注意,结果永远不会 0像您在问题中所说的那样,它总是一个指针.

遗憾的是,没有标准的方法可以看出C中的差异,C++对它有一些支持(typeinfo)但结果却有所不同.

我们可以在哪里使用这种表达方式?

我无法想到这种语言中这个模糊不清的角落的有用和具体用法.

  • 这个答案肯定是错的.`1`被认为是真的,因此两个操作都计算为`((int*)0)`. (2认同)
  • 在这里,我找到了一个很好的解释 - http://carolina.mff.cuni.cz/~trmac/blog/2005/the-ugliest-c-feature-tgmathh/ (2认同)