为什么此代码可以将十六进制转换为十进制

nod*_*nja 2 c algorithm hex decimal

此代码将一个十六进制数字转换为十进制数值.

int value;
// ch is a char variable holding a hexadecimal digit
if (isxdigit(ch))
    if (isdigit(ch))
        value = ch - '0';
    else
        value = tolower(ch) - 'a' + 10;
else
    fprintf(stderr, "%c is not a valid hex digit", ch);
Run Code Online (Sandbox Code Playgroud)

我不完全理解它是如何工作的.我可以看到从char变量中减去不同的东西,具体取决于它是数字还是字母.我可以理解数字转换的部分,但我不明白为什么当字符是字母时必须将10添加到数值中.

unw*_*ind 11

减法tolower(ch) - 'a'将将字符映射到字母a..f的0..5范围内的数字.但是,十六进制数字a 16的(十进制)值是10 10,因此要将范围移回到需要的10..15,添加10.

也许这有助于:

+---------+------------+-----------------+-------------+
Character | Subtracted | Resulting value | Digit value |
+---------+------------+-----------------+-------------+
|   '0'   |     '0'    |       0         |       0     |
|   '1'   |     '0'    |       1         |       1     |
|   '2'   |     '0'    |       2         |       2     |
|   '3'   |     '0'    |       3         |       3     |
|   '4'   |     '0'    |       4         |       4     |
|   '5'   |     '0'    |       5         |       5     |
|   '6'   |     '0'    |       6         |       6     |
|   '7'   |     '0'    |       7         |       7     |
|   '8'   |     '0'    |       8         |       8     |
|   '9'   |     '0'    |       9         |       9     |
|   'a'   |     'a'    |       0         |      10     |
|   'b'   |     'a'    |       1         |      11     |
|   'c'   |     'a'    |       2         |      12     |
|   'd'   |     'a'    |       3         |      13     |
|   'e'   |     'a'    |       4         |      14     |
|   'f'   |     'a'    |       5         |      15     |
+---------+------------+-----------------+-------------+
Run Code Online (Sandbox Code Playgroud)

注意"结果值"列如何在'a'处重置为0,这不是根据最终"数字值"列所需的位置,该列显示每个十六进制数字的十进制数值.