【问题标题】:Obtaining address of pointer in C with and without ampersand, what's the difference?在C中获取带有和不带有&符号的指针地址,有什么区别?
【发布时间】:2018-12-01 05:45:21
【问题描述】:

我很难理解this guide's code on pointers in C。我认为您需要一个&符号来引用指针的地址,但指南的代码设法在没有它的情况下获得它。我用我评论为“我的添加行”的一项更改修改了他们的代码。该行与其上方的行相同,但包含一个&符号。这些行的评估产生非常相似的值,但不是相同的值。我的逻辑哪里去了?

谢谢, 纳库尔

  #include <stdio.h>

int main () {

   int  var = 20;   /* actual variable declaration */
   int  *ip;        /* pointer variable declaration */

   ip = &var;  /* store address of var in pointer variable*/

   printf("Address of var variable: %x\n", &var  );

   /* address stored in pointer variable */
   printf("Address stored in ip variable: %x\n", ip );

  /* MY ADDED LINE: address stored in pointer variable */
   printf("Address stored in ip variable: %x\n", &ip );


   /* access the value using the pointer */
   printf("Value of *ip variable: %d\n", *ip );

   return 0;

【问题讨论】:

  • “这些行的评估产生非常相似的值,但不是相同的值。”可能是因为varip 在堆栈上彼此靠近。
  • 行不一样。那里有一个&符号。你期待var == &amp;var吗?为什么不?那你为什么会期待ip == &amp;ip? (提示:相同的答案。)
  • 感谢您的洞察力。我现在明白指针变量本身有一个地址。

标签: c pointers


【解决方案1】:

指针只是一个普通变量,它保存着其他东西的地址作为它的值。换句话说,一个指针指向可以找到其他东西的地址。通常你会想到一个保存立即数的变量,例如int a = 5;,而指针只会保存5 存储在内存中的地址,例如int *b = &amp;a;.

作为一个普通变量,指针本身有一个地址。它的地址是变量本身的地址,而不是它存储的地址。例如,char buf[] = "foo", *p = buf; 创建一个数组 buf 并将 buf 中第一个字符的地址分配为 p 持有的地址(例如,p 指向buf)。但是p 本身在内存中有一个地址。它位于p 的地址,buf 中第一个字符的地址保存在内存中。一个简短的例子可能会有所帮助:

#include <stdio.h>

int main (void) {

    char buf[] = "foo",
        *p = buf;

    printf ("address for buf      : %p\n"
            "address of 1st char  : %p\n"
            "address held by p    : %p\n"
            "address for p itself : %p\n",
            (void*)buf, (void*)&buf[0], (void*)p, (void*)&p);
}

使用/输出示例

$ ./bin/pointeraddr
address for buf      : 0x7fffbfd0e530
address of 1st char  : 0x7fffbfd0e530
address held by p    : 0x7fffbfd0e530
address for p itself : 0x7fffbfd0e540

现在让我们仔细看看指针保存的内容和指针地址(指针保存在内存中的位置)为简单起见,我们只使用地址中的最后三个数字。

char数组buf在内存中存储在哪里?

    +---+---+---+---+
    | f | o | o | \0|   buf - array of char
    +---+---+---+---+
      5   5   5   5
      3   3   3   3
      0   1   2   3

当访问一个数组时,数组被转换为指向第一个元素的指针,受以下约束:

(p3) 除非它是sizeof 运算符的操作数,否则 _Alignof 运算符,或一元 '&amp;' 运算符,或者是 字符串 字面量 用于初始化一个数组,一个具有类型的表达式 "array of type" 被转换为一个类型为 "pointer to type" 的表达式,它指向数组对象的初始元素并且是 不是左值。

C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

数组buf 的第一个字符是什么? (答案:buf[0]) 第一个字符的地址是什么(使用一元'&amp;' 运算符)?它与 buf 的地址相同,但类型为 pointer to char(与 buf 相对,在访问时是 char[4]pointer to array )

p 呢?它有自己的地址,用于存储buf 中第一个字符的地址,例如

    +---+  p - pointer to char
    | 5 |
    | 3 |  holds the address 0x7fffbfd0e530
    | 0 |
    +---+
      5
      4    stored at 0x7fffbfd0e540
      0

如何获取p持有的地址的值(字符)?您使用一元 dereference 运算符 *pp持有的地址怎么获取? p 已经是一个指针,所以简单地评估 p 本身就可以得到 p 持有的地址,例如

char *q = p;

q 现在保存由p 保存的地址,该地址存储在内存中创建q 的新地址中。

或者,非常简单,打印p 现在也由q 持有的地址,只需将p(或q)转换为(void*) 并使用"%p" 打印转换说明符,例如

printf ("address held by p & q : %p\n", (void*)p);

没有魔法。指针只是一个变量,它保存其他东西的地址作为它的值。与任何变量一样,它都有自己的地址。如果你这样想,你总能弄清楚你有什么——以及你需要做什么才能获得存储在该地址的值。

检查一下,如果您还有其他问题,请告诉我。

【讨论】:

  • 非常感谢您的解释。这是非常彻底的,我很感激。这下全说通了。指针变量本身有一个地址。指针的值是它所指向的地址。解引用运算符告诉您它所指向的值。
  • 是的,你明白了!我很高兴它有帮助。这就是我与指针和平相处的方式——我希望更多的教程能像这样分解它。它有助于。祝你编码顺利。
【解决方案2】:

逻辑走向南方,因为“&”给了你一个指针(在你的例子中是一个指向指针的指针)。让我用正确的术语调整你的代码,然后它就会变得清晰:

printf("Address stored in ip variable, pointing to
    the memory location of var: %x\n", ip );

printf("Address pointing to the (memory location / address)
    of pointer ip which itself contains the (memory location / 
    address) of var: %x\n", &ip );

【讨论】:

  • 感谢您的澄清!我现在知道了。谢谢!
【解决方案3】:

你用过

int var = 20;
int *ip;
ip = &var;

你打印了&amp;var, ip, &amp;ip *ip

这里&amp;varip会表示保存20的内存地址。 而*ip 将指示值 20。 你想要的最重要的东西是&amp;ip。 当int *ip 被调用时,这个变量的内存区域将被创建。 所以ip 占用了一些内存区域。 当你打印&amp;ip时,这将指示保存ip(contains the address of var)的内存地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多