编程C 开发者

在C语言中,表达式中应用了哪些类型转换(type conversion, type promotion)规则?请举例说明意外错误和解决方案。

用 Hintsage AI 助手通过面试

答案

在C语言中,表达式中经常发生类型转换(type promotion, type conversion),由标准规定:

  • 整数提升:较低位数的类型(例如,charshort)在算术操作之前会自动转换为intunsigned int
  • 常规算术转换:如果操作数类型不同,则根据规定的规则转换为“更宽泛”的类型。
  • 在有符号和无符号类型的混合操作中,由于转换的原因,结果可能会意外变化。

示例:

unsigned short a = 65535; signed short b = -1; printf("%d\n", a + b); // 取决于转换!

建议:特别在处理位操作、数组长度、索引时,仔细检查操作数的类型,并避免隐式混合有符号和无符号类型。

考验的问题

下面的代码片段会输出什么?

unsigned int u = 1; int i = -2; printf("%d\n", u + i);

答案:变量i将被转换为unsigned int,最终值会变得非常大,因为底层结果为:1U + (unsigned int)-2U,这将产生接近UINT_MAX(4294967295)的数字。只有当printfint格式化时,才会打印出负数,否则显示为垃圾值。

由于对主题细节的不理解而导致的真实错误示例


故事

在计算图像强度的平均值时,混淆了intunsigned int。负值通过unsigned错误传递,产生巨大的数字,导致图像缓冲区溢出。


故事

在嵌入式固件中,通过size_t计算字符串长度,同时通过int索引数组。在检查数组越界条件时,比较int i >= size_t len,这对长字符串破坏了逻辑,并在比较不同类型时导致了漏洞(size_t是无符号的)。


故事

一位金融项目的开发者通过%计算负数的余数,忘记了负操作数的结果符号取决于实现。在一个环境中,结果是正数,而在另一个环境中为负数,这导致计算周期性“偏移”。