【问题标题】:My pointer/addresses are wrong no matter what I try无论我尝试什么,我的指针/地址都是错误的
【发布时间】:2019-01-01 22:57:36
【问题描述】:

这是我正在尝试的:

int a,b;
int *ptr;

a = 123;
ptr = &a;
b = *ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("&ptr is %p\n",&ptr);
printf("&b is %p\n",&b);

结果:

&a is 0x7ffee01fc828
ptr points to 0x7ffee01fc828
&ptr is 0x7ffee01fc818
&b is 0x7ffee01fc820

我希望 &b 显示与 &a 相同的地址...但事实并非如此,所以我尝试了:

int a,*b;
int *ptr;

a = 123;
ptr = &a;
b = ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("&ptr is %p\n",&ptr);
printf("&b is %p\n",&b);

这仍然会导致 &b 出现意外的内存地址:

&a is 0x7ffee1cbd828
ptr points to 0x7ffee1cbd828
&ptr is 0x7ffee1cbd818
&b is 0x7ffee1cbd820

谁能帮我理解为什么我无法让 &b 与 &ptr 或 &a 匹配相同的地址?

谢谢!

【问题讨论】:

  • 你在比较指针和指针...删除& 你会看到相同的值
  • 因为在 C 中,没有两个不同的对象具有相同的地址。指针也是对象。它们和它们指向的东西不一样,就像一个信封和上面印有地址的房子不同。
  • 请记住,指针只是一个普通变量,它保存其他东西的地址作为它的值。换句话说,一个指针指向可以找到其他东西的地址。您通常会想到一个保存立即值的变量,例如int a = 5;,而指针只会保存5 存储在内存中的地址,例如int *b = &a;。如果您需要存储在b 指向的内存地址的值,您可以使用一元'*' 运算符取消引用 b,例如int c = *b; 将初始化 c = 5)。
  • @rici:与大多数其他编程语言不同,C 中的指针是实际内存地址,而不是对象。它们既不是信封,也不是房子。
  • @RobertHarvey -- 指针是对象,因为指针是内存中保存某些值的位置。 That is what C objects are.

标签: c pointers memory-address


【解决方案1】:

我希望 &b 显示与 &a 相同的地址...

有这种期望意味着您对指针如何工作以及它们在 C 编程语言中的语义有一个错误的心理模型。关键的误解似乎发生在原始代码片段的这两行:

首先你有

b = *ptr;

这一行翻译成*“将地址ptr的内存内容复制到变量b中。”变量b 甚至从未与指针本身接触。你可以把它改写成同样的效果

int tmp = *ptr;
b = tmp;

事实上,每个现代 C 编译器都会为这两种情况生成相同的代码。

你有误解的第二行是这一行

printf("&b is %p\n",&b);

特别是取变量b的地址的效果,即&b的结果。 b 是一个完全独立的变量,有自己的地址。 这个地址不能改变!变量唯一可以改变的是它的值。

指针也是变量,是的,指针本身也有地址。指针的值是它指向的地址。但是像每个变量一样,您无法更改存储变量的地址,并且当您将地址分配给指针时,您正在更改其值。因此,当您在第二个代码片段中分配b = ptr; 时,您将ptr 复制到b。之后,ptrb 都指向同一个地址,但这两个指针是相同值的两个独立副本,每个副本被放置在内存中的不同位置。取b 的地址自然会产生与ptr 的地址不同的东西。

【讨论】:

  • 感谢您深入解释我的误解。当他们解释这些事情时,我正在学习的链接学习课程是有限的,所以我通过试验、错误和 stackoverflow 来弄清楚!
【解决方案2】:

现在 abptr 是 3 个不同的变量(无论它们的类型如何)

所以他们的地址是不同的。通过 not 获取指针变量的 地址,您将获得相同的值。

int a,*b;
int *ptr;

a = 123;
ptr = &a;
b = ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("b is %p\n",b);

【讨论】:

  • 感谢您的澄清!非常感谢您抽出宝贵的时间并言简意赅。
猜你喜欢
  • 2023-04-02
  • 2017-04-21
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2017-10-27
  • 2020-08-11
相关资源
最近更新 更多