Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么输出是255而不是无穷大?_C - Fatal编程技术网

C 为什么输出是255而不是无穷大?

C 为什么输出是255而不是无穷大?,c,C,为什么这个程序打印255而不是无穷大?因为您的字符类型只能保存0-255或-128-127,在这种情况下这并不重要。255之后,它将溢出并返回到0。0的计算结果为false,因此for循环被中断。因为您的字符类型只能保存0-255或-128-127,在本例中这并不重要。255之后,它将溢出并返回到0。0的计算结果为false,因此for循环被中断。首先,任何整数都不会达到无穷大。整数具有固定的值范围。您可能期望int计数达到2147483647 32位或9223372036854775807 6

为什么这个程序打印255而不是无穷大?

因为您的字符类型只能保存0-255或-128-127,在这种情况下这并不重要。255之后,它将溢出并返回到0。0的计算结果为false,因此for循环被中断。

因为您的字符类型只能保存0-255或-128-127,在本例中这并不重要。255之后,它将溢出并返回到0。0的计算结果为false,因此for循环被中断。

首先,任何整数都不会达到无穷大。整数具有固定的值范围。您可能期望int计数达到2147483647 32位或9223372036854775807 64位这样的值

它没有这样做的原因是,你的程序不是这样做的。您的程序仅在++c作为布尔条件真实计算时增加计数。一旦c本身的值用完,这种情况就会停止

如果char在您的环境中被签名,则在127处发生;然后,在达到此类类型的最大可能值后,您会遇到复杂的、实现定义的规则,在您的示例中,显然是返回到-128,然后继续到0。这是255步。 如果它是无符号的,则从0到255,然后以定义良好的方式返回到0。这仍然是255步。 下面对for循环进行了微妙的修改,将c的增量从条件部分移动到迭代后的步骤部分,因此它不再确定循环运行的时间:

#include <stdio.h>

int main(void){
    char c = 0;
    int count=0;
    for (;++c;)
        count++;
    printf("%d", count);
    return 0;
}

但是,现在您的整个程序都有未定义的行为,因为它描述了一个从不终止或执行I/O的线程。

首先,任何整数都不会达到无穷大。整数具有固定的值范围。您可能期望int计数达到2147483647 32位或9223372036854775807 64位这样的值

它没有这样做的原因是,你的程序不是这样做的。您的程序仅在++c作为布尔条件真实计算时增加计数。一旦c本身的值用完,这种情况就会停止

如果char在您的环境中被签名,则在127处发生;然后,在达到此类类型的最大可能值后,您会遇到复杂的、实现定义的规则,在您的示例中,显然是返回到-128,然后继续到0。这是255步。 如果它是无符号的,则从0到255,然后以定义良好的方式返回到0。这仍然是255步。 下面对for循环进行了微妙的修改,将c的增量从条件部分移动到迭代后的步骤部分,因此它不再确定循环运行的时间:

#include <stdio.h>

int main(void){
    char c = 0;
    int count=0;
    for (;++c;)
        count++;
    printf("%d", count);
    return 0;
}

但是,现在整个程序都有未定义的行为,因为它描述了一个从不终止或执行I/O的线程。

计算机中的数据存储在一定量的内存中。在这种情况下,char类型的c存储在一个字节上,因此它可能只有256个不同的值。如果您坚持增加它的值,它将进行包装,当它再次达到0时,for循环完成


假设它从0开始,并在检查其值之前递增,则for循环仅运行255次;在c的第256个增量时,其值再次变为0。

计算机中的数据存储在一定量的内存中。在这种情况下,char类型的c存储在一个字节上,因此它可能只有256个不同的值。如果您坚持增加它的值,它将进行包装,当它再次达到0时,for循环完成

假设它从0开始,并在检查其值之前递增,则for循环仅运行255次;在第256个c增量时,其值再次变为0。

简短回答 程序打印“255”,因为循环在c再次变为零之前遍历255个值,从而触发结束循环的条件

中等回答 C允许对字符进行签名或不签名。如果它是无符号的,则char在C实现中为8位,程序将其从1递增到255。下一个增量将其重置为零,因为无符号算术和转换被定义为换行,循环停止

