целое число, чтобы натянуть функцию itox в C - PullRequest
0 голосов
/ 15 февраля 2019

Я получил это откуда-то, но я не понимаю смысл этого.Как это на самом деле работает?

void itox(unsigned int i, char *s) 
{ 
    unsigned char n; 

    s += 4; 
    *s = '\0'; 

    for (n = 4; n != 0; --n) { 
        *--s = "0123456789ABCDEF"[i & 0x0F]; 
        i >>= 4; 
    } 
} 

Спасибо.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Интересная часть здесь -

*--s = "0123456789ABCDEF"[i & 0x0F]; 

Здесь "0123456789ABCDEF" - строковый литерал, который хранится в памяти компилятора.

Мы обращаемся к этому литералу в виде массива.Итак, "0123456789ABCDEF"[0] будет символом '0', а "0123456789ABCDEF"[1] будет '1'

С этой информацией мы можем легко проанализировать весь код.

s += 4;      //Increment pointer s by 4
*s = '\0';   // last value to be '\0' to end the string


for (n = 4; n != 0; --n) { 
    *--s = "0123456789ABCDEF"[i & 0x0F];   
    i >>= 4; 
} 

// say i is 0x231
// For n == 4, i & 0x0F will be 1, 
// *--s will point s to the third element in the array, and
// this will be assigned to 1.
// i <<4 will be i/16, so i will be 0x23

// for n == 3, 
// *--s will point to second element of array, which will be 3.

// and so on.

Наконец, чтоВы получаете шестнадцатеричное значение целого числа в s

0 голосов
/ 15 февраля 2019

Предполагается, что s - это буфер длиной 5 (включая нулевой терминатор), и записывает шестнадцатеричное представление i.Результатом является шестнадцатеричное представление i по модулю 65536 (для многих старых систем unsigned int имеет диапазон от 0 до 65535).

s += 4; 
*s = '\0';

Это завершаетсяs и помещает туда нулевой терминатор.

for (n = 4; n != 0; --n) {

Теперь мы вернемся назад к строке результата и заполним соответствующий char.

"0123456789ABCDEF"[i & 0x0F]; 

Это выбирает правильный char.i & 0x0F получает наименее значимое шестнадцатеричное значение, и, используя его в качестве нижнего индекса для доступа к массиву на "0123456789ABCDEF", получается соответствующий символ.

*--s = ...

Полученный символ помещается в правильное местои указатель снова уменьшается, поэтому следующая позиция может быть заполнена в следующем цикле цикла.

i >>= 4; 

Теперь мы сместим число на четыре бита, удалив четыре бита, которые мы только что преобразовали в шестнадцатеричное число,Теперь следующие четыре бита будут младшими значащими шестнадцатеричными цифрами.


Пример

Давайте возьмем число 58008.В шестнадцатеричном виде это 0xE298.Мод 16 это 8, поэтому "0123456789ABCDEF"[8]; получает "8".

Затем мы сдвигаем его на четыре бита, в результате чего 3625.Мод 16 это 9, и мы получаем "9".После следующей смены мы получаем 226, мод 16 - 2, а через одну смену - 14."0123456789ABCDEF"[14] is "E".

Соберите эти результаты в обратном порядке, и вы получите E298.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...