简体   繁体   English

在带有和不带有“&”号的情况下获取C中指针的地址,有什么区别?

[英]Obtaining address of pointer in C with and without ampersand, what's the difference?

I am having difficulty understanding this guide's code on pointers in C . 我很难理解本指南中有关C指针的代码 I thought that you needed an ampersand to reference the address of a pointer, but the guide's code manages to obtain it without one. 我以为您需要一个&符来引用一个指针的地址,但是指南的代码设法在没有一个的情况下获得了它。 I modified their code with one change which I've commented as"MY ADDED LINE". 我修改了他们的代码,做了一次更改,我将其注释为“我的添加的行”。 That line is identical to the line above it, but with the inclusion of an ampersand. 该线与上方的线相同,但带有“&”号。 The evaluations of these lines produce very similar values, but not identical values. 这些行的评估会产生非常相似的值,但不会产生相同的值。 Where is my logic going south? 我的逻辑往哪里去?

Thanks, Nakul 谢谢Nakul

  #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;

A pointer is simply a normal variable that holds the address of something else as its value. 指针只是一个普通变量,将其他地址作为其值。 In other words, a pointer points to the address where something else can be found. 换句话说,一个指针指向可以找到其他内容的地址。 Where you normally think of a variable holding an immediate values, such as int a = 5; 通常您会想到一个包含立即数的变量,例如int a = 5; , a pointer would simply hold the address where 5 is stored in memory, eg int *b = &a; ,指针将仅保存内存中存储5的地址,例如int *b = &a; .

Being a normal variable, a pointer itself has an address. 作为普通变量,指针本身具有地址。 It's address is the address for the variable itself, not the address it stores. 它的地址是变量本身的地址,而不是变量存储的地址。 For example, char buf[] = "foo", *p = buf; 例如, char buf[] = "foo", *p = buf; creates an array buf and assigns the address for the first character in buf as the address held by p (eg p points to the first character in buf ). 创建一个数组buf和用于在第一个字符分配地址buf由保持地址 p (例如p指向的第一个字符在buf )。 But p itself has an address in memory. 但是p本身在内存中有一个地址。 It is at the address for p where the address for the first character in buf is held in memory. 它是p的地址, buf第一个字符的地址保存在内存中。 A short example may help: 一个简短的示例可能会有所帮助:

#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);
}

Example Use/Output 使用/输出示例

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

Now let's look closer at what a pointer holds and the pointer address (where what the pointer holds is held in memory) Let's just use the last three numbers in the addresses for simplicity. 现在,让我们仔细看看指针的内容和指针地址(指针的内容保存在内存中)。为简单起见,我们仅使用地址中的最后三个数字。

Where is the array of char buf stored in memory? char buf 数组存储在内存中的什么位置?

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

When accessing an array, the array is converted to a pointer to the first element subject to the following: 访问数组时,该数组将转换为指向第一个元素的指针,但要遵循以下条件:

(p3) Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary '&' operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. (p3)除非它是sizeof运算符, _Alignof运算符或一元'&'运算符的操作数,或者是用于初始化数组的字符串文字 ,否则类型为“ array of type”的表达式将转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,而不是左值。

C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) C11标准-6.3.2.1其他操作数-左值,数组和函数指示符(p3)

What is the first character in the array buf ? buf数组中的第一个字符是什么? (answer: buf[0] ) What is the address of the first character (using the unary '&' operator)? (答案: buf[0] )第一个字符的地址是什么(使用一元'&'运算符)? It is the same as the address of buf, but has the type pointer to char (as apposed to buf which on access is a pointer to array of char[4] ) 它与buf的地址相同,但具有指向char的类型指针 (与buf并置,后者在访问时是指向 char[4] 数组指针

What about p ? p呢? It has its own address where the address to the first character in buf is stored, eg 它有自己的地址,用于存储buf第一个字符的地址,例如

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

How do you get the value (character) at the address held by p ? 如何获得p持有的地址中的值(字符)? You use the unary dereference operator *p . 您使用一元解引用运算符*p How do you get the address held by p ? 您如何获得p持有的地址? p is already a pointer, so simply evaluating p itself gives the address held by p , eg p已经是一个指针,因此简单地评估p本身就可以得到p持有的地址,例如

char *q = p;

q now holds the address held by p stored at the new address where q is created in memory. q现在保存由p存储的地址,该地址存储在内存中创建q的新地址处。

Or, very simply, to print the address held by p now also held by q , simply cast p (or q ) to (void*) and print with the "%p" conversion specifier , eg 或者,非常简单地,要打印现在也由q持有的p的地址,只需将p (或q )转换为(void*)并使用"%p" 转换说明符进行打印,例如

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

No magic. 没魔术 A pointer is simply a variable that holds the address of something else as its value. 指针只是一个变量,将其他内容的地址作为其值。 As with any variable, it has an address all its own. 与任何变量一样,它具有自己的地址。 If you think about it that way, you can always figure out what you have -- and what you need to do to get the value stored at that address. 如果您以这种方式考虑,则始终可以弄清楚所拥有的东西以及需要做什么才能获取存储在该地址的值。

Look things over and let me know if you have further questions. 仔细检查一下,如果您还有其他问题,请告诉我。

The logic goes south because "&" gives you a pointer (in your case a pointer to the pointer). 逻辑向南,因为“&”为您提供了一个指针(在您的情况下为指向该指针的指针)。 Let me adjust your code with the correct terminology, then it should become clear: 让我用正确的术语来调整您的代码,然后它应该变得清楚:

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 );

you used 你用过

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

and you printed &var, ip, &ip *ip 并且您打印了&var, ip, &ip *ip

Here &var and ip will indicate the address of the memory where 20 is saved. 在这里, &varip将指示保存20的内存地址。 And *ip will indicate the value 20. And the most important thing what you wanted is &ip . *ip将指示值20。最重要的是&ip When int *ip is called, the memory region for this variable will be created. 调用int *ip ,将创建此变量的存储区。 so ip occupy some memory region. 所以ip占用一些内存区域。 When you print &ip , then this will indicate the memory address where ip(contains the address of var) is saved. 当您打印&ip ,这将指示ip(contains the address of var)保存在的内存地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM