获取C中指针的地址,带和不带&符号,有什么区别?

Nak*_*ala 1 c pointers

我很难理解本指南关于 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;
Run Code Online (Sandbox Code Playgroud)

Dav*_*ica 5

指针只是一个普通变量,它将其他事物的地址作为其值。换句话说,一个指针指向可以找到其他东西的地址。在您通常认为保存立即值的变量的地方,例如int a = 5;,指针将简单地保存5存储在内存中的地址,例如int *b = &a;

作为一个普通变量,指针本身有一个地址。它的地址是变量本身的地址,而不是它存储的地址。例如,char buf[] = "foo", *p = buf;创建一个数组buf并将第一个字符 inbuf地址 分配为所持有的地址p(例如p指向 in 中的第一个字符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);
}
Run Code Online (Sandbox Code Playgroud)

示例使用/输出

$ ./bin/pointeraddr
address for buf      : 0x7fffbfd0e530
address of 1st char  : 0x7fffbfd0e530
address held by p    : 0x7fffbfd0e530
address for p itself : 0x7fffbfd0e540
Run Code Online (Sandbox Code Playgroud)

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

内存中存储的字符数组 在哪里buf

    +---+---+---+---+
    | f | o | o | \0|   buf - array of char
    +---+---+---+---+
      5   5   5   5
      3   3   3   3
      0   1   2   3
Run Code Online (Sandbox Code Playgroud)

访问数组时,数组被转换为指向第一个元素的指针,如下所示:

(p3) 除非它是运算sizeof符的操作数、运算 _Alignof符或一元运算'&'符,或者是用于初始化数组的字符串文字,否则类型为类型 数组”的表达式将转换为类型为的表达式”指向类型的指针”,它指向数组对象的初始元素,而不是左值。

C11 标准 - 6.3.2.1 其他操作数 - 左值、数组和函数指示符 (p3)

数组中的第一个字符是什么buf?(答案buf[0]:)第一个字符的地址是什么(使用一元运算'&'符)?它与 buf 的地址相同,但具有指向 char的类型指针(与buf访问时是指向数组指针相同char[4]

怎么样p?它有自己的地址,其中buf存储了第一个字符的地址,例如

    +---+  p - pointer to char
    | 5 |
    | 3 |  holds the address 0x7fffbfd0e530
    | 0 |
    +---+
      5
      4    stored at 0x7fffbfd0e540
      0
Run Code Online (Sandbox Code Playgroud)

您如何获得 持有的地址处的值(字符)p?您使用一元解引用运算符*p。你如何获得持有的地址pp已经是一个指针,所以简单地评估p自身给出由 持有的地址p,例如

char *q = p;
Run Code Online (Sandbox Code Playgroud)

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

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

printf ("address held by p & q : %p\n", (void*)p);
Run Code Online (Sandbox Code Playgroud)

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

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