如果char是有符号的,则由于++定义中的一系列规则,当值超出char的范围时,++c的行为是由实现定义的。很可能您的实现使用了一个八位字符,其值来自−128到127,当值变为128时,它将被包装为−128因此,255个值从1计数到127,从127计数到128−128至−在c再次变为零之前为1,循环停止,因为其测试表达式++c的计算结果为零

在C标准下,在实践中不会出现的一种理论上的可能性是,您的实现使用一个9位字符,其值为−256或−255到255,当值变为256时,将重置为零

长话短说 ++c是一个令人惊讶的复杂操作:

C 2018 6.5.3.1 2将其定义为等同于t o c+=1。 C 2018 6.5.16.2 3将C+=1定义为等同于C=C+1,但C的左值仅评估一次。 C 6.5.6 4告诉我们,通常的算术转换是在+的操作数上执行的。 通常的算术转换涉及6.3中的几个子句,这些子句导致使用int算术。由于int表示的值至少达到32767,因此此加法中不会出现超出范围的问题。 最后,C 6.5.16.1 2告诉我们加法的结果被转换为char。这就是有趣的事情发生在超出范围的值。 C 2018 6.3.1.3告诉我们转换为字符会发生什么。循环只有三种方式可以遍历255个值,然后在c中生成零:

char是无符号的八位字符,因此它表示0到255之间的值。当加法产生256时,6.3.1.3 2告诉我们转换为256模,产生零。 char是无符号的,8位,2的补码,所以它表示−128至+127。当加法产生128时,6.3.1.3告诉我们结果是实现定义的。您的实现产生−128之后,增量从−128至−1和0,然后循环停止。 char是无符号的,并且没有位,因此它表示两个字符中的值−256或−255至+255。当加法产生256时,实现产生零。然后循环停止。这在正常实践中不会发生;在C标准下,这只是一种理论上的可能性。 我们知道char是8位或9位,因为这是计数为255的唯一方法。如果它是C标准无论如何都不允许的七位,那么就无法计算255个不同的值。如果是10位或更多,则在实现定义的转换可以重置c之前,计数将上升到至少511。

简短回答 程序打印“255”,因为循环在c再次变为零之前遍历255个值,从而触发结束循环的条件

中等回答 C允许对字符进行签名或不签名。如果它是无符号的,则char在C实现中为8位,程序将其从1递增到255。下一个增量将其重置为零,因为无符号算术和转换被定义为换行,循环停止

如果char是有符号的,则由于++定义中的一系列规则,当值超出char的范围时,++c的行为是由实现定义的。很可能您的实现使用了一个八位字符,其值来自−128到127,当值变为128时,它将被包装为−128因此,255个值从1计数到127,从127计数到128−128至−在c再次变为零之前为1,循环停止,因为其测试表达式++c的计算结果为零

在C标准下,在实践中不会出现的一种理论上的可能性是,您的实现使用一个9位字符,其值为−256或−255到255,当值变为256时,将重置为零

长话短说 ++c是一个令人惊讶的复杂操作:

C 2018 6.5.3.1 2将其定义为等同于C+=1。 C 2018 6.5.16.2 3将C+=1定义为等同于C=C+1,但C的左值仅评估一次。 C 6.5.6 4告诉我们,通常的算术转换是在+的操作数上执行的。 通常的算术转换涉及6.3中的几个子句,这些子句导致使用int算术。由于int表示的值至少达到32767,因此此加法中不会出现超出范围的问题。 最后,C 6.5.16.1 2告诉我们加法的结果被转换为char。这就是有趣的事情发生在超出范围的值。 C 2018 6.3.1.3告诉我们转换为字符会发生什么。循环只有三种方式可以遍历255个值,然后在c中生成零:

char是无符号的八位字符,因此它表示0到255之间的值。当加法产生256时,6.3.1.3 2告诉我们转换为256模,产生零。 char是无符号的,8位,2的补码,所以它表示−128至+127。当加法产生128时,6.3.1.3告诉我们结果是实现定义的。您的实现产生−128之后,增量从−128至−1和0,然后循环停止。 char是无符号的,并且没有位,因此它表示两个字符中的值−256或−255至+255。当加法产生256时,实现产生零。然后循环停止。这在正常实践中不会发生;在C标准下,这只是一种理论上的可能性。 我们知道char是8位或9位,因为这是计数为255的唯一方法。如果它是C标准无论如何都不允许的七位,那么就无法计算255个不同的值。如果是10位或更多,则在实现定义的转换重置c之前,计数将至少上升到511<

