Выглядит для меня примерно идиоматично, за исключением того, что я бы написал цикл примерно так:
char *writeptr = ptr_binarray + needed_digits;
*writeptr = 0;
do {
--writeptr;
*writeptr = (input % 2) + '0';
input /= 2;
} while (input > 0);
Нет необходимости в целочисленном индексе.
В этом конкретном случае я бы не стал беспокоиться о malloc
, поскольку вы free
выполняете ту же функцию. Просто выделите достаточно большой массив символов в стеке:
char binarray[sizeof(unsigned long)*CHAR_BIT + 1];
Или используйте массивы переменной длины C99:
char binarray[needed_digits + 1];
Кроме того, если вы используете только gcc, то вместо логарифма вы можете использовать __builtin_clz
для вычисления needed_digits
. Это не о идиоматическом C, так как это диалект gcc. Но даже без этого вам не нужна математика с плавающей запятой, чтобы выяснить, сколько цифр необходимо:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
Только что заметил возможную ошибку и в этой строке - ваш цикл do / while аккуратно обрабатывает случай, когда input
равен 0, а первая строка - нет, поскольку вы не можете взять журнал 0.
Есть ли лучший способ (учитывая, что я хотел бы иметь возможность сдвигать биты и т.д. ...)
Не уверен, что вы имеете в виду здесь. Если вы хотите выполнять такие операции, как сдвиг битов над значением, не конвертируйте его в строку, подобную этой. Сохраните его как long int
, и сделайте там сдвиг битов.
Другие мелочи, так как вы спрашиваете общее мнение. Ничего из этого я бы не стал критиковать, если у вас есть причина, по которой вы это сделали:
- Уберите бессмысленных паренов вокруг (
needed_digits
), это просто шум.
- Сообщение об ошибке, вероятно, должно идти в stderr, а не в stdout.
- Я бы всегда сразу проверял возвращаемое значение из malloc (или любой другой функции, которая возвращает значение ошибки), а не между строкой кода. Поэтому переместите строку
int idx = needed_digits
вниз непосредственно перед циклом «do .. while» (поскольку вы используете std = c99. Если это был c89, то вы все равно можете это сделать, за исключением того, что я собираюсь рекомендовать .. .).
- Я бы не ставил "else" после условного выхода или возврата. Но другие люди поступят так же, как и вы, и спор, возможно, станет племенным.
- Лично я не умножил бы на
sizeof(char)
в malloc, так как размер буфера, выделенного malloc, измеряется в символах по определению. Но другие помещают это так, чтобы у каждого malloc всегда был размер sizeof, поэтому я снова не могу утверждать, что мой путь идиоматичен. Это просто лучше; -)
- Очистка указателей после освобождения, возможно, имеет смысл, когда они в структуре, но не так много для автоматики.
Для каждой из трех последних вещей, хорошая практика программирования на С не обязательно должна быть такой же, как я, а согласовывать стиль кодирования с вашими коллегами / сотрудниками. Разрешается использовать стандарт кодирования «делай как хочешь», лишь бы ты согласился не спорить и не «приводить в порядок» код друг друга.