我正在编写一个基本程序来计算十进制值的二进制等式。我将单个位或0和1值存储到数组中,以便最终可以反转数组并打印准确的二进制表示形式。但是,当我打印数组内容以检查数组是否已正确填充时,我看到了垃圾值,如果arr [] = {0}
,则为0我的代码
int main() {
int i = 0, j = 0, k, decimal, binary = 0, remainder, divider;
int bin[10];
printf("Enter decimal value");
scanf("%d", &decimal);
while ((decimal != 0) && (i < decimal)) {
remainder = decimal % 2;
decimal = decimal / 2;
bin[i] = remainder;
j++;
printf("%d", bin[i]);
}
printf("\n%d", j);
printf("\n%d", bin[0]);
printf("\n%d", bin[1]);
printf("\n%d", bin[2]);
printf("\n%d", bin[3]);
printf("%d", bin);
return 0;
}
答案 0 :(得分:1)
如果您在转换方面仍然遇到问题,请考虑几点。首先,您过度考虑了从十进制到二进制的转换。对于任何给定的整数值,该值已经以二进制形式存储在内存中。
例如,当您有整数10
时,计算机会将其作为1010
存储在内存中。因此,出于所有实际目的,您需要做的就是读取值的内存,并将1
的每个位的数组值设置为1
,将0
的每个位的数组值设置为0
{1}}。您甚至可以做得更好,因为最有可能的是数字的二进制表示形式,因此无需将1和0作为完整的4字节整数值存储在bin
中,为什么不做bin
个字符数组,并将字符'1'
或'0'
存储在字符数组中(当 nul终止时,它们可以将二进制表示形式简单打印为一个字符串。
这提供了许多好处。无需从基数10转换为基数2以及基数转换所需的除法和模调用,您只需将decimal
右移一位并检查最低有效位是否为0
或1
并根据简单的一元'0'
操作的结果存储所需的字符'1'
或and
。
例如,如果您使用整数,则可以确定用sizeof (int) * CHAR_BIT
表示二进制中任何整数值所需的位数(其中CHAR_BIT
是{{1}中提供的常量},并指定字符(例如字节)中的位数。对于整数,可以使用:
limits.h
要存储二进制数的字符表示形式(或者如果需要,可以存储整数#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
),只需声明一个字符数组即可:
1, 0
(初始化为全零和 char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
以允许 nul-终止字符,以便在填充时将数组视为字符串)
接下来,您已经发现,无论是执行基本转换还是移位,并且+1
各个位值的结果顺序都将相反。为了解决这个问题,您只需声明一个指向数组中最后一个字符的指针,然后从后往前用1和0填充数组即可。
这里的字符数组/字符串表示也使事情变得简单。将数组初始化为全零后,您可以从倒数第二个字符开始写入数组,并从末尾开始进行操作,以确保完成后得到一个以n结尾的字符串。此外,无论构成and
的位数是多少,始终会留下一个指向二进制表示形式开头的指针。
根据如何循环decimal
中的每个位,您可能需要分别处理decimal
的情况。 (由于您在decimal = 0;
中有位的情况下循环执行,因此如果decimal
则不会执行循环)简单的decimal = 0;
可以处理这种情况,而您的if
可以简单地循环else
中的所有位:
decimal
(注意:,由于 if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
指向 nul-终止字符,因此必须使用减前运算符将p
减1(例如p
),然后取消引用并分配字符或值)
所有剩下的就是输出您的二进制表示形式,并且如果如上所述完成,它就是一个简单的--p
。将所有部分放在一起,您可以执行以下操作:
printf ("%s\n", p);
(注意:)有关验证所有用户输入的评论-尤其是在使用#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
#define NBITS sizeof(int) * CHAR_BIT /* constant for bits in int */
int main (void) {
int decimal = 0;
char bin[NBITS + 1] = ""; /* declare storage for NBITS + 1 char */
char *p = bin + NBITS; /* initialize to the nul-terminating char */
printf ("enter a integer value: "); /* prompt for input */
if (scanf ("%d", &decimal) != 1) { /* validate ALL user input */
fputs ("error: invalid input.\n", stderr);
return 1;
}
if (decimal == 0) /* handle decimal == 0 separately */
*--p = '0';
else /* loop shifting decimal right by one until 0 */
for (; decimal && p > bin; decimal >>= 1)
*--p = (decimal & 1) ? '1' : '0'; /* decrement p and set
* char to '1' or '0' */
printf ("binary: %s\n", p); /* output the binary string */
return 0;
}
系列功能时。否则,您很容易陷入未定义行为意外输入不是以数字开头的内容
使用/输出示例
scanf
负数的二进制补码
$ ./bin/int2bin
enter a integer value: 0
binary: 0
$ ./bin/int2bin
enter a integer value: 2
binary: 10
$ ./bin/int2bin
enter a integer value: 15
binary: 1111
仔细研究一下,如果您有任何疑问,或者是否真的需要$ ./bin/int2bin
enter a integer value: -15
binary: 11111111111111111111111111110001
来组成bin
数组,请告诉我。拥有一个包含各个位值的整数数组没有多大意义,但是如果您必须这样做,我很乐意提供帮助。