Pointers and Array in C – relationship and use

In C programming, pointers and array shares a very close relationship. Array is a data structure that hold finite sequential collection of similar type data. We use array to store a collection of similar type data together. To access and array element we use index. These index starts from 0 and goes up to N-1 (where N is size of the array).

Relationship between pointers and array

Consider the below array declaration,

int arr[5];

It declares an integer array with a capacity of five elements. To access any element of the given array we use array index notation. For example to access zeroth element we use arr[0], similarly to access fifth element we use arr[4].

Let us transform things in the context of pointers.

int * ptr = &arr[0];

The above statement declares an integer pointer pointing at zeroth array element.

In C programming, array exhibits a special behaviour. Whenever you refer an array name directly, is behaves a pointer pointing at zeroth array element. Which means both of the below statements are equivalent.

int * ptr = &arr[0];
int * ptr = arr;

This special behaviour of array allows many interesting things to happen. Things such as you can interchangeably use array and pointers. You can also use array name as a pointer pointing at zeroth element. In context of array and pointer, all of the following statements are valid.

int arr[5];
int * ptr = arr;

arr[0] = 10;    // Stores 10 at 0th element of array
ptr[1] = 20;    // Stores 20 at 1st element of array

ptr    = arr;   // ptr and arr both points to 0th element of array
*ptr   = 100;   // Stores 100 at 0th element of array (Since ptr points at arr[0])
*arr   = 100;   // Stores 100 at 0th element of array

How to access single dimension array using pointer

Array elements are stored sequentially in memory. Below is the memory representation of array

int arr[] = {10, 20, 30, 40, 50};
Pointer and array memory representation
Pointer and array memory representation

In the above image first array element i.e. arr[0] is allocated at memory 0x1000. For the above case I have assumed integer size as 4 bytes. Hence, next array element i.e. arr[1] will get memory at 0x1004 and so on fifth array element is allocated at 0x1016.

Since array elements are stored sequentially, hence you can easily apply pointer arithmetic to iterate though elements. You can use following pointer arithmetic operations to access array elements.

int arr[5];
int * ptr = arr;        // Integer pointer pointing at arr[0]

ptr[0] = 10;            // Assigns 10 to arr[0]
ptr++;                  // ptr now points at arr[1]
ptr--;                  // ptr now points back at arr[0]

*(ptr + 4) = 100;       // Assigns 100 to arr[4].
                        // Note, ptr currently pointing at arr[0] not arr[1].
                        // Hence (ptr + 4) will point at arr[4]

*(arr + 0) = 10;        // Assigns 10 to arr[0]

Example program to read and print array elements using pointer

/**
 * C program to read and print array elements using pointer
 */

#include <stdio.h>

#define SIZE 10     // Maximum array size

int main()
{
    int arr[SIZE];  // Declare an array of size 10
    int *ptr = arr; // Pointer to first element of integer array
    int i;

    /* Input number from user in array */
    printf("Enter %d array elements: ", SIZE);
    while(ptr < &arr[SIZE])
    {
        // Input in array using pointer
        scanf("%d", ptr);

        // Move pointer to next array element
        ptr++;
    }

    // Make sure pointer point back to 0th element
    ptr = arr;

    // Print all elements using pointer
    printf("Elements in array are: ");
    for(i=0; i < SIZE; i++)
    {
        printf("%d, ", *(ptr + i));
    }

    return 0;
}

Output –

Enter 10 array elements: 10 20 30 40 50 60 70 80 90 100
Elements in array are: 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
  • The condition while(ptr < &arr[SIZE]) will iterate till ptr points withing array range.
  • In statement scanf("%d", ptr); you might have noticed that, I have not used address of operator & with variable name in scanf() function. This is because scanf() function accepts memory address and pointer variable contains memory address. Hence, there we can use pointer variable directly in scanf().

Is name of array is constant pointer to zeroth array element?

As I spoke earlier whenever you use array name directly, the C compiler assumes it as a pointer pointing at zeroth array element. This pointer is not modifiable. Therefore, you may think it as a const pointer.

Constant pointer is a special pointer whose value cannot be modified. Means a pointer that once point to a memory location cannot point to another memory location later in the program.

Let us write a C program to prove array name behaves as a constant pointer in C.

int main()
{
    int arr[] = {10, 20, 30, 40, 50};  // Integer array
    int *ptr = arr;  // Pointer to 0th element of array

    /*
     * If arr behaves as a constant pointer then compiler
     * must complain about arr++. Since arr++ is equivalent to 
     * arr = arr + 1 which is not permitted.
     */
     arr++; // Error

     // No error
     ptr++;

    return 0;
}

On compilation of the above program, it produces following compilation errors. Which is a proof that the array name (as a pointer) is not modifiable.

parrname.c: In function 'main':
parrname.c:10:9: error: lvalue required as increment operand
      arr++; // Error

However, the above proof is not adequate to say array name is a constant pointer to zeroth element of array. If it is a constant pointer then sizeof(arr) must return size of constant integer pointer, but it doesn’t.

sizeof(arr) returns total bytes occupied by array i.e. number-of-elements * array-data-type-size.

Read more about, how to find size of a data type using sizeof() operator.

I have read text of many authors, calling name of array as constant pointer to zeroth array element. However, the statement is not true.

Array name when used directly behaves as a constant pointer but it is not a constant pointer. Pointer and array both are different concepts though interlinked.

A note on array index

The behaviour of array as a pointer lets you do several magical things. Let us discuss another important behaviour of array as a pointer in C programming. Consider the below integer array.

int arr[] = {10, 20, 30, 40, 50};

As I spoke earlier, we can use array name as a pointer pointing to zeroth element. The array dereferencing operator [ ] internally converts array indexed accessing, in the context of pointers. For example,

arr[0];  // Equivalent to *(arr + 0)
arr[4];  // Equivalent to *(arr + 4)

We can also write the statement *(arr + 0) as *(0 + arr), since additions are associative in nature. Which in array indexed format can be written as 0[arr].

Let us collect it all together.

arr[0]        =>  *(arr + 0)
*(arr + 0)    =>  *(0 + arr)  // Since additions are associative

*(arr + 0)    =>  arr[0]
*(0 + arr)    =>  0[arr]
arr[0]        =>  0[arr]      // Both are equivalent

Conclusion: You can interchangeably use arr[0] as 0[arr]. Both convey the same meaning in C programming.

Use this cool magical array syntax to surprise your mates. 🙂