簡體   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