在C语言中进行二进制字符转十六进制的转换

3

我正在查看由Tibor Kiss创建的简单C函数(下面是链接)。我试图理解如何将单个二进制字节转换为两个十六进制字符涉及添加“W”(0x57)。为什么要这样做呢?

我了解>>通过四个位置向右移动字符c(用0填充左侧位)。我还理解x=c&0x0f部分,只需使用按位AND掩码来过滤掉x的上四位。

我只是不知道为什么将二进制字节转换为十六进制会涉及添加ASCII“W”(0x57)。

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en543105

/******************************************************************************
 * Function:        void btoh(unsigned char c,char *str)
 *
 * PreCondition:    None
 *
 * Input:           str - pointer to the zero terminated string
 *                  c   - byte to convert
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Convert one byte to a 2 character length hexadecimal
 *                  zero terminated string
 *
 * Note:            Using static variable for less code size
 *****************************************************************************/
void btoh(unsigned char c,char *str)
{
    static unsigned char x;
    x=c>>4;
    *str=x+(x>9?'W':'0');
    x=c&0x0f;
    str[1]=x+(x>9?'W':'0');
    str[2]=0;
}

'W' 是 ASCII 码 87(10),87 + 10 = 97('a') - BLUEPIXY
1
@BLUEPIXY 别喊。 - user529758
2个回答

9
他添加“W”的原因是他简化了这个表达式:
*str=x+(x>9? ('a'-10) :'0');

他观察到'W'等同于'a'-10,并在他的代码中输入了这个简化常量。这不是一个很好的想法,因为如果没有查看ASCII表,很难理解正在发生什么。此外,编译器会将'a'-10表达式简化为完全相同的值,因此可读性会丧失,而没有任何特定的收益。

刚刚弄明白了。为什么会有人这样做呢? - user529758
2
@KeithNicholas 我的意思是,'a' - 10 是一个constexpr。如果我的编译器没有将其优化为字面值 0x57,我会立即将其弹出到外太空。 - user529758
1
@H2CO3 你可能需要澄清一下最后的“it”是指你的编译器,而不是字面上的意思 :-) - Sergey Kalinichenko
1
@H2CO3 为什么呢,外层空间到处都是糟糕的编译器 :-) - Sergey Kalinichenko
@H2CO3:我也是。我还记得我们为Commodore-16拆卸BIOS/监视器/操作系统的时候(如果我没记错,Bill G.做得非常好),并追踪'@' // ox40例程以格式化十六进制。还涉及到'0' // 0x30和其他一些文字,但从未出现过'W'。请停止这样做! - wildplasser
显示剩余2条评论

0
如果 c 是 (H1H2H3H4L1L2L3L4),则 str[0] 包含 0000H1H2H3H4,而 str[1] 包含 0000L1L2L3L4
+ '0'                                             ANSI

0000 0*** + 0011 0000 = 0011 0****  0  -->  0x30   0
                                    1  -->  0x31   1
                                    2  -->  0x32   2
                                       ...
+'W'                                               ANSI
00001011 + 0101 0111 =  0110 0010   B  -->  0x62  -->b
00001100 + 0101 0111 =  0110 0011   C  -->  0x63  -->c
00001010 + 0101 0111 =  0110 0001   A  -->  0x61  -->a
00001101 + 0101 0111 =  0110 0100   D  -->  0x64  -->d
00001111 + 0101 0111 =  0110 0110   F  -->  0x66  -->f
00001110 + 0101 0111 =  0110 0101   E  -->  0x65  -->e

所以他只是转向

                0x12 to '1''2'0
                0xAB to 'a''b'0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接