简体   繁体   中英

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 . 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

  #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; , a pointer would simply hold the address where 5 is stored in memory, eg 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; 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 ). But p itself has an address in memory. It is at the address for p where the address for the first character in buf is held in memory. 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?

    +---+---+---+---+
    | 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.

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

What is the first character in the array buf ? (answer: buf[0] ) What is the address of the first character (using the unary '&' operator)? 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] )

What about p ? It has its own address where the address to the first character in buf is stored, eg

    +---+  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 ? You use the unary dereference operator *p . How do you get the address held by p ? p is already a pointer, so simply evaluating p itself gives the address held by p , eg

char *q = p;

q now holds the address held by p stored at the new address where q is created in memory.

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

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

Here &var and ip will indicate the address of the memory where 20 is saved. And *ip will indicate the value 20. And the most important thing what you wanted is &ip . When int *ip is called, the memory region for this variable will be created. so ip occupy some memory region. When you print &ip , then this will indicate the memory address where ip(contains the address of var) is saved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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