/p> 要进行此输出,字符类型不需要无符号。如果它是int而不是char,它会被符号化并转到不定式还是限制?@EricPostpischil啊,你是对的,误读了。谢谢,已编辑。@LjupcheToshev您不能用整数表示无穷大,至少在C中是这样。这个答案假设字符是无符号的。字符类型不需要无符号的,这样输出才会发生。如果它是int而不是char,它会有符号并变为无穷大还是极限?@ericppostshil啊,你是对的,误读了。谢谢,已编辑。@LjupcheToshev您不能用整数表示无穷大,至少在C中是这样。这个答案假设字符是无符号的。有点离题,但计数到无穷大需要多长时间?@AndrewHenle是永恒的。@AndrewHenle:C标准没有规定性能,允许编译器进行优化,所以无限可以在有限的时间内到达。@Ericspostshil,但这不算无限-@安德烈·惠恩尔:当然是这样,用无穷而不是一数到无穷。相同的可观察行为。有点离题,但计数到无穷大需要多长时间?@AndrewHenle一个永恒。@AndrewHenle:C标准没有规定性能,并且允许编译器进行优化,因此可以在有限时间内达到无穷大。@EricPostChil,但这不是计数到无穷大-@安德烈·惠恩尔:当然是这样,用无穷而不是一数到无穷。相同的可观察行为。这个答案假设字符是无符号的。@swithwings:不完全是。即使字符是有符号的,如果它是8位,它可能只有256个不同的值,如果它不是2的补码,它可能会更少,并且在第256次递增时它会再次变为零,除非实现定义了一个陷阱,用于将超出范围的值转换为字符。@EricPostchil你自己说,有一个标准引用,这种情况下的结果是实现定义的。除非这个答案解决了这个问题,否则它只能如实地谈论未签名的案例。@swithwings的OP说我对编码是新手。使用诸如实现定义和未定义行为之类的术语并不能让初学者更清楚地回答问题,相反,swithings:在OP的C实现中,这个答案中的每个句子都是正确的。答案是正确的,尽管“重新开始”是模糊的。这个答案假设char是无符号的。@swithwings:不完全正确。即使字符是有符号的,如果它是8位,它可能只有256个不同的值,如果它不是2的补码,它可能会更少,并且在第256次递增时它会再次变为零,除非实现定义了一个陷阱,用于将超出范围的值转换为字符。@EricPostchil你自己说,有一个标准引用,这种情况下的结果是实现定义的。除非这个答案解决了这个问题,否则它只能如实地谈论未签名的案例。@swithwings的OP说我对编码是新手。使用诸如实现定义和未定义行为之类的术语并不能让初学者更清楚地回答问题,相反,swithings:在OP的C实现中,这个答案中的每个句子都是正确的。答案是正确的,尽管“重新开始”是模糊的。此程序中没有签名溢出。对于有符号字符的情况:++c被定义为等同于c++=1。c+=1被定义为等同于c=c+1,只是左值c只计算一次。在c+1中,c被提升为int,127+1不会溢出int。然后128被转换为char。这是根据C 6.3.1.3 3定义的实现。我有我的C++帽子。谢谢你的解释,尽管我不完全理解它的意思。@ LjupcheToshev你在用哪本书?如果你判断为不完整,那么这本书也是。问题中报告的行为可能发生在具有有符号九位字符的C实现中,在该实现中,将超出范围的值转换为字符被定义为产生零。因此,程序计数1到255,递增到256,在转换中产生零,并退出循环。此程序中没有符号溢出。对于有符号字符的情况:++c被定义为等同于c++=1。c+=1被定义为等同于c=c+1,只是左值c只计算一次。在c+1中,c被提升为int,127+1不会溢出int。然后128被转换为char。这是根据C 6.3.1.3 3定义的实现。我有我的C++帽子。谢谢你的解释,尽管我不完全理解它的意思。@ LjupcheToshev你在用哪本书?如果你判断为不完整,那么这本书也是。问题中报告的行为可能发生在具有有符号九位字符的C实现中,在该实现中,将超出范围的值转换为字符被定义为产生零。因此,程序计数1到255,递增到256,在转换中产生零,并退出循环。