سؤال

أنا أبحث عن وظيفة تسمح لي بطباعة تمثيل ثنائي int.ما لدي حتى الآن ؛

char *int2bin(int a)
{
 char *str,*tmp;
 int cnt = 31;
 str = (char *) malloc(33); /*32 + 1 , because its a 32 bit bin number*/
 tmp = str;
 while ( cnt > -1 ){
      str[cnt]= '0';
      cnt --;
 }
 cnt = 31;
 while (a > 0){
       if (a%2==1){
           str[cnt] = '1';
        }
      cnt--;
        a = a/2 ;
 }
 return tmp;

}

ولكن عندما اتصل

printf("a %s",int2bin(aMask)) // aMask = 0xFF000000

أحصل على إخراج مثل ؛

0000000000000000000000000000000000xtpyy (و مجموعة من الشخصيات غير المعروفة.

هل هو خلل في وظيفة أو أنا طباعة عنوان صفيف حرف أو شيء ما ؟ آسف, لا أستطيع أن أرى أين أنا ذاهب خاطئ.

NB رمز من هنا

تحرير:ليس من الواجبات المنزلية لمعلوماتك, أنا أحاول تصحيح شخص آخر صورة التلاعب الروتين في لغة غير مألوفة.ولكن إذا كان يوصف المنزلية لأنها ابتدائية مفهوم ثم اللعب النظيف.

هل كانت مفيدة؟

المحلول

إليك خيارًا آخر تم تحسينه بشكل أكبر حيث يمكنك تمرير المخزن المؤقت المخصص لك.تأكد من أنه الحجم الصحيح.

// 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);
}

نصائح أخرى

بعض الاقتراحات:

  • خالية من إنهاء السلسلة الخاصة بك
  • لا تستخدم الأرقام السحرية
  • التحقق من قيمة الإرجاع malloc()
  • لا تلقي القيمة المرتجعة لـ malloc()
  • استخدم العمليات الثنائية بدلاً من العمليات الحسابية لأنك مهتم بالتمثيل الثنائي
  • ليست هناك حاجة للتكرار مرتين

إليك الكود:

#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()في السلسلة المخصصة.سوف تقوم بتسريب الذاكرة إذا اتصلت بها للتو printf يتصل.
  • فهو يقوم بتمرير مرتين على الرقم، وهو أمر غير ضروري.يمكنك أن تفعل كل شيء في حلقة واحدة.

إليك تطبيق بديل يمكنك استخدامه.

#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));

المعلمة الثانية هي مؤشر إلى المخزن المؤقت الذي تريد تخزين السلسلة الناتجة فيه.إذا لم يكن لديك مخزن مؤقت يمكنك المرور NULL و int2bin سوف أكتب إلى أ static المخزن المؤقت وإعادته إليك.ميزة هذا على التنفيذ الأصلي هي أنه لا داعي للقلق بشأن المتصل free()في السلسلة التي يتم إرجاعها.

الجانب السلبي هو أن هناك مخزنًا مؤقتًا ثابتًا واحدًا فقط، لذا فإن الاستدعاءات اللاحقة ستحل محل نتائج الاستدعاءات السابقة.لا يمكنك حفظ النتائج من مكالمات متعددة لاستخدامها لاحقًا.كما أنها ليست آمنة لمؤشر الترابط، مما يعني أنه إذا قمت باستدعاء الوظيفة بهذه الطريقة من سلاسل رسائل مختلفة، فيمكن أن تضرب سلاسل بعضها البعض.إذا كان هذا احتمالًا، فستحتاج إلى تمرير المخزن المؤقت الخاص بك بدلاً من التمرير NULL, ، مثل ذلك:

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

هنا خوارزمية بسيطة.

void decimalToBinary (int num) {

        //Initialize mask
        unsigned int mask = 0x80000000;
        size_t bits = sizeof(num) * CHAR_BIT;

        for (int count = 0 ;count < bits; count++) {

            //print
            (mask & num ) ? cout <<"1" : cout <<"0";

            //shift one to the right
            mask = mask >> 1;
        }
    }

هذا ما قمت بإنشائه لعرض interger كرمز ثنائي يتم فصله لكل 4 بتات:

