Array
Array
An array is a collection of similar data elements. These data elements have the
same data type. The elements of the array are stored in consecutive memory
locations and are referenced by an index (also known as the subscript). The
subscript is an ordinal number which is used to identify an element of the array.
DECLARATION OF ARRAYS
We have already seen that every variable must be declared before it is used. The
same concept holds true for array variables. An array must be declared before
being used. Declaring an array means specifying the following:
Data type—the kind of values it can store, for example, int, char, float,
double.
Name—to identify the array.
Size—the maximum number of values that the array can hold.
Arrays are declared using the following syntax: type name[size];
The elements of an array can be initialized at the time of declaration, just as any
other variable. When an array is initialized, we need to provide a value for every
element in the array. Arrays are initialized by writing,
type array_name[size]={list of values};
OPERATIONS ON ARRAYS
Traversing an array means accessing each and every element of the array for a
specific purpose. Traversing the data elements of an array A can include
printing every element, counting the total number of elements, or performing
any process on these elements. Since, array is a linear data structure (because all
its elements form a sequence), traversing its elements is very simple and
straightforward. The algorithm for array traversal is given in Fig.
If an element has to be inserted at the end of an existing array, then the task of
insertion is quite simple. We just have to add 1 to the upper_ bound and assign
the value. Here, we assume that the memory space allocated for the array is still
available.
The algorithm INSERT will be declared as INSERT (A, N, POS, VAL). The
arguments are
(a) A, the array in which the element has to be inserted
(b) N, the number of elements in the array
(c) POS, the position at which the element has to be inserted
(d) VAL, the value that has to be inserted
In the above example, only one element of the array is passed to the called
function. This is done by using the index expression. Here, arr[3] evaluates to a
single integer value. The called function hardly bothers whether a normal
integer variable is passed to it or an array value is passed.
Passing Addresses
Like ordinary variables, we can pass the address of an individual array element
by preceding the indexed array element with the address operator. Therefore, to
pass the address of the fourth element of the array to the called function, we will
write &arr[3]. However, in the called function, the value of the array element
must be accessed using the indirection (*) operator. Look at the code shown in
Fig.
Passing the Entire Array
We have discussed that in C the array name refers to the first byte of the array
in the memory. The address of the remaining elements in the array can be
calculated using the array name and the index value of the element. Therefore,
when we need to pass an entire array to a function, we can simply pass the name
of the array.
A function that accepts an array can declare the formal parameter in either of
the two following ways.
func(int arr[]); or func(int *arr);
When we pass the name of an array to a function, the address of the zeroth
element of the array is copied to the local pointer variable in the function. When
a formal parameter is declared in a function header as an array, it is interpreted
as a pointer to a variable and not as an array. With this pointer variable you can
access all the elements of the array by using the expression: array_name +
index. You can also pass the size of the array as another parameter to the
function.
So for a function that accepts an array as parameter, the declaration should be as
follows.
func(int arr[], int n); or func(int *arr, int n);
Pointers And Arrays
Array notation is a form of pointer notation. The name of the array is the
starting address of the array in memory. It is also known as the base address. In
other words, base address is the address of the first element in the array or the
address of arr[0]. Now let us use a pointer variable as given
in the statement below.
int *ptr;
ptr = &arr[0];
Here, ptr is made to point to the first element of the array. Execute the code
given below and observe the output.
main()
{
int arr[]={1,2,3,4,5};
printf("\n Address of array = %p %p %p", arr, &arr[0], &arr);
}
Similarly, writing ptr = &arr[2] makes ptr to point to the third element of the
array that has index 2. figure 3.24 shows ptr pointing to the third element of the
array. If pointer variable ptr holds the address of the first element in the array,
then the address of successive elements can be calculated by writing ptr++.
int *ptr = &arr[0];
ptr++;
printf("\n The value of the second element of the array is %d", *ptr);
The printf() function will print the value 2 because after being incremented ptr
points to the next location. One point to note here is that if x is an integer
variable, then x++; adds 1 to the value of x. But ptris a pointer variable, so when
we write ptr+i, then adding i gives a pointer that points i elements further along
an array than the original pointer. Since ++ptr and ptr++ are both equivalent to
ptr+1, incrementing a pointer using the unary ++ operator, increments the
address it stores by the amount given by sizeof(type) where type is the data type
of the variable it points to (i.e., 2 for an integer).
TWO-DIMENSIONAL ARRAYS
Any array must be declared before being used. The declaration statement tells
the compiler the name of the array, the data type of each element in the array,
and the size of each dimension. A two-dimensional array is declared as:
data_type array_name[row_size] [column_size];
Therefore, a two-dimensional m ¥ n array is an array that contains m x n data
elements and each element is accessed using two subscripts, i and j, where i <=
m and j <= n.
For example, if we want to store the marks obtained by three students in five
different subjects, we can declare a two dimensional
array as:
int marks[3][5];
In the above statement, a two-dimensional array called marks has been declared
that has m(3) rows and n(5) columns. The first element of the array is denoted
by marks[0][0], the second element as marks[0][1], and so on. Here, marks[0]
[0] stores the marks obtained by the first student in the first subject, marks[1][0]
stores the marks obtained by the second student in the first subject.
However, when we store the elements in a column major order, the elements of
the first column are stored before the elements of the second and third column.
That is, the elements of the array are stored column by column where m
elements of the first column will occupy the first m locations.
This is illustrated in Fig.
In one-dimensional arrays, we have seen that the computer does not keep track
of the address of every element in the array. It stores only the address of the first
element and calculates the address of other elements from the base address
(address of the first element). Same is the case with a two-dimensional array.
Here also, the computer stores the base address, and the address of the other
elements is calculated using the following formula. If the array elements are
stored in column major order,
Address(A[I][J]) = Base_Address + w{M ( J – 1) + (I – 1)}
And if the array elements are stored in row major order,
Address(A[I][J]) = Base_Address + w{N ( I – 1) + (J – 1)}
where w is the number of bytes required to store one element, N is the number
of columns, M is the number of rows, and I and J are the subscripts of the array
element.