C 使用写入函数重新编码printf%p

C 使用写入函数重新编码printf%p,c,pointers,printf,write,C,Pointers,Printf,Write,我目前正在执行一项任务,需要打印变量的地址。使用printf%p会很容易,但我只允许使用unistd的write 我尝试将指针强制转换为一个无符号整数和uintptr\u t,然后将其转换为十六进制数。使用uintptr\t时,它可以工作,但对于无符号整数,它只打印地址的一半。也许有人能解释为什么会这样 我还看到了一些使用“>>”和“的解决方案,看起来只打印了地址的一半,因为您使用的“无符号整数”只有uintptr\u t的一半大小(请注意,uintptpr\u t是无符号整数类型) 您可以使用

我目前正在执行一项任务,需要打印变量的地址。使用printf%p会很容易,但我只允许使用unistd的write


我尝试将指针强制转换为一个无符号整数和uintptr\u t,然后将其转换为十六进制数。使用uintptr\t时,它可以工作,但对于无符号整数,它只打印地址的一半。也许有人能解释为什么会这样


我还看到了一些使用“>>”和“的解决方案,看起来只打印了地址的一半,因为您使用的“无符号整数”只有
uintptr\u t
的一半大小(请注意,
uintptpr\u t
是无符号整数类型)

您可以使用
unsigned char
数组将数据存储在指针变量中,然后使用put
uintptpr\u t
打印完整指针

根据,允许使用字符类型读取其他类型的对象


使用printf%p会很容易,但我只允许使用unistd的write

然后形成一个字符串并打印出来

int n = snprintf(NULL, 0, "%p", (void *) p);
char buf[n+1];
snprintf(buf, sizeof buf, "%p", (void *) p);
write(1, buf, n);

使用转换为整数的指针会略微降低可移植性,并且不一定能形成指针的最佳文本表示形式—这取决于实现


使用uintptr\t时,它可以工作,但对于无符号整数,它只打印地址的一半

未指定
unsigned
的宽度不足以包含指针中的所有信息


uintptru\t
,如果可用(非常常见),可以为
void
指针保留大部分信息。足够好,可以往返到等效指针,即使是以另一种形式。

因为您使用的“无符号整数”只有
uintptru\t
的一半大小?(
uintpttr\u t
是一个无符号整数,因此这看起来毫无意义)jsiller,“我不确定是否允许我使用uintptr\u t。”-->
uintptpr\u t
是可选类型。替代方法:使用最宽的可用值:
uintmax\u t,无符号长,
”我尝试将指针强制转换为一个无符号整数和uintptr\u t,然后将其转换为十六进制数。“->最好发布该代码。unsigned long long long与unsigned intnevermind具有相同的输出。我在两天前尝试了此操作,但显然做了一些错误,因为long long works我只允许使用write,不允许使用其他函数。@jsiller在没有
main()的情况下很难编写程序”
。祝你好运。实际上我不应该写main。我只使用main来测试它,但任务只要求一个只使用write来打印内存地址的函数。我可以自己编写其他函数并使用它们,但编写snprintf并不是那么容易。好吧,我试着理解这一点,但弄糊涂了很多:D.在seco中nd解决方案将指针p强制转换为无符号字符*(如:“unsigned char d=(unsigned char)&p;”)。这到底是什么意思?f.e.d[0]或d[10]的值是多少?它使
d
指向分配给
p
的内存,允许查看
p
对应的数据,因为
无符号字符数组
d[0]
将是指针的最小字节(如果它是小尾端),并且
d[10]
将超出范围(如果指针的大小小于11字节)。
#include <stdio.h>
#include <unistd.h>

void printOne(unsigned char v) {
    const char* chars = "0123456789ABCDEF";
    char data[2];
    data[0] = chars[(v >> 4) & 0xf];
    data[1] = chars[v & 0xf];
    write(1, data, 2);
}

int main(void) {
    int a;
    int* p = &a;
    /* to make sure the value is correct */
    printf("p = %p\n", (void*)p);
    fflush(stdout);

    /* print in reversed order, assuming little endian */
    for (size_t i = sizeof(int*); i > 0; i--) {
        printOne(((unsigned char*)&p)[i - 1]);
    }

    return 0;
}
int n = snprintf(NULL, 0, "%p", (void *) p);
char buf[n+1];
snprintf(buf, sizeof buf, "%p", (void *) p);
write(1, buf, n);