When an array is declared the compiler allocates a base address and sufficient
amount of memory to contain all the elements of the array in contiguous memory
locations. Here, the base address is the location of the first element of the
array and the array name is a constant pointer to the first element. Let’s say
we declare an array a whose base address is 5000 i.e. a=5000 then the
name a is defined as a constant pointer to the first element a<0>.
Therefore,
a=5000=&a<0>
Now if we declare an integer pointer p, then
p=a; will make the
pointer p point to the array a and is equivalent to
p=&a<0>;Â
Since in an array the elements are stored in contiguous memory locations they
can be accessed easily and with greater speed using pointers rather than array
indexing. This can be done by incrementing the pointer.
p++ ;
Now the pointer will point to the second element a<1>. Here the address of an
element is calculated using its index and scale factor of the data
type.
Address of a<1> = base address + (index * scale factor of data
type)
                      = 5000 + (1 * 2)
= 5002
To access the elements of the array:
*p gives the value of a<0>,
*(p+1) gives the value of a<1>, *(p+2) gives the value of a<2> and so
on.
Program to read and print an array
 #include
 main()
 {
 Â
int a<10>,*p,I;
  p=a;
  printf(" \n Enter the elements of the array
:\n");
  for(i=0;i<10;i++)
  {
    scanf("%d",p);             /* Note: for the scanf statement the address
operator & is not used */
    p++;
  }
  p=a;                            /* Resetting the pointer to the first
element of the array */
  printf(" \n The
elements of the array are:\n");
  for(p=a;p<=&a<9>;p++)    /* Thus eliminating the loop control
variable i */
  {
    printf("%d",*p);
  }
 }
Pointers can also be used
to manipulate two-dimensional arrays as well. We know that in a one dimensional
array a the expression
 *(a + i) is equivalent to
a
Similarly, a two dimensional array can be represented in the
following manner;
 *(*(a+I)+j) and this is equivalent to a
In this case the base address is &a<0><0> and starting at this address
the compiler allocates contiguous space for all the elements row wise. That is
the first element of the second row is placed immediately after the last element
of the first row and so on.
Now if we declare
 int a<3><4>;
 p=a=&a<0><0>           /* It is equivalent to (p + 4 * i + j)
*/
Thus if i is incremented by 1 p is incremented by 4 which is the size
of each row.
Pointers and character strings
We can also use
pointers to access the individual characters of a string. A string as we know is
essentially an array of characters terminated by a null character. The example
given below illustrates the use of pointers to strings.
Program to determine the length of a character
string
 #include
 main()
 {
  char str<100>, *p;
 Â
p=str;
  printf("\nEnter a string :
");
  gets(p);
  printf("The elements of the array are :");
  for(;*ptr!=’\0’;ptr++)
 Â
{
    printf("%c",*ptr);
  }
  printf("The
length of the string is : %d",(ptr-str));
 }
Input:
Enter a string : This is a C
tutorial
Output :
The elements of the array are : This is a C
tutorial
The length of the string is : 20
The gets() function reads a
string of characters terminated by a newline character(‘\n’) from the standard
input device and stores it in a string variable that is passed as a parameter.
The newline character does not become a part of the string but instead a
null(‘\0’) character, considered as a string terminator is inserted at the end
of the string.
In the above program when the ‘for’ loop terminates, the pointer ptr holds
the address of the null character. Therefore, the statement ptr-str gives the
length of the string.
One important use of pointers is in handling of a table of strings. Consider
the following array of strings:
 char
name<3><25>;
This says that name is a table containing three names each
with a maximum length of 25 characters including the null character. This table
will consist of three rows and twenty five columns. The total storage
requirement for the name table is 75 bytes. But the names entered may not be of
equal lengths hence storage space is wasted. Instead of making each row a fixed
number of characters, we can make a pointer to a string of varying length. For
example,
 static char
*name<3>={"Ram","Shyam","Raj"};
 for(i=0;i<3;i++)
 printf("%s\n",name);
declares name to be an array of
three pointers to characters, each pointer points to a particular name; name<0>
-> Ram, name<1> -> Shyam, name<2> -> Raj.
This declaration allocates
only 14 bytes, sufficient to hold all the characters. The printf statement
prints all the three names.
Now to access the jth character in the
ith name,
*(name+j)
The character arrays with rows of varying length are called ragged arrays and
are better handled by pointers. Another point to be noted is that * has a lower
precedence than <>, therefore ptr<3> declares ptr as an array of three pointers
while (*ptr)<3> declares ptr as a pointer to an array of three elements.