0
int s[4][2]= {
             {1234,56},
             {1212,33},
             {1434,80},
             {1312,78}
             };
int i,j;
for(i=0;i<=3;i++)
{
    printf("\n");
    for(j=0;j<=1;j++)
    {
        printf("%d  ",*(s[i]+j));
    }
}

Output Showing is

1234,56
1212,33
1434,80
1312,78

As we know *(&Variable) will print the Value of the Variable But when We implement the same concept in above program...

int s[4][2]= {
             {1234,56},
             {1212,33},
             {1434,80},
             {1312,78}
             };
int i,j;
for(i=0;i<=3;i++)
{
    printf("\n");
    for(j=0;j<=1;j++)
    {
        printf("%d  ",*(&s[i]+j));
    }
}

output is showing the Address of each element of array.

Why this is happening? Why Output is not equal to value of elements of Array??

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261

3 Answers3

2

Notice here, s is a two dimensional array, and array names decay to pointer to the first element, in certain cases.

Here, s[i] is of type array, array of two ints.

Then, quoting C11, chapter §6.3.2.1,

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

Thus,

  • In the first case,

    *(s[i]+j)
    

    s[i] is of type int [2], which decays to an int *, which is used in the pointer arithmetic, producing another int *. After the dereference, you get an int.

  • In the second case,

    *(&s[i]+j)
    

    due to the same aforesaid reason, in case of &s[i], s[i] does not decay, and the type is "pointer to int [2]" and the pointer arithmetic works on that. So, in this case, the result of the addition is also "pointer to int [2]" and after the final dereference, it becomes int *, which is the mismatch for %d and that is what reported by your compiler.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Your array is bi-dimensional. So, s[i] is the address of line i (i.e. s[i] is of type int *), and &s[i] is an address of an address (i.e. of type int **). When you apply * on it, you get an address (i.e. int *).

It is true that the operator & means "address-of" and *(&x) refers to the value of x.

AhmadWabbi
  • 2,253
  • 1
  • 20
  • 35
  • Thanks I think It is accurate for the Question asked – Kunal Verma Sep 21 '16 at 17:55
  • "s[i] is of type int *" NO. `s[i]` is of type `int [2]`, an array type, which can be implicitly converted to `int *` in certain contexts. "and &s[i] is an address of an address (i.e. of type int **)" NO. `&s[i]` is of type `int (*)[2]`, a pointer-to-array type. "When you apply * on it, you get an address (i.e. int *)" Again, no. You get `int [2]`, which can be implicitly converted to `int *` in certain contexts. – newacct Sep 22 '16 at 00:20
  • @newacct LOL. ok. But I prefer saying things simply (but not %100 accurate) for a beginner to understand easily rather than saying accurate yet complex answers. Also, this distinction between `int [2]` and `int *` is somehow "logical", and IMHO, not worth mentioning in the answer of this question, as @Kunal talks about addresses in his question. – AhmadWabbi Sep 22 '16 at 08:26
  • @newacct You can see that the answer satisfied the PO more than "real accurate" answers. – AhmadWabbi Sep 22 '16 at 08:32
0

First case

Your print statement is this.

printf("%d  ",*(s[i]+j));

Here s[i]+j is the address.

lets consider i=0,j=1 , first i loop, second j loop.

here s[i] will be the address in which value 1234 is residing. lets say it is 489000. so s[i]+j , here s[0]+1 will be the address at which value 56 is residing. lets say it is 489004

So, *(s[i]+j) ,ie; here *(s[0]+1) will be giving the value at address 489004. ie 56. So here it will print the values 1234, 56, 1212 etc.

Second Case Your print statement is this.

printf("%d  ",*(&s[i]+j));

Here &s[i]+j is the address.

lets consider i=0,j=0 , first i loop, first j loop.

here s[i] will be the address in which value 1234 is residing. Lets say it is 489000. So &s[i] will be the address in which address 489000 is residing. Lets say it is 380000. Recall the concepts of pointer's.

So &s[i]+j will be "address in which address 489000 is residing + j" . ie; 380000+j

we are applying a value at operator * on this particular 'address' we got. *(&s[i]+j). So it becomes, Value at['address in which address 489000 is residing' + j]. Value at[380000 + j].

when i=0,j=0, it will print, Value At[380000] , ie; 489000.

So it will print the address in which the values 1234, 56 , 1212 etc are stored.

Shijo Joseph
  • 162
  • 1
  • 11