-1
int i[5]={0,1,2,3,4,};
int *ip=&i[0];
printf("%d,%d,%d,%d,%d,%d,%d,%d",*ip,ip,&ip,&i,&i[0],i,i[0],*(&i));

The output of above piece of code that I got in my comp is

0,2358832,2358824,2358832,2358832,2358832,0,2358832

Observe that both ip=&i=2358832 but *ip=0 and *(&i)=2358832. How can one address, in this case 2358832, have two values?

hmatt1
  • 4,939
  • 3
  • 30
  • 51
Hari
  • 121
  • 1
  • 18

3 Answers3

4
int i[5]={0,1,2,3,4,};
int *ip=&i[0];
printf("%d,%d,%d,%d,%d,%d,%d,%d",*ip,ip,&ip,&i,&i[0],i,i[0],*(&i));

First of all, it is a mistake to format an address using %d. Use %p for that. You get away with it because your addresses happen to be 4 byte integers, the same size of your platform's int type.

Let's go through this one at a time:

  • *ip is the same as i[0].
  • ip contains the address of the first element of the array, which is also the address of the array because the array begins with its first element.
  • &ip contains the address of the variable ip.
  • &i contains the address of the array, the same address as held in ip, see above.
  • &i[0] is again the same as ip.
  • i is the array, which decays to a pointer, so has the same value when treated as an address as ip, &i[0].
  • i[0], well you know what that is.
  • *(&i) is the same as i, see above.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • But i is a pointer right. Pointers themselves have addresses(Just like ip in this case, has an address). So how can i and the first element of the array share the same address? @ http://stackoverflow.com/users/505088/david-heffernan – Hari Oct 01 '14 at 20:27
  • @HariprasadRamakrishnan No, i is an array. Its size is 5 ints, not one address. David gets that wrong, too: &i has the same numerical value as ip, because ip happens to point to the first element of the array, but &i is a pointer to array. Dereferencing it gives back the array; dereferencing ip gives back an int. – Peter - Reinstate Monica Oct 01 '14 at 20:32
  • @PeterSchneider What I mean is that the address of the array is the same as the address held in the pointer `ip`. I don't mean that `&i` is the same thing as `ip`. – David Heffernan Oct 01 '14 at 20:34
  • @DavidHeffernan But many textbooks state: As an array i is defined, a pointer i is also automatically defined pointing to the array's first element. Whats ur view on that? – Hari Oct 01 '14 at 20:36
  • 1
    I doubt that any textbooks state that. You could read this link: http://stackoverflow.com/questions/1461432/what-is-array-decaying – David Heffernan Oct 01 '14 at 20:39
  • @HariprasadRamakrishnan many textbooks are wrong – M.M Oct 01 '14 at 20:42
  • @HariprasadRamakrishnan: Any textbook that actually says that is wrong; no storage is set aside for a pointer object separate from the array elements themselves. During translation, the compiler will replace the array expression with a pointer expression that evaluates to the address of the first element (unless the array expression is the operand of the `sizeof` or unary `&` operators). – John Bode Oct 01 '14 at 20:44
  • Like many say Arrays are constant pointers. Whats your view on that? – Hari Oct 01 '14 at 20:47
  • That's nonsense. Where are you getting all this from? – David Heffernan Oct 01 '14 at 20:51
  • @HariprasadRamakrishnan: **Arrays are not pointers, `const` or otherwise**. Ever. Array *expressions* will be converted to pointer expressions under certain circumstances, but that doesn't make arrays and pointers the same thing. See the [online C 2011 standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), section 6.3.2.1, paragraph 3. – John Bode Oct 01 '14 at 20:51
  • Thank you everyone. Though I fully didn't understand Arrays decaying into pointers, I got that there is no pointer declared as such in the array's name, following array's declaration; only arrays's name is synonymous with &(name of arrays first element.). Special thanks to @DavidHeffernan :) – Hari Oct 01 '14 at 20:57
  • 1
    @HariprasadRamakrishnan: You might want to read [this document](http://cm.bell-labs.com/who/dmr/chist.html), especially the section titled "Embryonic C", to understand what's happening with arrays. – John Bode Oct 01 '14 at 20:59
2

I'll try to explain with help of diagram.

int i[5]={0,1,2,3,4,};
int *ip=&i[0];

After this code we have two variables: array i of 5 ints and pointer ip which points to first element of array i (i.e. contains the address of first element of array i). Let's see how these variables are laid out in memory (for this diagram I assume that ints have size 4 and pointers have size 8, on your system it can be different, but for your question it doesn't matter now):

enter image description here

Now let's have a look at printf arguments and explain them using diagram:

  • *ip - "Take the value of variable ip - 2358832 - and, interpreting this value as address, get the value of type int (because ip has type int *) which is stored at this address - 0";
  • ip - "Get the value of variable ip - 2358832";
  • &ip - "Get the address of variable ip - 2358824";
  • &i - "Get the address of variable i - 2358832";
    • Note 1: variable usually occupies more than one memory cell, in such case "address of variable" means address of first memory cell which is occupied by this variable => variable i occupy many cells but have address "2358832" - address of its first cell;
    • Note 2: variable ip occupies more than one cell too (8 on our diagram)
  • &i[0] - "Get the address of first element of array i - 2358832";
  • i - "Get the value of variable i - ?". This one is tricky. When compiler requested to get "value of array", compiler gets the address of first element of this array. Usually it is called "array decays to pointer". So in our case i => &i[0] => 2358832 (see above);
  • i[0] - "Get the value of first element of array i - 0";
  • *(&i) - two steps:
    • &i => 2358832 (see above). Note that this intermediate value (as any other value!) has type. In this case type is int (*)[5] - pointer to array.
    • *(&i) - "Get the value of array which is stored at address 2358832". As we already know, "value of array" means the address of first element of this array - 2358832.
kotlomoy
  • 1,420
  • 8
  • 14
0

What puzzles you is that after

int i[5]={0,1,2,3,4,};
int *ip=&i[0];

"both ip=&i=2358832 but *ip=0 and *(&i)=2358832. How can one address, in this case 2358832, have two values?".

Two expressions each yield an address with the same numerical value. How can there be different values stored at the same address, as proven by printing the result of dereferencing these same addresses?

The answer must lie, if you think of it, in the type of ip vs &i (and printf's weak type checking). It's related to one of the subtleties of the C/C++ (hi Lundin) type system. Often an array "decays", as the lingo goes, to a pointer to its first element. That's why you can pass i to a function that takes a pointer (e.g. printf), or add 1 to it and get the address of the next element, or simply dereference it like *i.

Taking the address of an array is one of the cases where it does not decay. It stays an array; &i has the type "pointer to array", not "pointer to int". The array shares its address with its first element, so the numerical values are identical. But what the compiler does with the pointer is different:

Dereferencing &i gives you the array back, like with any other type; and what happens when you pass that to a function like printf? Finally it decays to a pointer to its first element, which happens to be at the well-known address 2358832.

It may become clearer if you imagine a struct in place of the array; the two are related (a struct is also a series of objects, only of different types). A pointer to the first struct member has surely a different meaning than a pointer to the struct, although they as surely have the same numerical value.

Or take the following little (strictly spoken, undefined behaviour) program which shows that the same address can carry "different values", depending on what you tell the compiler to do with the data there:

#include<stdio.h>
int main()
{
    unsigned int sixpointo = 1086324736;
    float *fp = (float *)&sixpointo;
    printf("&sixpointo: %p, fp: %p, sixpointo: %d, *fp: %f\n", 
            &sixpointo,     fp,     sixpointo,     *fp);
    return 0;
}
Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62