【问题标题】:C - Convert Integer to Binary ArrayC - 将整数转换为二进制数组
【发布时间】:2015-07-23 03:52:46
【问题描述】:

我对 C 语言非常陌生。 我需要一个小程序来将int 转换为二进制,并且二进制最好存储在一个数组中,以便我可以进一步将它们分开以进行解码。 我有以下内容:

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

int main()
{
    int arr[20];
    int dec = 40;
    int i = 0, ArrLen;

    if(dec > 0)
    {
        while(dec > 0)
        {
            arr[i] = dec % 2;
            i++;
            dec = dec / 2;
        }
    }
    else
    {
        printf("Invalid Number");
    }
}

从上面的代码中,我可以将 二进制 值存储在 arr 中。 但不是得到二进制等价物:101000,数组现在就像{0, 0, 0, 1, 0, 1},这是正确答案的反转。 所以问题是,如何以正确的顺序获得一个数组或者可能翻转它? 我有一件事是肯定的,那就是数组的最大长度不会超过8 元素。

此转换将被重复使用。 所以我打算把它放在一个函数中,这样我就可以调用该函数,传入一个整数,然后将数组作为返回值。那么另一个问题是,获取一个数组作为返回值是否可行?

【问题讨论】:

  • 首先考虑如何手工完成。然后将其放入代码中。顺便说一下,int 中的值已经是二进制的。有很多不同的方法可以做到这一点,特别是如果你征集你所知道的关于计算机如何存储数据的知识。但我猜这是一个班级的作业,因为这是大多数学校让你早做的事情。
  • 嗨奎因,这不是一个任务。我放学后很远。只是我实际上在 C#、PHP 和 JAVA 方面做得更多。不是任何 C 语言。从 int 中打印为 BINARY 很容易,但要存储它们,我还不能接球。
  • 你不能在C中传递一个数组。你必须在函数中malloc并返回一个指向地址的指针。
  • @M.Shaw struct R { unsigned char ar[8]; }; struct R func(int value) { struct R r; .... return r; } - 如果您将一个固定数组埋入 struct,您可以按值返回它。如果询问,编译器将生成适当的代码来执行此操作。对于这项任务来说,这是否需要或可取是一个不同的问题。

标签: c arrays dynamic-c


【解决方案1】:

您可以使用指向 int 的指针来参数化数组。参数化位数也可能很有用。

void int_to_bin_digit(unsigned int in, int count, int* out)
{
    /* assert: count <= sizeof(int)*CHAR_BIT */
    unsigned int mask = 1U << (count-1);
    int i;
    for (i = 0; i < count; i++) {
        out[i] = (in & mask) ? 1 : 0;
        in <<= 1;
    }
}

int main(int argc, char* argv[])
{
    int digit[8];
    int_to_bin_digit(40, 8, digit);
    return 0;
}

