我试图制作一个“十进制到二进制”程序。它应该只能从0转换为255,并且可以。
当用户第一次输入数字时,我有两个变量“ n”和“ temp”,我将其存储在“ n”上。然后,我将“ n”分配给“ temp”(因此创建一个副本,至少这是我认为的做法)。
然后我只在代码中使用'temp'。我从不使用'n',直到我决定打印用户输入的号码为止。这就是问题所在,如果我输入的数字大于255,则变量'n'变为1。
我尝试通过几个C在线编译器运行代码,所有这些编译器都以正确的方式输出变量'n',这意味着尽管二进制数在数字大于255(按预期)时不起作用,它们仍会打印输入值。
我找到了一个在线编译器,该编译器在大于255时不打印'n'变量。
https://www.tutorialspoint.com/compile_c_online.php
如果通过此编译器运行我的代码,您将看到变量'n'在不使用的情况下如何变为1。
我知道如果您使用大于255的数字,则“二进制部分”将不起作用。我想知道为什么“ n”无处不在发生变化。
#include <stdio.h>
int main()
{
int bin[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int arrSize = 7;
int n;
int temp;
scanf("%d", &n);
temp = n;
while(temp != 0)
{
bin[arrSize] = temp % 2;
temp = temp / 2;
arrSize = arrSize - 1;
}
printf(" Decimal: %d ----> binary: ", n);
for(int i = 0; i <= 7; i++)
{
printf("%d", bin[i]);
}
printf("\n");
return 0;
}
答案 0 :(得分:1)
您已经经历了“缓冲区溢出”。 快速定义:
当程序或进程尝试写入时发生缓冲区溢出 与固定长度的内存块或缓冲区相比,有更多的数据 缓冲区分配为保留。由于缓冲区被创建为包含一个 定义的数据量,多余的数据可以覆盖 除非程序,否则与目标缓冲区相邻的内存地址 包括足够的边界检查以标记或丢弃数据 很多被发送到内存缓冲区。
您的代码中的错误仍然存在于while循环中:
while(temp != 0){
//I added this line to make it clear
printf("inside loop\tarrSize=%d\n",arrSize);
bin[arrSize] = temp % 2;
temp = temp / 2;
arrSize = arrSize - 1;
}
对于等于300的输入(每个输入> 255都会发生错误),您将获得以下输出:
inside loop arrSize=7
inside loop arrSize=6
inside loop arrSize=5
inside loop arrSize=4
inside loop arrSize=3
inside loop arrSize=2
inside loop arrSize=1
inside loop arrSize=0
inside loop arrSize=-1
inside loop arrSize=0
问题是我们的索引等于-1,您会问会发生什么?实际上数组是指向表第一个元素的地址+偏移量(索引*表类型的大小)的指针,这意味着对于bin [-1],它实际上是arrSize,而bin [-2] ]实际上是n。 您可以通过如下验证地址来进行检查:
printf("@ of bin[-1]:\t%p\n",(void*)&bin[-1]);
printf("@ of arrSize:\t%p\n\n",(void*)&arrSize);
printf("@ of bin[-2]:\t%p\n",(void*)&bin[-2]);
printf("@ of n:\t\t\t%p\n",(void*)&n);
这与我的编译器给了我
@ of bin[-1]: 0x7ffe00e32f9c
@ of arrSize: 0x7ffe00e32f9c
@ of bin[-2]: 0x7ffe00e32f98
@ of n: 0x7ffe00e32f98
因此,您进行更改时实际上不知道bin [-1](或根据n的值的bin [-2]),而实际上这是arrSize(或n)。
如何解决此问题?我建议您每次要遍历数组时都要验证索引(循环的条件必须在arrSize函数中)。或者,如果您想让这个特定的示例忽略它,而专注于逻辑:验证输入(在您的情况下,输入n必须为:0 <= n <= 255
)
答案 1 :(得分:-1)
void *ieee2b(double value,char size,void *res){
char
*p0=res,
*p=p0;
vbreplacec(vbsprintf(p,"%*.*s",size,size," "),' ','0',p);
if((long)value!=value)
while(1){
double
tmp=value*2;
*p++='0'+(long)tmp;
if(tmp==1||tmp==0||p-p0>size)
break;
value=tmp-(long)tmp;
}
else{
p=p0+size-1;
while((long)value>1){
*p--='0'+((long)value%2);
value=(long)value/2;
}
*p--='0'+((long)value);
}
return res;
}