3

In my book, it has been written that *p[3] declares p as an array of 3 pointers. I got it. But for (*p)[3] it has been written that (*p)[3] declares p as a pointer to an array of three elements. What does it mean? There is no example for (*p)[3]. Can anybody give me an example of it??

opu 웃
  • 464
  • 1
  • 7
  • 22
  • Arrays in C are just contiguous blocks of memory, one `sizeof` its elements for each. You can have a pointer to this memory. You can also store pointers _in_ this memory. Perhaps the most fun would be a pointer to an array of pointers, `void **p[3]`! Hope it helps. – erik258 Mar 10 '14 at 14:32
  • 1
    [This chapter of the C FAQ](http://c-faq.com/aryptr/index.html) is mandatory reading for everyone, beginners and veterans all alike. 6.13 deals with this specific case. – Lundin Mar 10 '14 at 14:57

8 Answers8

13
int a[3] = {1,2,3};
int (*p)[3];
p=&a;    
printf("%d %d %d",(*p)[0],(*p)[1],(*p)[2]); 

At first you will have to understand the difference between a and &a. Value of both a and &a will be same. But There is huge difference in the meaning of them. Here a represent the first element of an array i.e. &a[0] and &a represent the whole or complete array. If you do a+1 you will find the address of next element in the array i.e. &a[1] but if you perform &a+1, it will give the next address to the complete array i.e. here &a+1 = &a[2]+1. Thus here p=&a means you have assigned the address of an array of size 3 to a pointer p.

Rahul
  • 3,479
  • 3
  • 16
  • 28
5

Example for *p[3]:

int a = 10;
&a; // <-- this is the address of the variable a
int b = 20;
int c = 30;
int *p[3];  // <-- array of three pointers
        // p[0] being the first, p[2] being the last and third
        // p is the address of p[0]
p[0] = &a;
p[1] = &b;  // Stored the addresses of a, b and c
p[2] = &c;

p[0];   // pointer to a

*p[0];  // this is the variable a, it has the value 10

Example for (*p)[3]:

int a[3];   // array of three integers
a[0] = 10;
a[1] = 20;
a[2] = 30;
a;      // address of the very first element, value of which is 10
&a;     // address of the pointer, the address holding variable

int (*p)[3];    // pointer to an array of three integers
p = &a;

// p is a variable
// p points to a
// a is a variable
// a points to a[0], 10
// a, therefore, is a pointer
// p points to a pointer
// p, therefore, is a pointer to a pointer

It was amusing, kind of, to write all this. I hope it also facilitates a better understanding.

Utkan Gezer
  • 3,009
  • 2
  • 16
  • 29
2

Something like this?

int a[3]; // int array of size 3
int (*p)[3]; // pointer to int array of size 3

p = &a; // Make p point to the address of a

a is an array of size 3, it can take three elements. p is declared as a pointer, it shall point to an int array of size 3.

int a;
int *p;

a is an integer. p is a pointer to an integer, not an integer array, a simple integer.

Simplified: Think of a pointer as a variable, it's value is just the address to some other variable. You can specify to what type of variable your pointer may point too, in this case, an int array of size 3.

Jite
  • 4,250
  • 1
  • 17
  • 18
1

Basically:

int *p[3]; // to access a value you need to do
           // *p[1] (take first entry and dereference it)
-------------------------
| first pointer to int  | <- p points here
-------------------------
| second pointer to int |
-------------------------
| third pointer to int  |
-------------------------

int (*p)[3] // to access a value you need to do
            // (*p)[1] (dereference pointer to array and take first value in array)
------------------  \
| first integer  |  |
------------------  |
| second integer |  } p points to the whole array
------------------  |
| third integer  |  |
------------------  /
RedX
  • 14,749
  • 1
  • 53
  • 76
  • in the case of int (*p)[3] you have shown that p points to first integer but it is not so. That why i am downvoting. – Rahul Mar 10 '14 at 14:44
  • @Rahul, p does point there in a physical sense but from an abstraction level you still have to tell him which entry you want from the array. I tried to improve by pointing p to 'before' the array. If you have any idea on how to better represent the abstraction please let me know. – RedX Mar 10 '14 at 14:51
  • in your representation it is showing that p is pointing to first element but actually it represents the whole array.Your representation is confusing. – Rahul Mar 10 '14 at 14:54
1
 (*p)[3] means pointer to the starting element's address of your array.
 *p[3] means an array containing three pointers..
hareesh
  • 53
  • 7
1

Here's one example of where pointers to arrays come up; passing a multi-dimensional array as a function argument.

Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.

So, assume the following code:

int foo[5][5];
bar( foo );

The expression foo in the call to bar has type "5-element array of 5-element array of int"; since foo isn't the operand of the sizeof or unary & operators, it will be converted to an expression of type "pointer to 5-element array of int", or int (*)[5] (in this case, T == "5-element array of int") The definition of bar must then look something like

void bar ( int (*arr)[5] ) { ... }

The parameter arr has type "pointer to 5-element array of int". The parentheses around *arr are necessary because the [] subscript operator has higher precedence than the unary * operator, so an expression like *p[i] is parsed as *(p[i]); you dereference the result of the subscript operation. To force the dereference to happen before the subscript, you need to explicitly group the unary * operator with the identifier: (*p)[i].

In the context of a function parameter declaration, T a[] and T a[N] are treated as T *a; all three declare a as a pointer to T. So you can write your function definition as

void bar ( int arr[][5] ) { ... }

or even

void bar ( int arr[5][5] ) { ... }

In all three cases, arr is a pointer to a 5-element array of int. I prefer writing out the pointer type explicitly, because that's what's actually happening; others prefer using the 2D array syntax because it's easier to read.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0
http://stackoverflow.com/questions/1810083/c-pointers-pointing-to-an-array-of-fixed-size

above link might help you more to understand the concept..

0

For question of (*p)[3].

int b[2][3]={{10,20,30},{40,50,60}};

// two 1-D array of 3 integer values.first array is b[0] second array is b[1].

here b will return a pointer to 1-D array of 3 integers value. b return us int (*)[3].that means pointer one dimentional array of size three.

so *p=b; // is not valid. but (*p)[3]=b; // is valid.

because p as a pointer to an array of three elements

if print p or *p or p[0] or &p[0][0] then it will print 1st element address of first 1-D array.

if print p+1 or *(p+1) or p[1] or & p[1][0] then it will print 1st element address of 2nd 1-D array.

Syed Waqas Bukhary
  • 5,130
  • 5
  • 47
  • 59