如果循环到C/C++中有符号和无符号的最大值,会发生什么?

让我们看一下C/C++中的以下代码片段。

null

C++

// An Unsigned char example
#include <iostream>
using namespace std;
void fun1()
{
unsigned char i;
for (i = 0; i < 256; i++)
cout << i << " " ;
}
int main()
{
fun1();
return 0;
}
// This code is contributed by shubhamsingh10


C

// An Unsigned char example
#include<stdio.h>
void fun1()
{
unsigned char i;
for (i = 0; i < 256; i++)
printf ( "%d " , i);
}
int main()
{
fun1();
return 0;
}


输出:

 Infinite Loop 

说明:

我们知道字符变量的大小是8位或1字节。因此,按十进制数的基数2表示,8位中的最大数为11111111。这是因为8位中的无符号数的范围从0到2 8. -1

现在(11111) 2. = (255) 10

如果我们将循环从0开始,最多执行255次,它将在循环中执行256次语句(包括0和255)。当循环达到(255)时 10 ,执行后,变量“i”增加1,即通过2s补码运算,

(11111111) 2. + (00000001) 2. = (00000000) 10

注意:在这种情况下,结束进位被丢弃;因此,最终递增的数字是0,这将导致循环的重新执行,因此循环将无限次运行。因此,如果我们将无符号字符i的限制设置为小于255而不是256,则可以避免上述情况。

现在考虑下面的程序:

C++

// A signed char example
#include <iostream>
using namespace std;
void fun2()
{
signed char i;
for (i = 0; i < 128; i++)
cout << i << " " ;
}
int main()
{
fun2();
return 0;
}
// This code is contributed by shubhamsingh10


C

// A signed char example
#include<stdio.h>
void fun2()
{
signed char i;
for (i=0; i<128; i++)
printf ( "%d " ,i);
}
int main()
{
fun2();
return 0;
}


 Infinite Loop  

签名字符范围从-2开始 7. 到2 7. -1,因此如果限制小于128,它也适用于无限执行。

注意(127)的2s补码 10 is(01111111) 2. 加上1,我们将得到(10000000) 2. 这是–(128) 10 当从2s补码形式计算时。

那么,如何从0循环到最大值(255或128或任何其他最大限制)? 下面是一种方法。

// One way of looping till maximum of unsigned in C/C++
#include<stdio.h>
void fun1()
{
unsigned char i = 0;
do
{
printf ( "%d " , i);
i++;
}
while (i > 0);
}
int main()
{
fun1();
return 0;
}


输出: 从0到255的数字

// One way of looping till maximum of signed in C/C++
// (Same as above except first statement)
#include<stdio.h>
void fun2()
{
signed char i = 0;
do
{
printf ( "%d " , i);
i++;
}
while (i > 0);
}
int main()
{
fun2();
return 0;
}


GCC中的输出: 从0到127的数字

注: 在C语言中,有符号溢出是未定义的行为,因此上述解决方案可能无法在所有有符号数字的计算机上运行。此外,上面显示的签名的输出可能在所有机器上都不相同。对于无符号数字,这种行为定义得很好。

C99中提到了以下内容 在这里 .

关于未签名: 涉及无符号操作数的计算永远不会溢出,因为一个结果 由生成的无符号整数类型表示的值将被约化为比生成的类型可以表示的最大值大一的数

关于签名: 未定义行为的一个例子是整数溢出行为。

本文由 马图尔夫人 .如果你喜欢GeekSforgek,并且想贡献自己的力量,你也可以写一篇文章,并将文章邮寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享