这是一种将long转换为二进制(char*)表示的惯用C方法吗?

Chr*_*heD 2 c binary type-conversion

问题在于我猜的标题.

这是我提出的临时解决方案,但我想知道:

  • 如果将二进制表示为char*则存在缺点.有没有更好的方法(考虑到我想要比特移位等...)
  • 如果下面的代码中存在明显的非惯用C(或其他错误).

欢迎所有建议......

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

/* compile with 
    gcc -lm -std=c99 
*/

void binary_repr(unsigned long input) {
    int needed_digits = (int) (floor(log2(input)) + 1);
    char *ptr_binarray = malloc((needed_digits + 1) * sizeof (char));
    int idx = (needed_digits);

    if (ptr_binarray == NULL) {
            printf("Unable to allocate memory.");
        exit(1);
    } 
    else {
        do {
            idx--;
            if (input % 2 == 0) { 
                ptr_binarray[idx] = '0'; 
            } 
            else { 
                ptr_binarray[idx] = '1'; 
            }
            input = input / 2;

        } while (input > 0);

        ptr_binarray[needed_digits] = '\0';
        printf("%s\n", ptr_binarray);
        free(ptr_binarray);
        ptr_binarray = NULL;
    }
}

int main()
{
    binary_repr(8);
    binary_repr(14);
    binary_repr(4097);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 7

看起来大概是惯用的,除了我写的循环类似于:

char *writeptr = ptr_binarray + needed_digits;
*writeptr = 0;
do {
    --writeptr;
    *writeptr = (input % 2) + '0';
    input /= 2;
} while (input > 0);
Run Code Online (Sandbox Code Playgroud)

不需要整数索引.

对于这种特殊情况,我不会打扰,malloc因为你free在同一个功能.只需在堆栈上分配一个足够大的char数组:

char binarray[sizeof(unsigned long)*CHAR_BIT + 1];
Run Code Online (Sandbox Code Playgroud)

或者使用C99的可变长度数组:

char binarray[needed_digits + 1];
Run Code Online (Sandbox Code Playgroud)

此外,如果您只使用gcc,那么您可以考虑使用__builtin_clz计算,而不是采用对数needed_digits.然而,这不是惯用语C,因为它是gcc方言.但即使没有它,您也不需要浮点数学来计算出需要多少位数:

http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

刚刚注意到该行中也存在可能的错误 - 你的do/while循环整齐地处理大小input为0 的情况,但是第一行没有,因为你不能记录0的日志.

有没有更好的方法(考虑到我想要比特移位等...)

不确定你的意思.如果你想对值进行位移操作,那么不要将它转换为这样的字符串.保持它long int,并在那里做你的位移.

其他小事,因为你要求一般意见.只要你有理由做到这一点,这些都不是我真正批评的事情:

  • 删除(needed_digits)周围无意义的parens ,它只是噪音.
  • 错误消息可能应该发送到stderr而不是stdout.
  • 我总是会立即检查来自malloc(或任何其他返回错误值的函数)的返回值,而不是在它们之间有一行代码.所以将int idx = needed_digits线向下移动到'do ... while'循环之前(因为你使用std = c99.如果它是c89,那么你仍然可以这样做,除了我要推荐......).
  • 在有条件退出或退货后我不会放"其他".但其他人会像你一样做,而论证可能会得到部落.
  • 我个人不会sizeof(char)在malloc中乘以,因为malloc分配的缓冲区的大小按照定义以字符为单位进行测量.但是其他人把它放在那里,所以每个malloc始终都有一个尺寸,所以我不能说我的方式是惯用的.它只是更好;-)
  • 免费后清除指针在它们处于结构中时可能是值得的,但对于自动化而言并非如此.

对于最后三件事中的每一件事,良好的C编程实践不一定像我一样,而是与您的同事/合作者达成编码风格.只要您同意不争辩,并且不要"整理"彼此的代码,编码标准就可以"按照您的喜好"进行.