繁体   English   中英

程序不使用动态数组输出任何内容

[英]Program doesn't output anything using a dynamic array

我刚开始使用 C,我正在尝试创建一个程序,该程序接受一个数字并使用此方法(来自indepth.dev )将其转换为二进制:

要将整数转换为二进制,请从所讨论的整数开始,然后将其除以 2,同时注意商和余数。 继续将商除以 2,直到商为零。 然后只需按照相反的顺序写出余数。 (...) 现在,我们只需要以相反的顺序写出余数 - 1100。 因此,十进制中的 12 表示为二进制中的 1100。

我正在尝试使数组的大小动态化。 来自 Python 这有点令人困惑,因为在 Python 中你可以只附加到一个列表。

到目前为止,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main() 
{
    int *ptr, n, i;
    ptr = (int*)malloc(1 * sizeof(int));
    printf("Enter a number to convert: ");
    scanf("%d", &n);
    for (i = 0; n>0; i++)
    {   
        ptr = realloc(ptr, i * sizeof(int));
        ptr[i] = n % 2;
        n = n/2;

    }

    for(i=i-1; i>= 0; i--)
    {
        printf("%d", ptr[i]);
    }
    free(ptr);
    return 0;
}

当我运行程序并输入一个数字时,它不会输出任何内容。 如果我用固定的数组大小做同样的事情,它就可以工作。 为什么会这样?

问题在于这几行:

for (i = 0; n>0; i++)
{   
    ptr = realloc(ptr, i * sizeof(int));
    ptr[i] = n % 2;
    n = n/2;
}

您每次都在重新分配一个能够容纳i整数的数组,但是您最终在索引i处写入。 包含i整数的数组的索引从0i - 1 ,因此您写入的内容超过了数组的末尾。 这会导致未定义的行为

最简单的解决方法是从i = 1开始并写入ptr[i - 1]

for (i = 1; n > 0; i++)
{   
    ptr = realloc(ptr, i * sizeof(int));
    ptr[i - 1] = n % 2;
    n = n/2;
}

一种更简单的方法是使用固定大小的数组。 您已经知道int长度为8*sizeof(int)位,因此这是您需要的最大值。 此外,您可能不需要使用有符号整数,因为它们可能会导致负值出现问题(因此您可以使用unsigned )。

编辑:我说8 * sizeof(int)因为sizeof运算符以字节为单位返回类型的大小(在本例中为int )。 一个字节是 8 位,因此我将其乘以 8 以获得以位为单位的大小。 我在这里说的是8 ,但使用CHAR_BIT (来自limits.h )会更好,因为 C 中的“字节”可以使用超过 8 位来表示,在这种情况下, CHAR_BIT每字节保存正确的位数。 我不知道任何 C 实现的CHAR_BIT值不同于8 ,但它仍然是正确的方法。 我更新了下面的代码以使用CHAR_BIT而不是8

#include <stdio.h>
#include <limits.h>
#define N_BITS CHAR_BIT * sizeof(unsigned)

int main(void) {
    unsigned digits[N_BITS] = {0}; // Start with an array filled with zeroes.
    unsigned n;
    int i;

    printf("Enter a number to convert: ");
    scanf("%u", &n);

    // Calculate binary digits.
    for (i = 0; n > 0; i++) {
        digits[i] = n % 2;
        n /= 2;
    }

    // Skip leading zeroes.
    while (digits[i] == 0)
        i--;

    // Print binary digits in reverse order.
    for(; i >= 0; i--)
        printf("%u", digits[i]);

    // Final newline.
    putchar('\n');

    return 0;
}

奖金:

#include <stdio.h>

int main(void) {
    int i = 8 * sizeof(unsigned);
    unsigned n;

    printf("Enter a number to convert: ");
    scanf("%u", &n);

    while (i--)
        putchar('0' + ((n >> i) & 1));
    putchar('\n');

    return 0;
}

您分配的内存不足。 如果sizeof( int )等于4则二进制位数可以等于32 ( sizeof( int ) * CHAR_BIT )。

并且不需要使用realloc。

而且这个说法

ptr = realloc(ptr, i * sizeof(int));

当循环中的i等于 0 时,分配零大小的内存。您不能写入这样的内存。

您还应该使用 unsigned int 类型的对象。

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void) 
{
    unsigned int Base = 2;

    int *ptr = malloc( CHAR_BIT * sizeof( unsigned int ) );

    printf( "Enter a number to convert: " );

    unsigned int x = 0;

    scanf( "%u", &x );

    size_t n = 0;

    do
    {
        ptr[n++] = x % Base; 
    } while ( x /= Base );

    while ( n-- )
    {
        printf( "%u", ptr[n] );
    }
    putchar( '\n' );

    free( ptr );

    return 0;
}

它的输出可能看起来像

Enter a number to convert: 12
1100

如果你想使用realloc那么代码看起来像

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void) 
{
    unsigned int Base = 2;

    int *ptr = NULL;

    printf( "Enter a number to convert: " );

    unsigned int x = 0;

    scanf( "%u", &x );

    size_t n = 0;

    do
    {
        ptr = realloc( ptr, ( n + 1 ) * sizeof( unsigned int ) );
        ptr[n++] = x % Base; 
    } while ( x /= Base );

    while ( n-- )
    {
        printf( "%u", ptr[n] );
    }
    putchar( '\n' );

    free( ptr );

    return 0;
}

一般来说这样的调用

ptr = realloc( ptr, ( n + 1 ) * sizeof( unsigned int ) );

是不安全的,因为该函数可以返回 NULL。 所以一般来说你应该使用一个中间变量,比如

unsigned int *tmp = realloc( ptr, ( n + 1 ) * sizeof( unsigned int ) );
if ( tmp ) ptr = tmp;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM