0

Suppose mat is a pointer to an array of size 5 where each element is an integer

int (*mat)[5];

and I have initialized it as

int a[5] = {5, 4, 3, 2, 1};
mat = &a;

I've written the code as

#include <stdio.h>

int main()
{
    int (*mat)[5];
    int a[5] = {5, 4, 3, 2, 1};
    mat = &a;
    printf("%p\n%p\n%d\n", mat, *mat, **mat);
    return 0;
}

Output:

43800  
43800  
5

Why does mat and *mat give the same answer?

Student
  • 807
  • 1
  • 8
  • 11
metasj
  • 65
  • 1
  • 7
  • 2
    Possible duplicate of [What is array decaying?](https://stackoverflow.com/questions/1461432/what-is-array-decaying) – JGroven Aug 08 '18 at 17:07
  • @JGroven Array decaying means that, when an array is passed as a parameter to a function, it's treated identically to ("decays to") a pointer. However, there is no any passing case ?? – snr Aug 08 '18 at 17:11
  • @snr I was under the impression that array decaying is the implicit conversion from array to pointer, and that using an array as a parameter is merely a demonstration of decay. – JGroven Aug 08 '18 at 17:19
  • @JGroven ((: just was kidding, Thank you for explanation freshman – snr Aug 08 '18 at 17:22
  • 1
    Arrays decay to pointers in nearly every case. The two exceptions are the `sizeof` and the `&` operator. – Osiris Aug 08 '18 at 17:23

3 Answers3

2

A picture may help:

     +---+            +---+
mat: |   | ------> a: | 5 | a[0]
     +---+            +---+
                      | 4 | a[1]
                      +---+
                       ...
                      +---+
                      | 1 | a[4]
                      +---+

So, first thing we notice - the address of the array a is the same as the address of the array element a[0]. The expression a has type "5-element array of int"; unless that expression is the operand of the sizeof or unary & operators, it is converted ("decays") to an expression of type "pointer to int", and the value of the expression is the address of the first element of the array. Thus, the expressions &a, a, and &a[0] will all yield the same value (address of the first element of a), even though they're not all the same type (int (*)[5], int *, int *).

So, given the above, all of the following are true:

  mat == &a 
 *mat ==  a
**mat ==  a[0] 

Since &a and a evaluate to the same address, mat and *mat evaluate to the same value.

John Bode
  • 113,266
  • 18
  • 112
  • 190
1

Quite simply, the address of an array is the same as its first element's. In this context, *mat is of type int[5] which decays to int *, i.e. a pointer to the first element of the array.

Quentin
  • 60,592
  • 7
  • 125
  • 183
FatalError
  • 50,375
  • 14
  • 97
  • 115
  • if I have an array int a[5], a is an integer pointer containing &a[0],but what is the address of a? – metasj Aug 08 '18 at 17:11
  • @metasj `&a` and `&a[0]` have a different type. `a` is of type `int[5]`. `&a[0]` is of type `int *`. `&a` is of type `int (*)[10]`. Arrays are not pointers. – Osiris Aug 08 '18 at 17:15
  • @metasj `a` is not an integer pointer but it will evaluate as an integer pointer in most kinds of expressions. – Ian Abbott Aug 08 '18 at 17:36
0

mat is a pointer to array 5 of int.

*mat is an array 5 of int.

Arrays such as *mat, when pass to functions are converted in "... to an expression with type pointer to type that points to the initial element of the array object...". C11 §6.3.2.1 3

*mat in printf("%p\n",*mat); is a pointer to an int.


"Why does mat and *mat give the same answer?"

These both point to the same memory location. mat points to the array. In printf(), *mat points to the first array element, an int.

As pointers, mat and *mat point to very different types. They could have employed different presentation (even size) and yielded different text output, yet their values are equivalent. This difference is uncommon.


Further, "%p" expects a void*. Use a void* cast for portable code.

printf("%p\n%p\n",mat,*mat);  // undefined behavior
printf("%p\n%p\n",(void*) mat,(void*) *mat);
chux - Reinstate Monica
  • 127,356
  • 13
  • 118
  • 231