c - 算术溢出,因为 C 程序中有符号字符

标签 c output

我们知道 signed char 的值只能从 -128127。 但是当我们运行下面的程序时,即使 l 输出超出了有符号字符的范围,也没有发生溢出。

#include <stdio.h>


int main()
{
    char i = 60;
    char j = 30;
    char k = 10;
    char l = (i*j)/k;
    printf("%d ", l);

    return 0;
}

the output of l is 180 which is out of range for char l, but i am not getting any error.

在其他情况下,如果我们采用相同的程序而不是算术函数,如果我们简单地输入 l=180 并尝试打印它,那么我们会得到错误的答案。

#include <stdio.h>


int main()
{
    char i = 60;
    char j = 30;
    char k = 10;
    char l = 180;
    printf("%d ", l);

    return 0;
}

我在第二种情况下得到的答案是-76。 谁能解释为什么?即使我实际上执行的是同一件事,但我得到的结果却不同。

EDIT:

这是中间计算在 int 而不是 char 中进行的经典示例

所以在第 1 部分,当我进行计算时,它采用 int 中的所有值,在后面的部分中,我明确提到它是 char。

最佳答案

C语言实际上无法对char进行任何形式的计算。类型。 char是一个小整数类型,这意味着无论何时它作为表达式的一部分出现,它总是被隐式提升为 int .这称为整数提升整数提升规则

另外还有一个隐式类型转换回char ,因为您存储了类型为 int 的结果, 在 char 内.这称为左值转换:它将表达式的结果转换为指定对象的类型。

char l = (i*j)/k;

因此完全等同于

char l = (char)( (int)i * (int)j / (int)k );

因为所有算术运算都是在类型 int 上进行的,没有溢出。结果 180 可能适合也可能不适合 char .

你应该避免使用 char对于任何形式的算术,因为它具有实现定义的符号。在一个系统上它可能是有符号的,-128 到 127,在另一个系统上它可能是无符号的,0 到 255。使用 uint8_t相反,它是一种更好、更安全的类型。

关于c - 算术溢出,因为 C 程序中有符号字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38186440/

相关文章:

我可以制作一个从某个指针开始并在它开始的地方结束的循环吗?

bash - 将 Fortran 程序输出到变量中

java - 如何从函数中打印ln值?

c - 使用 DFS 计算连接 block 的结果错误

c - 如果我使用 else, "EVEN NUMBER ENTERED"会打印一次,如果我不使用,它会打印两次。为什么?

c - 数组作为结构数据库?

c - 如何检查一个字符串的第一个字母与同一字符数组内另一个字符串的最后一个字母

c++ - X Window 系统上的顶级窗口

c - 在 Linux 中设置系统时区

xslt - 为每个 xsl :text tag in the xml 设置禁用输出转义 ="yes"