C を使用して int をバイナリ表現で出力します

割り当てられたバッファを渡す場所をより最適化する別のオプションを次に示します。正しいサイズであることを確認してください。

// buffer must have length >= sizeof(int) + 1
// Write to the buffer backwards so that the binary representation
// is in the correct order i.e.  the LSB is on the far right
// instead of the far left of the printed string
char *int2bin(int a, char *buffer, int buf_size) {
    buffer += (buf_size - 1);

    for (int i = 31; i >= 0; i--) {
        *buffer-- = (a & 1) + '0';

        a >>= 1;
    }

    return buffer;
}

#define BUF_SIZE 33

int main() {
    char buffer[BUF_SIZE];
    buffer[BUF_SIZE - 1] = '\0';

    int2bin(0xFF000000, buffer, BUF_SIZE - 1);

    printf("a = %s", buffer);
}

いくつかの提案:

  • 文字列を null で終了
  • マジック ナンバーを使用しない
  • malloc() の戻り値を確認してください
  • malloc() の戻り値をキャストしない
  • バイナリ表現に関心があるため、算術演算ではなくバイナリ演算を使用してください
  • 2 回ループする必要はありません

コードは次のとおりです:

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

char * int2bin(int i)
{
    size_t bits = sizeof(int) * CHAR_BIT;

    char * str = malloc(bits + 1);
    if(!str) return NULL;
    str[bits] = 0;

    // type punning because signed shift is implementation-defined
    unsigned u = *(unsigned *)&i;
    for(; bits--; u >>= 1)
        str[bits] = u & 1 ? '1' : '0';

    return str;
}

あなたの文字列はヌルで終わっていません。 '\0' を必ず追加してください 文字列の末尾の文字。または、calloc で割り当てることもできます malloc の代わりに 、返されたメモリをゼロにします。

ところで、このコードには他にも問題があります:

  • 使用されているように、呼び出し時にメモリを割り当て、呼び出し元に free() の責任を負わせます。 割り当てられた文字列を ing します。 printf で呼び出すだけでは、メモリリークが発生します
  • 数字を 2 回通過しますが、これは不要です。すべてを 1 つのループで実行できます。

使用できる代替実装を次に示します。

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

char *int2bin(unsigned n, char *buf)
{
    #define BITS (sizeof(n) * CHAR_BIT)

    static char static_buf[BITS + 1];
    int i;

    if (buf == NULL)
        buf = static_buf;

    for (i = BITS - 1; i >= 0; --i) {
        buf[i] = (n & 1) ? '1' : '0';
        n >>= 1;
    }

    buf[BITS] = '\0';
    return buf;

    #undef BITS
}

使い方:

printf("%s\n", int2bin(0xFF00000000, NULL));

2 番目のパラメーターは、結果の文字列を格納するバッファーへのポインターです。バッファーがない場合は、NULL を渡すことができます。 と int2bin static に書き込みます バッファして、それを返します。元の実装に対するこの利点は、呼び出し元が free() について心配する必要がないことです。 返される文字列を取得します。

欠点は、静的バッファーが 1 つしかないため、後続の呼び出しで前の呼び出しの結果が上書きされることです。後で使用するために、複数の呼び出しの結果を保存できませんでした。また、スレッドセーフではありません。つまり、異なるスレッドからこの方法で関数を呼び出すと、互いの文字列が破壊される可能性があります。その可能性がある場合は、 NULL を渡す代わりに独自のバッファーを渡す必要があります 、そのように:

char str[33];
int2bin(0xDEADBEEF, str);
puts(str);