int getal = 32;             /** To determain the value of a bit 2^i , intergers are 32bits long**/
int binairy[getal];         /** A interger array to put the bits in **/
int i;                      /** Used in the for loop **/
for(i = 0; i < 32; i++)
{
    binairy[i] = (integer >> (getal - i) - 1) & 1;
}

int a , counter = 0;
for(a = 0;a<32;a++)
{
    if (counter == 4)
    {
        counter = 0;
        printf(" ");
    }
   printf("%i", binairy[a]);
   teller++;
}

يمكن أن يكون كبيرًا بعض الشيء ولكني أكتبه دائمًا بطريقة (آمل) بحيث يتمكن الجميع من فهم ما يجري.نأمل أن يكون هذا ساعد.

#include<stdio.h>
//#include<conio.h>  // use this if you are running your code in visual c++,      linux don't 
                     // have this library. i have used it for getch() to hold the screen for input char.

void showbits(int);
int main()
{
    int no;
    printf("\nEnter number to convert in binary\n");
    scanf("%d",&no);
    showbits(no);
//  getch();        // used to hold screen... 
                    // keep code as it is if using gcc. if using windows uncomment #include & getch()
    return 0;   

}
void showbits(int n)
{
    int i,k,andmask;

    for(i=15;i>=0;i--)
    {
        andmask = 1 << i;
        k = n & andmask;

        k == 0 ? printf("0") : printf("1");
    }

}

شيئان:

  1. أين تضع حرف NUL؟لا أستطيع رؤية مكان حيث '\0' تم تعيينه.
  2. تم توقيع Int، وسيتم تفسير 0xFF000000 كقيمة سالبة.لذا while (a > 0) سوف تكون كاذبة على الفور.

جانبا:وظيفة malloc في الداخل قبيحة.ماذا عن توفير مخزن مؤقت لـ int2bin؟

بضعة أشياء:

int f = 32;
int i = 1;
do{
  str[--f] = i^a?'1':'0';
}while(i<<1);
  • انها منصة عالية تعتمد ، ولكن ربما هذه الفكرة أعلاه يحصل لك بدأت.
  • لماذا لا تستخدم memset(str, 0, 33) إلى مجموعة كل شار مجموعة إلى 0?
  • لا ننسى أن حر()!!!شار* مجموعة بعد استدعاء دالة!

نسختان بسيطتان مشفرة هنا (مستنسخة مع إعادة تنسيق معتدل).

#include <stdio.h>

/* Print n as a binary number */
void printbitssimple(int n) 
{
    unsigned int i;
    i = 1<<(sizeof(n) * 8 - 1);

    while (i > 0) 
    {
        if (n & i)
            printf("1");
        else
            printf("0");
        i >>= 1;
    }
}

/* Print n as a binary number */
void printbits(int n) 
{
    unsigned int i, step;

    if (0 == n)  /* For simplicity's sake, I treat 0 as a special case*/
    {
        printf("0000");
        return;
    }

    i = 1<<(sizeof(n) * 8 - 1);

    step = -1; /* Only print the relevant digits */
    step >>= 4; /* In groups of 4 */
    while (step >= n) 
    {
        i >>= 4;
        step >>= 4;
    }

    /* At this point, i is the smallest power of two larger or equal to n */
    while (i > 0) 
    {
        if (n & i)
            printf("1");
        else
            printf("0");
        i >>= 1;
    }
}

int main(int argc, char *argv[]) 
{
    int i;
    for (i = 0; i < 32; ++i) 
    {
        printf("%d = ", i);
        //printbitssimple(i);
        printbits(i);
        printf("\n");
    }

    return 0;
}

// هذا ما فعلته عندما طلب منا معلمنا القيام بذلك

int main (int argc, char *argv[]) {

    int number, i, size, mask; // our input,the counter,sizeofint,out mask

    size = sizeof(int);
    mask = 1<<(size*8-1);
    printf("Enter integer: ");
    scanf("%d", &number);
    printf("Integer is :\t%d 0x%X\n", number, number);
    printf("Bin format :\t");
    for(i=0 ; i<size*8 ;++i ) {
        if ((i % 4 == 0) && (i != 0))  {
            printf(" ");
        }

        printf("%u",number&mask ? 1 : 0);

        number = number<<1;
    }
    printf("\n");

    return (0);
} 

