unsigned int x = 4;
int y = -2;
int z = x > y;
当实现此操作时,变量Z的值为0,但为什么它为0而不是1?。
答案 0 :(得分:6)
信不信由你,如果C表达式是由两个参数构成的,一个是int
类型而另一个是unsigned
类型,那么int
值是在进行比较之前,将提升为unsigned
类型。
因此,在您的情况下,y
会提升为unsigned
类型。因为它是否定的,所以会通过添加UINT_MAX + 1
进行转换,并且它将采用值UINT_MAX - 1
。
因此x > y
将为0。
是的,这是很多错误的原因。即使是专业程序员也会不时地为此而堕落。有些编译器可以警告你:例如,使用gcc,如果使用-Wextra
进行编译,则会收到警告。
答案 1 :(得分:2)
这是算术转换的结果。
在表达式x > y
中,您有一个int
操作数和一个unsigned int
操作数。 y
被提升为unsigned int
,并通过将最多unsigned int
值加一个值转换为y
的值来转换价值。
C standard涵盖算术转换的第6.3.1.8节说明如下:
许多期望算术类操作数的运算符会导致 以类似的方式转换和生成结果类型。目的是为了 确定操作数和结果的通用实数类型。为了 指定的操作数,转换每个操作数,而不更改类型 域,对应的实际类型是普通实数的类型 类型。除非另有明确说明,否则常见的实际类型也是如此 结果的相应实际类型,其类型域为 操作数的类型域,如果它们是相同的,并且是复杂的 除此以外。这种模式称为通常的算术转换
...
否则,如果具有无符号整数类型的操作数具有等级 那么,大于或等于另一个操作数的类型的等级 带有符号整数类型的操作数转换为 具有无符号整数类型的操作数。
所以现在y
是一个非常大的值,与x
进行比较,因为x
小于此值,x > y
的计算结果为false,值为0.
答案 2 :(得分:1)
它被称为整数提升。
signed int
在此示例中,比较(>)运算符对unsigned int
和y
进行操作。根据转换规则,-2
将转换为unsigned int。由于-2
无法表示为无符号整数值,因此-2 + UINT_MAX+1
会转换为0
。
C11 6.3.1.3,第2段:
否则,如果新类型是无符号的,则转换为 重复加或减一个以上的最大值 可以用新类型表示,直到值在范围内 新类型。
因此,程序会打印UINT_MAX
,因为4
不小于int z = (int)x >y;
。
或者
如果要打印1,则执行显式类型的情况。像:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "status", "sources" })
public class NewsSource {
@JsonProperty("status")
private String status;
@JsonProperty("sources")
private List<Source> sources = null;
@JsonProperty("status")
public String getStatus() {
return status;
}
@JsonProperty("status")
public void setStatus(String status) {
this.status = status;
}
@JsonProperty("sources")
public List<Source> getSources() {
return sources;
}
@JsonProperty("sources")
public void setSources(List<Source> sources) {
this.sources = sources;
}
}