双重否定的原因是什么 – ( – n)?

我正在阅读一些遗留代码,我已经看到了类似的东西

char n = 65; char str[1024]; sprintf(str, "%d", -(-n)); 

为什么作者(不再存在)写-(-n)而不是n ? 不会 – 还不够?

首先要注意的是--n实际上 n 1并计算为新值, 类型为 char ; 所以它做了一些非常不同的事情-(-n)不要将代码更改为!

-n执行n的一元否定,并且由于C的类型提升规则也是int 类型的表达式。进一步的否定将其设置回原始值但保留类型 int

所以-(-n)实际上是一种冗长的写入+n ,这通常是一种无操作,但在这种情况下它将n类型转换为int

我怀疑作者正在防范错误的重构,他们担心参数的类型与格式说明符%d不匹配。

但在这种特殊情况下并不重要: sprintf会自动将char类型提升为int ,所以写它是绝对安全的

sprintf(str, "%d", n);

如果是“真正的”代码,还要考虑减小str缓冲区的大小,并考虑使用更安全的snprintf变体。

(作为最后的注释,注意双重否定可以产生有符号整数类型的溢出,所以请谨慎使用。)