c语言 - 程序不使用动态数组输出任何内容



我刚从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 实现的值与8forCHAR_BIT不同,但这仍然是正确的方法。我更新了下面的代码以使用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 时,分配大小为零的内存。您可能不会写入这样的记忆。

此外,还应使用无符号 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;

相关内容

  • 没有找到相关文章

最新更新