我从某个地方得到的,但是我有点不明白它背后的含义。 这实际上如何工作?
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;
}
}
谢谢。
答案 0 :(得分:3)
假定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
。 Mod 16是8
,因此"0123456789ABCDEF"[8];
得到"8"
。
然后我们将其移位四位,得到3625
。 Mod 16为9
,我们得到了"9"
。在下一班次之后,我们得到226
,mod 16是2
,在一个班次之后,我们得到14
。 "0123456789ABCDEF"[14]
是"E"
。
将这些结果反汇编,您将得到E298
。
答案 1 :(得分:1)
这里有趣的部分是
*--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