C数据类型的范围

C数据类型的范围,c,types,C,Types,我没想到会编译它,因为签名字符的范围是[−127, +127] ?? 我还试着输入一个8位的值12345678,也编译好了,9位,但是,导致我的Avast antivirus出现了我认为程序挂起了,但过了一会儿它就编译了。。我的问题是不应该有任何价值之外[−127、+127]是否因有符号字符数据类型而被编译器拒绝?C是一种老式语言。不要说我没想到会编译这些东西,因为。。。。一般来说,大多数C编译器都会尽力为您编译一些东西,即使这很危险。不要说编译器不应该拒绝任何超出范围的值吗?。大多数C编译器不

我没想到会编译它,因为签名字符的范围是[−127, +127] ?? 我还试着输入一个8位的值12345678,也编译好了,9位,但是,导致我的Avast antivirus出现了我认为程序挂起了,但过了一会儿它就编译了。。我的问题是不应该有任何价值之外[−127、+127]是否因有符号字符数据类型而被编译器拒绝?

C是一种老式语言。不要说我没想到会编译这些东西,因为。。。。一般来说,大多数C编译器都会尽力为您编译一些东西,即使这很危险。不要说编译器不应该拒绝任何超出范围的值吗?。大多数C编译器不会仅仅因为它们是个坏主意而拒绝它们,甚至不会因为它们可能不起作用而拒绝它们

然而,大多数现代编译器都会警告您错误的想法,但即使如此,您也可能需要明确地请求此类警告,因为在默认模式下,编译器可能仍在老派假设下运行,即程序员知道自己在做什么

在C语言中,无符号类型的溢出保证了其行为——实际上,算术总是按类型的大小进行模运算。虽然不能保证,但大多数处理器和编译器也对签名类型上的溢出实现了相同的功能——可能有相当数量的代码依赖于此。这就是编译器关于有符号整数溢出的警告不一定突出的另一个原因

尽管如此,我还是在两个不同的编译器下尝试了您的代码。一个警告:隐式常量转换中溢出,另一个警告:从“int”到“signed char”的隐式转换将值从32767更改为-1


如果您的编译器没有向您发出类似的警告,您可能需要a确保所有警告都已启用,或者在某个位置的“配置设置”对话框中使用复选框,或者使用命令行选项标志(如-Wall),或者b使用更好的编译器。

C语言允许您尝试将较大的类型显示为较小的类型,尽管它将如何做到这一点,但它并没有明确的定义,也不应该被依赖

在这一行上,有符号字符b=32767;您试图在签名字符中存储int。适用的是C标准C11 6.3.1.3/3中的本部分:

否则,新类型已签名,且无法在其中表示值;要么 结果是定义了实现或发出了定义了实现的信号

因此,将要发生的事情并没有很好的定义,而是留给系统和编译器。在典型的2的补码系统中,它很可能取二进制值32767=0x7FFF,去掉除LS byte=0xFF之外的所有内容,然后将其转换为有符号字符数,表示十进制-1

这就是说,您的代码实际上没有任何意义,在实际应用程序中也没有这种代码的用处,所以好的编译器会给您一个警告


你的杀毒软件弹出的原因是杀毒软件讨厌程序员。它指出您试图更改自己程序的二进制输出的可执行文件。我建议禁用/卸载用于编程的计算机上的防病毒软件。

也许您忽略了编译器警告。请始终启用编译器警告,并注意它们。C和C++是非常多的语言,如果你坚持的话,你可以做非法的事情…例如,您也没有包括在其中,或者像您应该做的那样写入int main void…听说过溢出吗?注意:字符范围是[-128127],而不是您所说的[-127127]!!!!!在2s补码中,负范围通常比正范围大1。此外,通过调试器运行代码并查看存储在“b”中的实际值。严格来说,这实际上不是有符号整数溢出,而是从大有符号整数到小有符号整数的转换。当然,这仍然是一个坏主意,但不是未定义的,而是impl.defined。溢出将是有符号字符b=0;b+=666;。
#include <math.h>

int main(){

    signed char b = 32767;
    if (b){
        printf("YES");
    }
    else
        printf("NO");
}