[英]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
整数的数组的索引从0
到i - 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.