Looks approximately idiomatic to me, except that I'd write the loop something like:
char *writeptr = ptr_binarray + needed_digits;
*writeptr = 0;
do {
--writeptr;
*writeptr = (input % 2) + '0';
input /= 2;
} while (input > 0);
No need for an integer index.
For this particular case, I wouldn't bother with malloc
since you free
in the same function. Just allocate a big enough char array on the stack:
char binarray[sizeof(unsigned long)*CHAR_BIT + 1];
Or make use of C99's variable length arrays:
char binarray[needed_digits + 1];
Also, if you're only using gcc, then rather than taking a logarithm you could consider using __builtin_clz
to calculate needed_digits
. That's not about idiomatic C, though, since it's the gcc dialect. But even without it, you don't need floating point math to figure out how many digits are needed:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
Just noticed a probable error in that line, too - your do/while loop neatly handles the case where input
is 0, but the first line doesn't since you can't take the log of 0.
Is there a better way (considering i would want the ability of bit-shifting etc...)
Not sure what you mean here. If you want to do operations like bit-shifting on a value, then don't convert it to a string like this. Keep it as a long int
, and do your bit-shifting there.
Other minor things, since you're asking for general opinions. None of these are things I'd really criticise as long as you have a reason you've done them:
- Remove pointless parens around (
needed_digits
), it's just noise.
- Error message should probably go to stderr rather than stdout.
- I would always check the return value from malloc (or any other function that returns an error value) immediately, rather than have a line of code in between. So move the
int idx = needed_digits
line down to just before the 'do .. while' loop (since you're using std=c99. If it was c89, then you could still do that except that I'm going to recommend...).
- I wouldn't put an "else" after a conditional exit or return. But other people would do as you have, and the argument can probably get tribal.
- Personally I wouldn't multiply by
sizeof(char)
in malloc, since the size of the buffer allocated by malloc is measured in chars by definition. But others put it there so that every malloc consistently always has a sizeof, so again I can't claim my way is idiomatic. It's just better ;-)
- Clearing pointers after free is arguably worthwhile when they're in a structure, but not so much for automatics.
For each of the last three things, good C programming practice would not necessarily be to do as I do, but to agree a coding style with your colleagues / collaborators. The coding standard is allowed to be "do as you prefer", just so long as you agree not to argue, and not to "tidy up" each other's code.