如何在C语言中打印变量地址?

57

当我运行这段代码时。

#include <stdio.h>

void moo(int a, int *b);

int main()
{
    int x;
    int *y;

    x = 1;
    y = &x;

    printf("Address of x = %d, value of x = %d\n", &x, x);
    printf("Address of y = &d, value of y = %d, value of *y = %d\n", &y, y, *y);
    moo(9, y);
}

void moo(int a, int *b)
{
    printf("Address of a = %d, value of a = %d\n", &a, a);
    printf("Address of b = %d, value of b = %d, value of *b = %d\n", &b, b, *b);
}

我在编译器中一直收到这个错误。

/Volumes/MY USB/C Programming/Practice/addresses.c:16: warning: format ‘%d’ expects typeint’, but argument 2 has typeint *’
/Volumes/MY USB/C Programming/Practice/addresses.c:17: warning: format ‘%d’ expects typeint’, but argument 2 has typeint **’
/Volumes/MY USB/C Programming/Practice/addresses.c:17: warning: format ‘%d’ expects typeint’, but argument 3 has typeint *’
/Volumes/MY USB/C Programming/Practice/addresses.c: In function ‘moo’:
/Volumes/MY USB/C Programming/Practice/addresses.c:23: warning: format ‘%d’ expects typeint’, but argument 2 has typeint *’
/Volumes/MY USB/C Programming/Practice/addresses.c:24: warning: format ‘%d’ expects typeint’, but argument 2 has typeint **’
/Volumes/MY USB/C Programming/Practice/addresses.c:24: warning: format ‘%d’ expects typeint’, but argument 3 has typeint *’

你能帮我吗?

谢谢

blargman


2
那些提示是“警告”,而不是“错误”。这意味着您的程序仍将运行。但请根据下面的答案修复这些警告。 - Jim Balter
5个回答

100
你想使用%p来打印一个指针。根据规范:p参数应该是一个指向void类型的指针。指针的值将以一种实现定义的方式转换为一系列打印字符。别忘了进行强制类型转换,例如:
printf("%p\n",(void*)&a);

3
@blargman,是的,这是错误的。你也许可以通过类型转换来强行使代码工作,但因为%d是用于打印有符号整数的,所以它可能不是一个好的选择。 - Carl Norum
8
为了可移植性(并遵循标准中的SHALL),请记得将地址转换为所需类型。 printf(“%p \ n”,(void *)&a); - pmg
3
@pmg,需要使用cast吗?我认为在C语言中,void*的转换是安全且自动的(参见6.3.2.2第1段)。 - Carl Norum
6
在变参函数中,编译器无法对参数的类型与期望的类型进行检查。将参数强制转换为void*并不是自动完成的:在变参函数中自动完成的是将一些低范围整数转换为int,以及将float转换为double - pmg
@Carl:不,我只和表现良好的机器一起工作过。在古老的时代,使用 TurboC(或其他)时,我有几个程序,其中函数指针和数据指针具有不同的大小:sizeof(void(*)()) != sizeof(void*) - pmg
显示剩余8条评论

9
当您想要打印任何变量或指针的内存地址时,使用%d将无法完成任务并导致一些编译错误,因为您试图打印数字而不是地址,即使它能正常工作,您也会有意图错误,因为内存地址不是数字。值0xbfc0d878肯定不是数字,而是地址。
您应该使用%p。例如,
#include<stdio.h>

int main(void) {

    int a;
    a = 5;
    printf("The memory address of a is: %p\n", (void*) &a);
    return 0;
}

祝你好运!


3
0xbfc0d878的值是一个数字。(void*)0xbfc0d878不是数字。而%p格式化符通常使用人类可读的表示形式,看起来像数字(通常是十六进制),但这并不意味着指针就是数字。(顺便说一下,该问题已经在两年前得到回答。) - Keith Thompson
为什么我们需要强制转换为(void*) - Cristian Gutu

1
要打印变量的地址,您需要使用%p格式。 %d用于有符号整数。例如:
#include<stdio.h>

void main(void)
{
  int a;

  printf("Address is %p:",&a);
}

2
虽然这段代码可能回答了问题,但提供有关它如何以及为什么解决问题的额外上下文会提高答案的长期价值。 - Alexander

0

0

我在在线编译器中尝试了一下https://www.onlinegdb.com/online_c++_compiler

int main()
{
    cout<<"Hello World";
    int x = 10;
    int *p = &x;
    printf("\nAddress of x is %p\n", &x); // 0x7ffc7df0ea54
    printf("Address of p is %p\n", p);    // 0x7ffc7df0ea54

    return 0;
}

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