【问题标题】:Array contains garbage values not input values数组包含垃圾值而不是输入值
【发布时间】:2019-02-27 00:00:31
【问题描述】:

我正在编写一个基本程序来计算十进制值的二进制 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 enter image description here

【问题讨论】:

  • 查看i,jbin[i]=remainder; j++; 中的使用情况i 始终为0。

标签: c arrays binary decimal


【解决方案1】:

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

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

这提供了几个好处。您可以简单地将decimal 右移一位,然后检查最低有效位是0 还是1并根据简单的一元 and 操作的结果存储所需的字符 '0''1'

例如,在您使用整数的情况下,您可以使用sizeof (int) * CHAR_BIT 确定表示任何二进制整数值所需的位数(其中CHAR_BITlimits.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-terminating 字符允许在填充时将数组视为字符串)

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

这里的字符数组/字符串表示也使事情变得更容易。将数组初始化为全零后,您可以从倒数第二个字符开始写入数组,并从结尾到开头工作将确保完成后您有一个以空字符结尾的字符串。此外,无论组成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'   */

(注意: 因为p 指向nul-terminating 字符,您必须使用前置减量运算符减量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 系列函数时。否则你很容易误入Undefined Behavior意外输入不以数字开头的内容)

使用/输出示例

$ ./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 的数组,请查看并告诉我。拥有一个包含各个位值的整数数组没有多大意义,但如果这是您必须做的,我很乐意提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2017-03-13
    • 2019-12-25
    相关资源
    最近更新 更多