Joh*_*ith 3 c c++ type-conversion literals
当我使用size_t类型(或无符号长整数)进行算术运算时,我应该多么小心地使用类型文字来装饰整数常量.例如,
size_t a = 1111111;
if (a/2 > 0) ...;
Run Code Online (Sandbox Code Playgroud)
当编译器进行除法时会发生什么?它将2视为整数还是无符号整数?如果是前者,那么(unsigned int)/(int)的结果类型是什么?
我应该经常小心地写'你'文字
if (a/2u > 0) ...;
for (a=amax; a >= 0u; a -= 3u) ...;
Run Code Online (Sandbox Code Playgroud)
或编译器会正确猜测我想使用无符号整数运算?
size_t是一个无符号整数。2始终是类型int。所以编译器实际上是这样解释这个表达式的:
a/(size_t)2 > (size_t)0
Run Code Online (Sandbox Code Playgroud)
(但是,作为该组运算符的特殊情况,运算符或任何关系运算符的结果>始终是类型。)int
我应该总是小心地写“u”文字吗
某些编码标准(尤其是 MISRA-C)会要求您这样做,以确保代码中不存在隐式类型提升。隐式提升或转换非常危险,是 C 语言中的一个缺陷。
对于您的具体情况,隐性促销并不存在真正的危险。但在某些情况下,使用小整数类型时,您可能会由于隐式类型提升而导致符号性无意更改。
尽管u为代码中的每个文字编写后缀可能会降低可读性,但明确地永远不会有任何坏处。
现在,作为一名 C 程序员,为了应对类型提升危险,您真正必须做的是了解整数提升和常见算术转换的工作原理(这里是有关该主题的一些示例)。遗憾的是,有很多 C 程序员不这样做,包括退伍军人。结果是微妙的,但有时会出现严重的错误。特别是在使用按位运算符(例如移位)时,符号的更改可能会引发未定义的行为。
这些规则可能有点难以学习,因为它们的行为并不真正理性或一致。但在您详细了解这些规则之前,您必须明确类型。
编辑:要挑剔,实际上没有指定 的大小size_t,所有标准都说它必须足够大以至少容纳值 65535 (2 个字节)。因此从理论上讲,size_t可能等于unsigned short,在这种情况下,促销结果会完全不同。但实际上,我怀疑这种情况是否有任何意义,因为我不相信存在任何size_t小于 的实现unsigned int。