【讨论】:

  • 次要:/* 断言:count 0 */
  • @chux 我对sizeof(?) 持观望态度,因为它正在评估有符号类型并且只转换为无符号以使用逻辑移位。 count 为零不应被标记为错误,但小于零可能是错误。在实践中count 应该是无符号的。
  • 断言count&gt;0 有助于count == 01U &lt;&lt; (count-1); 的问题。注意 count 不会在 `1U
【解决方案2】:

或递归 V2.0:

#include <stdio.h>

char *binaryToAbits(unsigned int answer, char *result) {
  if(answer==0) return result;
  else {
    result=binaryToAbits(answer>>1,result);
    *result='0'+(answer & 0x01);
    return result+1;
  }
}

int main(void) {
    unsigned int numToConvert=0x1234ABCD;
    char ascResult[64];
    *binaryToAbits(numToConvert,ascResult)='\0';
    printf("%s",ascResult);
    return 0;
}

注意,感谢@chux,这里有一个更好的递归函数来处理转换 0 的情况——它输出“0”而不是“”:

char *binaryToAbits(unsigned int answer, char *result) {
  if(answer>1) {
    result=binaryToAbits(answer>>1,result);
  }
  *result='0'+(answer & 0x01);
  return result+1;
};

【讨论】:

  • 1) numToConvert=0 --> "" 而不是 "0"。 2) 对于0x1234ABCD,当然 64 足够,但我希望 65 或 33。
  • @chux - 当然,但这需要另一个函数来检查 0。很简单,我只是没有理会它。缓冲区大小:我认为是 32,然后是 nul 的 33,然后四舍五入到 64:)
  • "需要另一个函数来检查 0"。嗯,也许是一个小的重写:if (answer &gt; 1) {result=binaryToAbits(answer&gt;&gt;1,result); } *result='0'+(answer &amp; 1); return result+1; 有点简单,但处理0 很好。
  • @chux 好主意!征得您的许可,我会对其进行编辑并添加归属地。
  • 事实上,草皮,我还是要添加它。如果你反对,我会删除它,或者你可以:)
【解决方案3】:

与 Johnny Cage 的答案相同,但添加了一个函数来获取数字的长度

#include <math.h>

int bit_len(unsigned int n){
   return floor(log(n)/log(2))+1;
}
void int_to_bin_digit(unsigned int in, int len_digitis,int* out_digit){

  unsigned int mask = 1U << (len_digitis-1);
  int i;
  for (i = 0; i < len_digitis; i++) {
    out_digit[i] = (in & mask) ? 1 : 0;
    in <<= 1;
  }
}

int main(int argc, char* argv[]){
   int number = 30;
   int len = bit_len(number);
   int digits[len];
   int_to_bin_digit(number,len, digits);
   for( int i =0;i<len;i++){
       printf("%d",digits[i]);
   }
  return 0;
 }

【讨论】:

    【解决方案4】:

    使用按位逻辑:

    for(int i = 0 ; i < 8 ; i++)
    {
        bytearray[i] = inputint & pow(2,7-i);
    }
    

    【讨论】:

    • 你可以通过利用 C 联合和结构来更快地做到这一点。
    • sizeof(int) 是 4,而不是 8。
    • 它应该是pow(2, 7-i),所以数组不会反转。
    • @M.Shaw 哎呀,我对我的位感到兴奋,我忘了 sizeof 更多的是字节
    • sizeof(int) * 8 是 32。OP 说the maximum array length will not exceed 8 elements
    【解决方案5】:

    这可能会有所帮助:

    void binary(unsigned n)
    {
        unsigned i;
        for (i = 1 << 31; i > 0; i = i / 2)
            (n & i)?`/*STORE 1*/` : `/*STORE 0*/` ;
    }
    

    【讨论】:

    • 注意:最好使用 1u &lt;&lt; 31,因为 1 &lt;&lt; 31 是 32 位 int 的未定义行为。
    【解决方案6】:

    试试这样的:

    uint8_t * intToBin(int x) {
        uint8_t *bin = (int *) malloc(8);
        uint8_t i = 0;
        int mask = 0x80;
        for (i = 0; i < 8; i++) {
            bin[i] = (x & mask) >> (7-i);
            mask >>= 1;
        }
        return bin;
    }
    

    uint8_t 的声明中包含&lt;stdint.h&gt;。 如果您不希望内存泄漏,请记住free malloc-ed 内存。

    【讨论】:

    • 内存不足int *bin = (int * ) malloc(8); --> int *bin = malloc(8 * sizeof *bin);
    • @chux OP 需要 8 位存储在一个数组中。我应该将bin 的类型改为unsigned charuint8_t。 OP 需要 8 位,而我已经分配了 64 位。我完全没有理由需要 256 位内存来存储 8 位数据。
    • “OP 需要 8 位,我已经分配了 64”是不正确的。代码在malloc(8) 中分配了 8,这对于 8 int 来说肯定是内存不足 - 因此是注释。 IAC,malloc(8) 现在的内存足以容纳 8 个uint8_t。但现在它有一个新问题:返回一个uint8_t *,它被转换为int *。使用 4 字节 int,调用代码可以引用 int* 数组的前 2 个,但肯定 OP 期待 8 个。
    【解决方案7】:

    这应该可行。

    #include <stdio.h>
    
    void intToBin(int dec, int bin[], int numBits){
        for(int i = 0; i < numBits; i++){
            bin[i] = 1 & (dec >> i);
        }
    }
    
    void printArr(int arr[], int arrSize){
        for(int i = 0; i < arrSize; i++) {
            printf("%d ", arr[i]);
        }
    }
    
    int main(int argc, char* argv[]){
        int bin[32];
        intToBin(-15, bin, 32); 
        printArr(bin, 32);
    }
    

    【讨论】:

      【解决方案8】:

      递归实现:

      (由于您无法预先知道给定数字的二进制格式中的位数(0/1))

      int arr[200]; //for storing the binary representation of num
      int i=0; // to keep the count of the no of digits in the binary representation
      
      void calBinary(int n) // function to recalculate
      {
         if(n>1)
            calBinary(n/2);
         arr[i++]=n%2;
      }
      

      【讨论】:

      • 你的数组仍然会被反转。
      • @KaustavRay 可能是因为递归通常带有无副作用,但这不是无副作用
      • 是的,这是真的!它总是效率较低,但它没有错!反正我学会了! :)
      猜你喜欢
      • 2013-09-09
      • 2019-03-29
      • 2020-12-05
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      • 2012-04-10
      • 2016-07-08
      • 1970-01-01
      相关资源
      最近更新 更多