我正在研究自己的printf代码,我遇到了两个问题,希望你能帮助我.
第一个是%p选项:
这个选项给我一个void*十六进制形式的指针地址.所以我正在做的是:
void printp(void *thing)
{
dectohex((long)&thing, 1);
}
Run Code Online (Sandbox Code Playgroud)
这里dectohex仅仅是一个功能转换decimal到hex.除最后3个字符外,结果始终是正确的.总是.例如 :
me : 0x5903d8b8 , printf : 0x5903da28.
Run Code Online (Sandbox Code Playgroud)
并且这些角色不会经常变化,而另一部分在每次调用时都会发生变化.
我遇到的另一个问题是%O选项.我无法将签名的int转换为unsigned int.printf打印大量的数字negative int's,并没有演员表似乎工作,因为我无论如何都没有地方存储它.
编辑:非常感谢你的答案,所以显然对于第一个问题我只是有点愚蠢.对于第二个问题,我将尝试你给我的不同解决方案,如果我设法做到这一点,请更新你.
再次非常感谢您的时间和耐心,并对我的回复延迟感到抱歉,我检查了电子邮件提醒任何答案,但它显然不起作用.
REEDIT:在仔细阅读了我对第二个问题的答案之后,我想你们有些人认为我问过%o或%0.我真的在谈论%O,就像我认为的那样.在man中它告诉我"%O:long int参数被转换为无符号八进制".我的问题是在将long int转换为八进制之前,我需要将它转换为无符号的东西.
如果uintptr_t/intmax_t定义了(它是可选的),则将指针转换为该整数类型,然后打印。
否则,如果sizeof(uintmax_t) >= sizeof (void *),则转换为uintmax_t。 uintmax_t是必需的类型,但可能不够大。
void printp(void *thing) {
uintptr_t j = (uintptr_t) thing;
char lst[(sizeof j * CHAR_BIT + 3)/ 4 + 1]; // Size needed to print in base 16
char *p = &lst[sizeof lst] - 1;
*p = '\0';
do {
p--;
*p = "0123456789ABCDEF"[j%16];
j /= 16;
} while (p > lst);
fputs(p, stdout);
}
Run Code Online (Sandbox Code Playgroud)
该%O问题可能是符号扩展问题。(@mafso) 确保使用的贵重物品未签名,例如unsigned和unsigned long。没有看到代码很难确定。