إن أبسط طريقة بالنسبة لي للقيام بذلك (لتمثيل 8 بت):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char *intToBinary(int z, int bit_length){

    int div;
    int counter = 0;
    int counter_length = (int)pow(2, bit_length);

    char *bin_str = calloc(bit_length, sizeof(char));

    for (int i=counter_length; i > 1; i=i/2, counter++) {
        div = z % i;
        div = div / (i / 2);
        sprintf(&bin_str[counter], "%i", div);
    }

    return bin_str;
}

int main(int argc, const char * argv[]) {

    for (int i = 0; i < 256; i++) {
        printf("%s\n", intToBinary(i, 8)); //8bit but you could do 16 bit as well
    }

    return 0;
}

إليك حل آخر لا يتطلب حرفًا * .

#include <stdio.h>
#include <stdlib.h>

void    print_int(int i)
{
    int j = -1;
    while (++j < 32)
        putchar(i & (1 << j) ? '1' : '0');
    putchar('\n');
}

int main(void)
{
    int i = -1;
    while (i < 6)
        print_int(i++);
    return (0);
}

أو هنا لمزيد من سهولة القراءة:

#define GRN "\x1B[32;1m"
#define NRM "\x1B[0m"

void    print_int(int i)
{
    int j = -1;
    while (++j < 32)
    {
        if (i & (1 << j))
            printf(GRN "1");
        else
            printf(NRM "0");
    }
    putchar('\n');
}

وهنا هو الإخراج:

11111111111111111111111111111111
00000000000000000000000000000000
10000000000000000000000000000000
01000000000000000000000000000000
11000000000000000000000000000000
00100000000000000000000000000000
10100000000000000000000000000000
#include <stdio.h>

#define BITS_SIZE 8

void
int2Bin ( int a )
{
  int i = BITS_SIZE - 1;

   /*
    * Tests each bit and prints; starts with 
    * the MSB
    */
  for ( i; i >= 0; i-- )
  {
    ( a & 1 << i ) ?  printf ( "1" ) : printf ( "0" );
  }
  return;
}

int
main ()
{
  int d = 5;

  printf ( "Decinal: %d\n", d );
  printf ( "Binary: " );
  int2Bin ( d );
  printf ( "\n" );

  return 0;
}

ليست أنيقة جدًا، ولكنها تحقق هدفك ومن السهل جدًا فهمها:

#include<stdio.h>

int binario(int x, int bits)
{
    int matriz[bits];
    int resto=0,i=0;
    float rest =0.0 ;
    for(int i=0;i<8;i++)
    {
        resto = x/2;
        rest = x%2;
        x = resto;
        if (rest>0)
        {
            matriz[i]=1;
        }
        else matriz[i]=0;
    }
    for(int j=bits-1;j>=0;j--)
    {
        printf("%d",matriz[j]);
    }
    printf("\n");
}
int main()
{
    int num,bits;
    bits = 8;
    for (int i = 0; i < 256; i++)
    {
        num = binario(i,bits);
    }
    return 0;
}

هنا هو الحل الخاص بي.فهو ينشئ قناعًا، بدءًا من كل الأصفار والواحد في أقصى اليسار، وينقله منطقيًا إلى اليمين لكل بت في يفترض عدد صحيح 32 بت.تتم طباعة البتات بشكل تسلسلي عن طريق تحويل قيمة العدد الصحيح المقنع حاليًا إلى قيمة منطقية.

void printBits(int val){
    for(unsigned int mask = 0x80000000; mask; mask >>= 1){
         printf("%d", !!(mask & val));
    }
}
#include <stdio.h>
int main(void) {

    int a,i,k=1;
    int arr[32]; \\ taken an array of size 32

    for(i=0;i <32;i++) 
    {
        arr[i] = 0;   \\initialised array elements to zero
    }

    printf("enter a number\n");
    scanf("%d",&a);  \\get input from the user

    for(i = 0;i < 32 ;i++)
    {
        if(a&k)    \\bit wise and operation
        {
            arr[i]=1;
        }
        else
        {
            arr[i]=0;
        }
        k = k<<1; \\left shift by one place evry time
    }
    for(i = 31 ;i >= 0;i--)
    {
        printf("%d",arr[i]);   \\print the array in reverse
    }

    return 0;
}
void print_binary(int n) {
    if (n == 0 || n ==1) 
        cout << n;
    else {
        print_binary(n >> 1);
        cout << (n & 0x1);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top