[英]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.