# How do Ar­rays Decay into Point­ers?

## This ar­ti­cle is for C pro­gram­ming new­bies and en­thu­si­asts. It deals with how ar­rays are passed as pa­ram­e­ters to a func­tion de­cays into point­ers.

OpenSource For You - - CONTENTS -

Many new­bies to the C world are of­ten con­fused about pass­ing an ar­ray as the pa­ram­e­ter to a func­tion. They find it dif­fi­cult to de­cide whether it is done us­ing the ‘pass by value’ or ‘pass by ref­er­ence’ pa­ram­e­ter pass­ing mech­a­nism. This ar­ti­cle ex­plains how the ar­rays are passed to the func­tion and why this is so.

Ex­am­ple 1: ‘An ar­ray name as a func­tion pa­ram­e­ter is a pointer’

In this ex­am­ple, con­sider 1-D ar­ray to ex­plain the mean­ing of the above state­ment with the help of the demo codes. Con­sider Code 1, which con­tains a func­tion called dis­play() to dis­play the el­e­ments of the ar­ray.

1 #in­clude <stdio.h> 2 3 void dis­play(int num­bers[], int size); 4 5 int main() 6{ 7 //De­fi­na­tion of an ar­ray 8 int num­bers[] = {10, 20, 30, 40, 50}; 9 10 //Call­ing dis­play func­tion, to print the el­e­ments 11 dis­play(num­bers, sizeof(num­bers) / sizeof(num­bers[0])); 12 13 re­turn 0; 14 } 15 16 //Func­tion def­i­ni­tion 17 void dis­play(int num­bers[], int size) 18 { 19 int i; 20 for (i = 0; i < size; i++) 21 { 22 printf(“The value @ ad­dress: %p: %d\n”, &num­bers[i], num­bers[i]); 23 } 24 }

Code 1: This code is to demon­strate how ar­rays are passed to func­tions

From Code 1, when­ever ar­rays are passed as the ar­gu­ments to func­tions, they are al­ways passed by us­ing the ‘Pass by ref­er­ence’ mech­a­nism. Be­cause of this, they will decay into point­ers in the func­tion pa­ram­e­ters. In Line 17 of Code 1, In main func­tion, the name of ar­ray (num­bers) which con­tains the base ad­dress of the ar­ray (num­bers) is passed to the func­tion called the dis­play, and col­lected us­ing the pa­ram­e­ter called num­bers, which is noth­ing but the pointer to the base ad­dress of the ar­ray (num­bers) de­fined in the main func­tion. The func­tion dis­play() is equiv­a­lent to the code shown be­low.

void dis­play(int *num­bers, int size);

The def­i­ni­tion of the dis­play is also given in Code 2.

1 //Func­tion def­i­ni­tion 2 void dis­play(int *num­bers, int size) 3{ 4 int i; 5 for (i = 0; i < size; i++) 6 { 7 printf("The value @ ad­dress: %p: %d\n", &num­bers[i], num­bers[i]); 8 } 9}

Code 2

The two dec­la­ra­tions of the func­tion dis­play shown in Code 1 and Code 2 look dif­fer­ent from the pro­gram­mer’s per­spec­tive, but from the com­piler’s view­point, both are one and the same. The stan­dard spec­i­fies that a pa­ram­e­ter in the func­tion dec­la­ra­tion, which is of ‘ar­ray of type(T)’ shall be de­cayed to ‘pointer to type(T)’.

Note 1: An ar­ray name in the dec­la­ra­tion of a func­tion pa­ram­e­ter is treated by the com­piler as a pointer to the first el­e­ment of the ar­ray.

void dis­play(int num­bers[], int size); void dis­play(int num­bers[5], int size);

In the code given above, all the func­tion dec­la­ra­tions are equiv­a­lent. One can call the func­tion dis­play with an ar­ray, with a pointer or with its ac­tual ar­gu­ment. In all the three pro­to­types, the func­tion pa­ram­e­ter (num­bers) will decay into the ‘Pointer to the first el­e­ment of an ar­ray’.

Ex­am­ple 2

Con­sider the ex­am­ple of a 2D ar­ray, to ex­plain how it will decay into the ‘Pointer to an ar­ray’, when passed to the func­tion. Let us start with a demo code as shown in Code 3:

1 #in­clude <stdio.h> 2 #de­fine ROW 3 3 #de­fine COL 2 4 5 int main() 6{ 7 int ar­ray[ROW][COL]; 8 pop­u­late(ar­ray); 9 10 //Some code here 11 } 12 13 void pop­u­late(int ar­ray[ROW][COL]) 14 { 15 //Some code here 16 }

Code 3: Code to demon­strate how 2D ar­rays are passed to func­tions

From the ex­am­ple shown in Code 3, when the 2D ar­ray of type(T) is passed as a pa­ram­e­ter to the func­tion, it will decay into the ‘Pointer to an ar­ray’, as shown in Line 13 of Code 3. Code 3 shows a straight­for­ward way of pass­ing the 2D ar­rays to the func­tion, which means declar­ing them ex­actly the same way as de­clared in the call­ing func­tion.

1 #in­clude <stdio.h> 2 #de­fine ROW 3

3 #de­fine COL 2 4 5 int main() 6{ 7 int ar­ray[ROW][COL]; 8 pop­u­late(ar­ray); 9 10 //Some code here 11 } 12 13 void pop­u­late(int (*ar­ray)[COL]) 14 { 15 //Some code here 16 }

Code 4: Code to demon­strate how 2D ar­rays are passed to func­tions

As far as we are con­cerned, with the equiv­a­lence between point­ers and ar­rays, when ar­rays are passed as an ar­gu­ment to a func­tion, what re­ally gets passed is a pointer to the ar­ray’s first el­e­ment. When we de­clare a func­tion that ac­cepts an ar­ray as a pa­ram­e­ter, the com­piler sim­ply com­piles the func­tion as if that pa­ram­e­ter were a pointer, since a pointer is what it will ac­tu­ally re­ceive.

In gen­eral, when multi-di­men­sional ar­rays are passed as a pa­ram­e­ter to the func­tion, what ac­tu­ally is passed is a pointer to the ar­ray’s first el­e­ment. Since the first el­e­ment of a mul­tidi­men­sional ar­ray is an­other ar­ray, what gets passed to the func­tion is a ‘pointer to an ar­ray’.

We can­not re­ceive a 2D ar­ray as shown in the demo Code 5, since com­pil­ers will gen­er­ate code in such a way that func­tions will re­ceive the 2D ar­ray as ‘Pointer to an ar­ray’ and not ‘Pointer to Pointer’.

1 #in­clude <stdio.h> 2 #de­fine ROW 3 3 #de­fine COL 2 4 5 int main() 6{ 7 int ar­ray[ROW][COL]; 8 pop­u­late(ar­ray); 9 10 //Some code here 11 } 12 13 void pop­u­late(int **ar­ray) //Er­ror 14 { 15 //Some code here 16 }

Code 5: Code to demon­strate that 2D ar­rays can­not be col­lected as pointer to pointer

Now, con­sider Code 6 given be­low: