首页 > 解决方案 > 数组包含垃圾值而不是输入值

问题描述

我正在编写一个基本程序来计算十进制值的二进制 eq。我将单个位或 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;
}

.exe 在此处输入图像描述

标签: carraysbinarydecimal

解决方案


如果您仍然遇到转换问题,考虑几点可能会有所帮助。首先,您在考虑从十进制到二进制的转换。对于任何给定的整数值,该值已经以二进制形式存储在内存中。

例如,当您有整数10时,计算机会将其存储1010在内存中。因此,出于所有实际目的,您需要做的就是读取内存的值并将数组值设置1为每个位10每个位0。您甚至可以做得更好,因为您最可能追求的是数字的二进制表示,因此无需将 1 和 0 作为完整的 4 字节整数值存储在 中bin,为什么不制作bin一个字符数组并存储字符'1''0'字符数组中的字符(当nul-terminated时)允许将二进制表示简单地打印为字符串。

这提供了几个好处。无需从基数 10 转换为基数 2 以及基数转换所需的除法和模调用,您可以简单地decimal向右移动 1 并检查最低有效位是否为0or1并存储所需的字符'0''1'基于简单一元and运算的结果。

例如,在您使用整数的情况下,您可以确定用二进制表示任何整数值所需的位数sizeof (int) * CHAR_BIT(其中CHAR_BIT是提供的常量,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 */

(初始化为全零和+1允许以nul 结尾的字符以允许在填充时将数组视为字符串)

接下来,正如您所发现的,无论您执行基本转换还是移位,and各个位值的结果顺序都将是相反的顺序。为了解决这个问题,您可以简单地声明一个指向数组中最后一个字符的指针,并从后向前用 1 和 0 填充数组。

这里的字符数组/字符串表示也使事情变得更容易。将数组初始化为零后,您可以从倒数第二个字符开始写入数组,并从末尾到开头工作将确保您在完成后拥有一个以空字符结尾的字符串。此外,无论组成 的位数是多少decimal,您总是会留下一个指向二进制表示开头的指针。

根据您在 中循环每个位的decimal方式,您可能需要decimal = 0;单独处理 where 的情况。(因为你在有位时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'   */

注意:由于p指向nul 终止字符,因此在取消引用和分配字符或值之前,您必须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成为int. 拥有一个包含各个位值的整数数组并没有多大意义,但如果这是您必须做的,我很乐意提供帮助。


推荐阅读