Unit 4
Array
What are Arrays? A Simple Program using Array, more on Arrays
Arrays a kind of data structure that can store a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent individual variables. A specific element in an array is accessed by an index.
All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.
#include <stdio.h>
int main () {
int n[ 10 ]; /* n is an array of 10 integers */
int i,j;
/* initialize elements of array n to 0 */
for ( i = 0; i < 10; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 10; j++ ) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
When the above code is compiled and executed, it produces the following result −
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
Initialize an array in C either one by one or using a single statement as follows −
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
The number of values between braces { } cannot be larger than the number of elements that we declare for the array between square brackets [ ].
If you omit the size of the array, an array just big enough to hold the initialization is created.
Therefore, if you write −
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
You will create exactly the same array as you did in the previous example.
Following is an example to assign a single element of the array –
balance[4] = 50.0;
The above statement assigns the 5th element in the array with a value of 50.0. All arrays have 0 as the index of their first element which is also called the base index and the last index of an array will be total size of the array minus
Two pieces of information are needed to specify the memory of an ordinary variable:
- an address in memory giving the location of the first byte for that variable, and
- the type of the variable, which tells the compiler how many bytes of memory the variable requires, and enables it to correctly interpret the data.
When an array of a given size, say N, and of a given type is declared, the compiler allocates enough memory to hold all N pieces of data. If M bytes of memory is required for each piece of data of the type specified, then a total of N*M bytes of contiguous memory are allocated to that array.
The data for the first element is stored in the first M bytes, the data for the second element is stored in the next M bytes, etc.
The compiler remembers the address of the first byte of an array only. In fact the address of the first byte is considered as the memory address for the entire array.
Knowing the address of the first byte the computer can easily calculate to find the memory address for any other element of the array.
For example given an array A, to retrieve the data stored in A[n], the computer goes to the address of the array plus n*M and retrieves the next M bytes of data.
To illustrate, consider an integer array exam_score that is declared for use to store the exam score for a class of 12 students.:
const int CLASS_SIZE = 12;
int exam_score[CLASS_SIZE];
Suppose the 12 scores have been assigned to the array, and the following code is used to compute the class average:
float average;
int sum = 0, n;
for (n = 1; n <= CLASS_SIZE; n++)
sum += exam_score[n];
average = double(sum)/double(CLASS_SIZE);
This code when embedded in a suitable program will compile and run on most systems. However, the result for the average is almost always wrong. The reason is that the element exam_score[12] is referenced in the last iteration of the loop. The 12 elements of the array are indexed from 0 to 11, and the index of 12 is out-of-range.
- One Dimensional Array:
The array which is used to represent and store data in a linear form is called as 'single or one dimensional array.'
Syntax:
data-type array_name[size];
Example 2:
int a[3] = {2, 3, 5};
char ch[10] = "Data" ;
float x[3] = {2.5, 3.50,489.98} ;
Total Size of an array(in Bytes) can be calculated as follows:
total size(in bytes) = length of array * size of data type
In above example, a is an array of type integer which has storage size of 3 elements. One integer variable occupies 2 bytes. Hence the total size would be 3 * 2 = 6 bytes.
Memory Allocation :
P1: Program to display all elements of 1-D array.
#include<stdio.h>
#include<conio.h>
void main()
{
int a[20];
int n,i;
printf("\n Enter the size of array :");
scanf("%d",&n);
printf("size of array is %d",n);
printf("\n Enter Values to store in array one by one by pressing ENTER :");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("\n The Values in array are..");
for(i=0;i<n;i++)
{
printf("\n %d",a[i]);
}
getch();
}
P2: Program to copy 1-D array to another 1-D array
#include <stdio.h>
#include<conio.h>
void main()
{
int n, i, j, a[100], b[100];// a is original array and b is copied array
printf("Enter the number of elements in array a\n");
scanf("%d", &n);
printf("Enter the array elements in a\n");
for (i= 0; i < n ; i++)
scanf("%d", &a[i]);
/*
Copying elements from array a into array b */
for (i =0;i<n;i++)
b[i] = a[i];
/*
Printing copied array b
.
*/
printf("Elements of array b are\n");
for (i = 0; i < n; i++)
printf("%d\n", b[i]);
getch();
}
Output:
P3:Program to find reverse of 1-D array
#include <stdio.h>
#include<conio.h>
void main()
{
int n, i, j, a[100], b[100];// a is original array and b is reversed array
printf("Enter the number of elements in array\n");
scanf("%d", &n);
printf("Enter the array elements\n");
for (i= 0; i < n ; i++)
scanf("%d", &a[i]);
/*
* Copying elements into array b starting from end of array a
*/
for (i = n - 1, j = 0; i >= 0; i--, j++)
b[j] = a[i];
/*
Printing reversed array b
.
*/
printf("Reverse array is\n");
for (i = 0; i < n; i++)
printf("%d\n", a[i]);
getch();
}
output:
Enter the number of elements in an array:
5
Enter the elements
9 18 27 36 45
Reverse of an array
45 36 27 18 9
2. Multi Dimensional Array
1-D array has 1 row and multiple columns but multidimensional array has of multiple rows and multiple columns.
Two Dimensional array:
It is the simplest multidimensional array. They are also called as matrix.
Declaration:
data-type array_name[no.of rows][no. of columns];
Total no of elements= No.of rows * No. of Columns
Example 3: int a[2][3]
This example illustrates two dimensional array a of 2 rows and 3 columns.
Total no of elements: 2*3=6
Total no of bytes occupied: 6( total no.of elements )*2(Size of one element)=12
Initialization and Storage Representation:
In C, two dimensional arrays can be initialized in different number of ways. Specification of no. of columns in 2 dimensional array is mandatory while no of rows is optional.
int a[2][3]={{1,3,0}, // Elements of 1st row
{-1,5,9}}; // Elements of 2nd row
OR
int a[][3]={{1,3,0}, // Elements of 1st row
{-1,5,9}}; // Elements of 2nd row
OR
int a[2][3]={1,3,0,-1,5,9};
Fig. 3 gives general storage representation of 2 dimensional array
Eg 4. int a[2][3]={1,3,0,-1,5,9}
Accessing Two-Dimensional Array Elements:
An element in 2-dimensional array is accessed by using the subscripts i.e. row index and column index of the array. For example:
int val = A[1][2];
The above statement will access element from the 2nd row and third column of the array A i.e. element 9.
Array is a data structure which stores the collection of similar types of element in consecutive memory locations. Indexing of array always start with ‘0’ where as non-graphical variable ‘\0’ indicates the end of array. Syntax for declaring array is
data type array name[Maximum size];
- Data types are used to define type of element in an array. Data types are also useful in finding the size of total memory locations allocated for the array.
- All the rules of defining name of variable are also applicable for the array name.
- Maximum size indicates the total number of maximum elements that array can hold.
- Total memory allocated for the array is equal to the memory required to store one element of the array multiply by the total element in the array.
- In array, memory allocation is done at the time of declaration of an array.
Example:
Sr. No. | Instructions | Description |
#include<stdio.h> | Header file included | |
2. | #include<conio.h> | Header file included |
3. | void main() | Execution of program begins |
4. | { | Memory is allocated for variable i,n and array a |
5. | int i,n,a[10]; | |
6. | clrscr(); | Clear the output of previous screen |
7. | printf("enter a number"); | Print “enter a number” |
8. | scanf("%d",&n); | Input value is stored at the addres of variable n |
9. | for(i=0;i<=10;i++) | For loop started from value of i=0 to i=10 |
10. | { | Compound statement(scope of for loop starts) |
11. | a[i]=n*i; | Result of multiplication of n and I is stored at the ith location of array ieas i=0 so it is stores at first location. |
12. | printf("\n %d",a[i]); | Value of ith location of the array is printed |
13. | } | Compound statement(scope of for loop ends) |
14. | printf("\n first element in array is %d",a[0]); | Value of first element of the array is printed |
15. | printf("\n fifth element in array is %d",a[4]); | Value of fifth element of the array is printed |
16. | printf("\n tenth element in array is %d",a[9]); | Value of tenth element of the array is printed |
17. | getch(); | Used to hold the output screen |
18. | } | Indicates end of scope of main function |
This is the default way of passing the parameters to the function. This is achieved by passing the copy of data to the function. This mechanism is also called as call by value. In case of parameter passing by value, the changes made to the formal arguments in the called function have no effect on the values of actual arguments in the calling function.
This mechanism is used when programmer don't want to change the value of passed parameters. When parameters are passed by value then functions in C create copies of the passed in variables and do required processing on these copied variables.
Pass-by-value is implemented by actual data transfer so additional storage is required to maintain the copies of passed parameters.
Example:
#include <stdio.h>
#include<conio.h>
/* function declaration goes here.*/
void swap( int p1, int p2 );
int main()
{
int a = 10;
int b = 20;
printf("Before: Value of a = %d and value of b = %d\n", a, b );
swap( a, b );
printf("After: Value of a = %d and value of b = %d\n", a, b );
getch();
}
void swap( int p1, int p2 )
{
int t;
t = p2;
p2 = p1;
p1 = t;
printf("Value of a (p1) = %d and value of b(p2) = %d\n", p1, p2 );
}
Output :
Before: Value of a = 10 and value of b = 20
Value of a (p1) = 20 and value of b (p2) = 10
After: Value of a = 10 and value of b = 20
Note: In the above example the values of “a” and “b” remain unchanged before calling swap function and after calling swap function.
An array is a block of sequential data. Let's write a program to print addresses of array elements.
#include <stdio.h>
int main() {
int x[4];
int i;
for(i = 0; i < 4; ++i) {
printf("&x[%d] = %p\n", i, &x[i]);
}
printf("Address of array x: %p", x);
return 0;
}
Output
&x[0] = 1450734448
&x[1] = 1450734452
&x[2] = 1450734456
&x[3] = 1450734460
Address of array x: 1450734448
There is a difference of 4 bytes between two consecutive elements of array x. It is because the size of int is 4 bytes.
Notice that, the address of &x[0] and x is the same. It's because the variable name x points to the first element of the array.
From the above example, it is clear that &x[0] is equivalent to x. And, x[0] is equivalent to *x.
Similarly,
&x[1] is equivalent to x+1 and x[1] is equivalent to *(x+1).
&x[2] is equivalent to x+2 and x[2] is equivalent to *(x+2).
...
Basically, &x[i] is equivalent to x+i and x[i] is equivalent to *(x+i).
Example 1: Pointers and Arrays
#include <stdio.h>
int main() {
int i, x[6], sum = 0;
printf("Enter 6 numbers: ");
for(i = 0; i < 6; ++i) {
// Equivalent to scanf("%d", &x[i]);
scanf("%d", x+i);
// Equivalent to sum += x[i]
sum += *(x+i);
}
printf("Sum = %d", sum);
return 0;
}
When you run the program, the output will be:
Enter 6 numbers: 2
3
4
4
12
4
Sum = 29
Multidimensional arrays follow the same rules as single-dimensional arrays when passing them to a function. However, the combination of decay-to-pointer, operator precedence, and the two different ways to declare a multidimensional array (array of arrays vs array of pointers) may make the declaration of such functions non-intuitive.
The following example shows the correct ways to pass multidimensional arrays.
#include <assert.h>
#include <stdlib.h>
/* When passing a multidimensional array (i.e. an array of arrays) to a
function, it decays into a pointer to the first element as usual. But only
the top level decays, so what is passed is a pointer to an array of some fixed
size (4 in this case). */
void f(int x[][4]) {
assert(sizeof(*x) == sizeof(int) * 4);
}
/* This prototype is equivalent to f(int x[][4]).
The parentheses around *x are required because [index] has a higher
precedence than *expr, thus int *x[4] would normally be equivalent to int
*(x[4]), i.e. an array of 4 pointers to int. But if it's declared as a
function parameter, it decays into a pointer and becomes int **x,
which is not compatable with x[2][4]. */
void g(int (*x)[4]) {
assert(sizeof(*x) == sizeof(int) * 4);
}
/* An array of pointers may be passed to this, since it'll decay into a pointer
to pointer, but an array of arrays may not. */
void h(int **x) {
assert(sizeof(*x) == sizeof(int*));
}
int main(void) {
int foo[2][4];
f(foo);
g(foo);
/* Here we're dynamically creating an array of pointers. Note that the
size of each dimension is not part of the datatype, and so the type
system just treats it as a pointer to pointer, not a pointer to array
or array of arrays. */
int **bar = malloc(sizeof(*bar) * 2);
assert(bar);
for (size_t i = 0; i < 2; i++) {
bar[i] = malloc(sizeof(*bar[i]) * 4);
assert(bar[i]);
}
h(bar);
for (size_t i = 0; i < 2; i++) {
free(bar[i]);
}
free(bar);
}
Two Dimensional array:
It is the simplest multidimensional array. They are also called as matrix.
Declaration:
data-type array_name[no.of rows][no. of columns];
Total no of elements= No.of rows * No. of Columns
Example 3: int a[2][3]
This example illustrates two dimensional array a of 2 rows and 3 columns.
Total no of elements: 2*3=6
Total no of bytes occupied: 6( total no.of elements )*2(Size of one element)=12
Initialization and Storage Representation:
In C, two dimensional arrays can be initialized in different number of ways. Specification of no. of columns in 2 dimensional array is mandatory while no of rows is optional.
int a[2][3]={{1,3,0}, // Elements of 1st row
{-1,5,9}}; // Elements of 2nd row
OR
int a[][3]={{1,3,0}, // Elements of 1st row
{-1,5,9}}; // Elements of 2nd row
OR
int a[2][3]={1,3,0,-1,5,9};
Fig. 3 gives general storage representation of 2 dimensional array
Eg 4. int a[2][3]={1,3,0,-1,5,9}
Accessing Two-Dimensional Array Elements:
An element in 2-dimensional array is accessed by using the subscripts i.e. row index and column index of the array. For example:
int val = A[1][2];
The above statement will access element from the 2nd row and third column of the array A i.e. element 9.
The array arrangement shown in Figure is only conceptually true. This is because memory doesn’t contain rows and columns. In memory whether it is a one-dimensional or a two-dimensional array the array elements are stored in one continuous chain. The arrangement of array elements of a two-dimensional array in memory is shown below:
We know that the expressions s[0] and s[1] would yield the addresses of the zeroth and first one-dimensional array respectively. From Figure 8.6 these addresses turn out to be 65508
and 65512.
Suppose we want to refer to the element s[2][1] using pointers. s[2] would give the address 65516, the address of the second one-dimensional array.
Obviously ( 65516 + 1 ) would give the address 65518. Or ( s[2] + 1 ) would give the address 65518.
And the value at this address can be obtained by using the value at address operator, saying *( s[2] + 1 ). But, we have already studied while learning one-dimensional arrays that num[i] is same as *( num + i ). Similarly, *( s[2] + 1 ) is same as, *( *( s + 2 ) + 1 ). Thus, all the following expressions refer to the same element,
s[2][1]
* ( s[2] + 1 )
* ( * ( s + 2 ) + 1 )
Using these concepts the following program prints out each element of a two-dimensional array using pointer notation.
/* Pointer notation to access 2-D array elements */
main( )
{
int s[4][2] = {
{ 1234, 56 },
{ 1212, 33 },
{ 1434, 80 },
{ 1312, 78 }
} ;
int i, j ;
for ( i = 0 ; i <= 3 ; i++ )
{
printf ( "\n" ) ;
for ( j = 0 ; j <= 1 ; j++ )
printf ( "%d ", *( *( s + i ) + j ) ) ;
}
}
And here is the output...
1234 56
1212 33
1434 80
1312 78
Pointer to Multidimensional Arrays
In multidimensional array all the elements of the array are stored in multiple stacks of rows. Two dimensional array has two stacks of rows, it looks like two dimensional matrix containing rows and columns. Three dimensional array has three stacks of rows and it looks like a rubik’s cube. Like single dimensional array, all the elements of multidimensional array are of same type and C language does not allow user to store elements of two or more different data type in a single multidimensional array.
Suppose user wants to store string ‘Hello Raushan’ in two dimensional array, minimum size of an array to store above strings is 13 as it contains 12 alphabets and one space. Two dimensional arrays are built with rows and columns. For the above string we need to divide total array size into rows and columns. A pointer variable can store the address of only one array variable at a single instant of time. Similar to array, pointer can also hold the address of only respective type of element. For the above string user required character type of pointer. Following is the syntax of declaring two dimensional array and a pointer to array.
char arr[2][7]= {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ’, ‘R’, ‘a’, ‘u’, ‘s’, ‘h’, ‘a’, ‘n’};
char *p;
p=&arr[0][0];
In the above syntax, First line represents the syntax of declaring and defining two dimensional array. Here we declare the character type of array of size 14, which is divided into two rows and seven columns. Total memory allocated to the ‘arr’ array is 14. This array can hold 14 elements having data type ‘char’ and all these elements are stored in the consecutive memory location. Out of 14 elements the first 7 elements are stored in the first row whereas remaining elements are stored in the second row. The index of first element (ie ‘H’) is arr[0][0] where as the last element (ie ‘n’) is having index arr[1][5]. At the last position of the array ie arr[1][6] contains garbage value.
Second line represents the syntax of declaring pointer variable. Here, we define ‘p’ as a pointer variable which is of type ‘char’. This pointer variable can perform the operation on element having data type ‘char’.
Third line represents the syntax of defining pointer variable. Here, we assign the address of first element of the array ‘arr’ to pointer variable ‘p’.
Memory map of above syntax is as follows
Consider the following program
#include<stdio.h>
#include<conio.h>
void main()
{
int arr[2][3],i,j,*p;
clrscr();
printf("enter the elements of array");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&arr[i][j]);
}
}
printf("Two dimensional array is\n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("\t %d",arr[i][j]);
}
printf("\n");
}
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
p=&arr[i][j];
printf("\n address is %d and value is %d",p,*p);
}
}
getch();
}
Output:
Enter the elements of array
4
5
6
1
2
3
Two dimensional array is
4 5 6
1 2 3
address is -24 and value is 4
address is -22 and value is 5
address is -20 and value is 6
address is -18 and value is 1
address is -16 and value is 2
address is -14 and value is 3
In the above program, we define the array of size 6 which is divided in to two rows and three columns. in which value of first element of the array is 4 which is stored at location of arr[0][0], second element has value 4, which is stored at location of arr[0][1]and last element has value 3, which is stored at location of arr[1][2].
Pointer is a special variable that can hold the address of another variable whereas arrays are the special type of linear data structure in which elements are stored in contiguous memory locations. Pointers to array are used to retrieve the values of array element from their location. Pointer to array means that a variable which is meant to hold the address of array element. Following is the syntax of assigning the address of array element to pointer.
pointer-name = & array-name[element];
For example:
int arr[4];
int *p;
p= &arr[1];
In the above example, pointer variable ‘p’ is pointing the address of second variable of the array ‘arr’. Following figure depict the pictorial representation of above code.
Declaring Pointer to array
|
User can access the elements of array by using pointer variable. If we want to store value 7 at the second position then we need to write
*p= 7;
Assigning value to second position of an array
|
Pointer arithmetic can be used to perform the arithmetic operation on pointer to array. There are three forms of pointer arithmetic
1.Adding an integer to a pointer: C language allows user to add integer value to the pointer variable. Suppose in the above example we can shift the pointer variable ‘p’ to the forth position by writing
p=p+2;
Now, if we write *p=9 then value ‘9’ is stored at the last position.
Adding an integer to a pointer
|
2.Subtracting an integer from a pointer: Similar to addition of integer to pointer, user can subtract the integer value from pointer variable. We can shift the pointer variable ‘p’ to the third position by writing
p=p-1;
Now, if we write *p=5 then value ‘5’ is stored at the third position
Subtracting an integer from a pointer
|
3.Subtracting one pointer from another: C language allow user to perform arithmetic operation on two pointer variables. Consider the following code
int *p,*q, r,s;
int arr[4];
arr[1]=7;
arr[2]=5;
arr[3]=9;
p=&arr[2];
q=&arr[3];
r= p-q;
s=q-p;
In the above program variable ‘r’ contains the value ‘-1’ whereas variable ‘s’ contain value ’1’.
Pointer to Single Dimensional Arrays
Single dimensional array are the data structure in which all the elements are stored in a single row. Indexing of single dimensional array starts with 0 whereas last element has index (array size-1). All the elements of the array are of similar data-types, C language does not allow user to store elements of two or more different data type in a single array. Suppose user wants to store string ‘Hello Raushan’ then initially user required character type of array. Minimum size of an array to store above string is 13 as it contains 12 alphabets and one space. A pointer variable can store the address of only one array variable at a single instant of time. Similar to array, pointer can also hold the address of only respective type of element. For the above string user required character type of pointer. Following is the syntax of declaring single dimensional array and a pointer to array.
char arr[13]= {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ’, ‘R’, ‘a’, ‘u’, ‘s’, ‘h’, ‘a’, ‘n’};
char *p;
p=&arr[0];
In the above syntax, First line represents the syntax of declaring and defining single dimensional array. Here we declare the character type of array of size 13. Total memory allocated to the ‘arr’ array is 13. This array can hold 13 elements having data type ‘char’ and all these elements are stored in the consecutive memory location. Here we are storing string ‘Hello Raushan’ to the array ‘arr’. The index of first element (ie ‘H’) is arr[0] where as the last element (ie ‘n’) is having index arr[12].
Second line represents the syntax of declaring pointer variable. Here, we define ‘p’ as a pointer variable which is of type ‘char’. This pointer variable can perform the operation on element having data type ‘char’.
Third line represents the syntax of defining pointer variable. Here, we assign the address of first element of the array ‘arr’ to pointer variable ‘p’.
Memory map of above syntax is as follows
Consider the following basic program of pointer to array
#include<stdio.h>
void main()
{
int a[]={1,2,3,5,6,7,8};
int *p= a;
printf("\n This is the address of a %u, value of &a is %u ,Address of first element %d ,
Value stored at first place is %d",a,&a,&a[0],*a);
printf("\nThis is the address at p %u , value at p %u and the value pointed by p
%d",&p,p,*p);
printf("\n");
}
Output:
This is the address of a 3219815716, value of &a is 3219815716 ,Address of first element 3219815716 , Value stored at first place is 1
This is the address at p 3219815712 , value at p 3219815716 and the value pointed by
p 1
Consider the following program
#include<stdio.h>
#include<conio.h>
void main()
{
int arr[3];
int *p;
arr[0]=3;
arr[1]=6;
arr[2]=8;
for(i=0;i<3;i++)
{
p= &arr[i];
printf(“address of %d element is”,p);
printf(“\t value of %d element is \n”,*p);
}
In the above program, we define the array of size 3 in which value of first element of the array is 3, second element has value 6 and last element has value 8.Integer type of pointer variable ‘p’ initially points to the first element of the array. So, first ‘printf’ statement is responsible to print the address of array element whereas second ‘printf’ statement is used to print the value of array element using pointer.
For the first iteration of ‘for’ loop, value of loop variable ‘I’ is ‘0’. So, pointer variable ‘p’ contains the address of first element of the array ‘arr’. First ‘printf’ statement will print the memory address of first element of the array and second ‘printf’ statement print the value of first element of the array ie ‘3’.
In the second iteration loop variable is incremented by one. Now, ‘p’ contains the address of second element of the array ie ‘arr[1]’. So, this time ‘printf’ statements prints the address and value of second element of the array.
In the third iteration loop variable is incremented by one and it becomes ‘2’. Now, ‘p’ contains the address of third element of the array ie ‘arr[2]’. So, this time ‘printf’ statements prints the address and value of third element of the array.
Again the value of loop variable is incremented by one and it becomes ‘3’. So, the condition inside ‘for’ loop is not satisfied and flow of program execution comes out of loop.
Pointer to Multidimensional Arrays
In multidimensional array all the elements of the array are stored in multiple stacks of rows. Two dimensional array has two stacks of rows, it looks like two dimensional matrix containing rows and columns. Three dimensional array has three stacks of rows and it looks like a rubik’s cube. Like single dimensional array, all the elements of multidimensional array are of same type and C language does not allow user to store elements of two or more different data type in a single multidimensional array.
Suppose user wants to store string ‘Hello Raushan’ in two dimensional array, minimum size of an array to store above strings is 13 as it contains 12 alphabets and one space. Two dimensional arrays are built with rows and columns. For the above string we need to divide total array size into rows and columns. A pointer variable can store the address of only one array variable at a single instant of time. Similar to array, pointer can also hold the address of only respective type of element. For the above string user required character type of pointer. Following is the syntax of declaring two dimensional array and a pointer to array.
char arr[2][7]= {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ’, ‘R’, ‘a’, ‘u’, ‘s’, ‘h’, ‘a’, ‘n’};
char *p;
p=&arr[0][0];
In the above syntax, First line represents the syntax of declaring and defining two dimensional array. Here we declare the character type of array of size 14, which is divided into two rows and seven columns. Total memory allocated to the ‘arr’ array is 14. This array can hold 14 elements having data type ‘char’ and all these elements are stored in the consecutive memory location. Out of 14 elements the first 7 elements are stored in the first row whereas remaining elements are stored in the second row. The index of first element (ie ‘H’) is arr[0][0] where as the last element (ie ‘n’) is having index arr[1][5]. At the last position of the array ie arr[1][6] contains garbage value.
Second line represents the syntax of declaring pointer variable. Here, we define ‘p’ as a pointer variable which is of type ‘char’. This pointer variable can perform the operation on element having data type ‘char’.
Third line represents the syntax of defining pointer variable. Here, we assign the address of first element of the array ‘arr’ to pointer variable ‘p’.
Memory map of above syntax is as follows
Consider the following program
#include<stdio.h>
#include<conio.h>
void main()
{
int arr[2][3],i,j,*p;
clrscr();
printf("enter the elements of array");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&arr[i][j]);
}
}
printf("Two dimensional array is\n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("\t %d",arr[i][j]);
}
printf("\n");
}
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
p=&arr[i][j];
printf("\n address is %d and value is %d",p,*p);
}
}
getch();
}
Output:
Enter the elements of array
4
5
6
1
2
3
Two dimensional array is
4 5 6
1 2 3
address is -24 and value is 4
address is -22 and value is 5
address is -20 and value is 6
address is -18 and value is 1
address is -16 and value is 2
address is -14 and value is 3
In the above program, we define the array of size 6 which is divided in to two rows and three columns. in which value of first element of the array is 4 which is stored at location of arr[0][0], second element has value 4, which is stored at location of arr[0][1]and last element has value 3, which is stored at location of arr[1][2].
2-D is passed to a function it is optional to specify the size of the left most dimensions. So if we have an array of 2 rows and 3 dimensions then it can be passed to a function in the following two ways:
int two_d[2][3] = {
{99,44,11},
{4,66,9}
};
1st way:
void function(int a[][3])
{
// statements;
}
2nd way:
void function(int a[2][3])
{
// statements;
}
Recall that 2-D arrays are stored in row-major order i.e first row 0 is stored, then next to it row 1 is stored and so on. Therefore in C, a 2-D array is actually a 1-D array in which each element is itself a 1-D array. Since the name of the array points to the 0th element of the array.
In the case of a 2-D array, 0th element is an array.
Hence, we can also declare a function where the formal argument is of type pointer to an array.
3rd way:
void function(int (*a)[3])
{
// statements;
}
Essentially in all the three cases discussed the type of the variable a is a pointer to an array of 3 integers, they differ only in the way they are represented.
Example:
#include<stdio.h>
void change_twod(int (*a)[3]);
int main()
{
int i,j, two_d[2][3] = {
{99,44,11},
{4,66,9}
};
printf("Original array: \n\n");
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%3d ", two_d[i][j]);
}
printf("\n");
}
change_twod(two_d);
printf("\n\nModified array : \n\n");
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%3d ", two_d[i][j]);
}
printf("\n");
}
// signal to operating system everything works fine
return 0;
}
void change_twod(int (*arr)[3])
{
int i, j;
printf("\n\nIncrementing every element by 5\n");
// increment original elements by 6
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
arr[i][j] = arr[i][j] + 5;
}
}
}
Expected Output:
Original array:
99 44 11
4 66 9
Incrementing every element by 5
Modified array :
104 49 16
9 71 14
Similar to array of character, integer C language also provides facility to create array of pointers. Array of pointers contains same type of pointer variables which are stored in the consecutive memory location. As pointer variables are responsible to store addresses, array of pointer is also called as the collection of addresses. Array of pointer is different from the pointer to array. In pointer to array, a single pointer pointes to all the elements of an array. In array of pointers, all the elements of array are pointed by pointers. Syntax of declaring array of pointer is
data_type *array_name[size].
Consider the following program
#include<stdio.h>
int main(void)
{
char *p1 = "Sonu";
char *p2 = "Rani";
char *p3 = "Debu";
char *arr[3];
arr[0] = p1;
arr[1] = p2;
arr[2] = p3;
printf("\n p1 = [%s] \n",p1);
printf("\n p2 = [%s] \n",p2);
printf("\n p3 = [%s] \n",p3);
printf("\n arr[0] = [%s] \n",arr[0]);
printf("\n arr[1] = [%s] \n",arr[1]);
printf("\n arr[2] = [%s] \n",arr[2]);
return 0;
}
In the above code, we declare three pointers pointing to three strings. Then we declared an array of three pointers and assigned the pointers ‘p1′, ‘p2′ and ‘p3′ to the 0, 1 and 2 index of array. Compiler first assign memory address to three pointer variables and the array of pointers and then store the value at the respective address of pointer variable and array element. Diagrammatic representation of the memory mapping to above code is as follows.
Element | Memory address | Value |
P1 | -28 | Sonu |
P2 | -30 | Rani |
P3 | -32 | Debu |
Arr[0] | -38 | Sonu |
Arr[1] | -36 | Rani |
Arr[2] | -34 | Debu |
Let’s see the output:
p1 = [Sonu]
p2 = [Rani]
p3 = [Debu]
arr[0] = [Sonu]
arr[1] = [Rani]
arr[2] = [Debu]
Visualizing 3D array:
If we want to visualize a 2D array, we can visualize it in this way:
int arr[3][3], it means a 2D array of type integer having 3 rows and 3 columns.It is just a simple matrix
int arr[3][3]; //2D array contaning 3 rows and 3 columns
1 2 3
4 5 6
7 8 9
But, what happen if we add one more dimension here,
i.e, int arr[3][3][3], now it becomes a 3D array.
int shows that the 3D array is an array of type integer.
arr is the name of array.
first dimension represents the bl ock size(total number of 2D arrays).
second dimension represents the rows of 2D arrays.
third dimension represents the columns of 2D arrays.
i.e; int arr[3][3][3], so the statement says that we want three such 2D arrays which consists of 3 rows and 3 columns.
int arr[3][3][3]; //3D array
block(1) 1 2 3 block(2) 10 11 12 block(3) 19 20 21
4 5 6 13 14 15 22 23 24
7 8 9 16 17 18 25 25 27
3x3 3x3 3x3
Declaring a 3D array:
To declare 3D array:
Specify data type, array name, block size, row size and column size.
Each subscript can be written within its own separate pair of brackets.
Syntax: data_type array_name[block_size][row_size][column_size];
example:
int arr[2][3][3]; //array of type integer
//number of blocks of 2D arrays:2 |rows:3 |columns:3
//number of elements:2*3*3=18
block(1) 11 22 33 block(2) 12 13 14
44 55 66 21 31 41
77 88 99 12 13 14
3x3 3x3
Ways to declare 3D array:
1). int arr[2][3][3];
In this type of declaration, we have an array of type integer, block size is 2, row size is 3 and column size is 3.Here we have not stored any values/elements in the array.So the array will hold the garbage values.
int arr[2][3][3]; //no elements are stored
block(1) 1221 -543 3421 block(2) 654 5467 -878 //all values are
3342 6543 4221 456 1567 7890 //garbage values
-564 4566 -345 567 6561 2433
3x3 3x3
2). int arr[2][3][3]={};
In this type of declaration, we have an array of type integer, block size is 2, row size is 3 and column size is 3 and we have put curly braces after assignment operator.So the array will hold 0 in each cells of array.
int arr[2][3][3]={}; //0 will be stored
block(1) 0 0 0 block(2) 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
3). int arr[3][2][2]={0,1,2,3,4,5,6,7,8,9,3,2}
In this type of declaration, we have an array of type integer, block size is 3,
row size is 2, column size is 2 and we have mentioned the values inside the curly braces during the declaration of array. So all the values will be stored one by one in the array cells.
int arr[3][2][2]={0,1,2,3,4,5,6,7,8,9,3,2}
block(1) 0 1 block(2) 4 5 block(3) 8 9
2 3 6 7 3 2
2x2 2x2 2x2
4). int arr[3][3][3]=
{ {{10,20,30},{40,50,60},{70,80,90}},
{{11,22,33},{44,55,66},{77,88,99}},
{{12,23,34},{45,56,67},{78,89,90}}
};
In this type of declaration, we have an array of type integer, block size is 3,
row size is 3, column size is 3 and the values of each blocks are assigned during its declaration.
int arr[3][3][3]=
{ {{10,20,30},{40,50,60},{70,80,90}}, //elements of block 1
{{11,22,33},{44,55,66},{77,88,99}}, //elements of block 2
{{12,23,34},{45,56,67},{78,89,90}} //elements of block 3
};
block(1) 10 20 30 block(2) 11 22 33 block(3) 12 23 34
40 50 60 44 55 66 45 56 67
70 80 90 77 88 99 78 89 90
Inserting values in 3D array:
In 3D array, if a user want to enter the values then three for loops are used.
First for loop represents the blocks of a 3D array.
Second for loop represents the number of rows.
Third for loop represents the number of columns.
Example:
Following is the implementation in C:
#include<stdio.h>
int i,j,k; //variables for nested for loops
int main()
{
int arr[2][3][3]; //array declaration
printf("enter the values in the array: \n");
for(i=1;i<=2;i++) //represents block
{
for(j=1;j<=3;j++) //represents rows
{
for(k=1;k<=3;k++) //represents columns
{
printf("the value at arr[%d][%d][%d]: ",i,j,k);
scanf("%d",&arr[i][j][k]);
}
}
}
printf("printing the values in array: \n");
for(i=1;i<=2;i++)
{
for(j=1;j<=3;j++)
{
for(k=1;k<=3;k++)
{
printf("%d ",arr[i][j][k]);
if(k==3)
{
printf("\n");
}
}
}
printf("\n");
}
return 0;
}
OUTPUT:
enter the values in the array:
the value at arr[1][1][1]: 23
the value at arr[1][1][2]: 34
the value at arr[1][1][3]: 45
the value at arr[1][2][1]: 76
the value at arr[1][2][2]: 78
the value at arr[1][2][3]: 98
the value at arr[1][3][1]: 87
the value at arr[1][3][2]: 67
the value at arr[1][3][3]: 98
the value at arr[2][1][1]: 34
the value at arr[2][1][2]: 23
the value at arr[2][1][3]: 67
the value at arr[2][2][1]: 58
the value at arr[2][2][2]: 19
the value at arr[2][2][3]: 84
the value at arr[2][3][1]: 39
the value at arr[2][3][2]: 82
the value at arr[2][3][3]: 44
printing the values in array:
23 34 45
76 78 98
87 67 98
34 23 67
58 19 84
39 82 44
In the above program;
We have declared three variables i,j,k for three for loops.
we have declared an array of type integer int arr[2][3][3];(blocks:2 rows:3 columns:3)
First section of nested for loops ask the user to insert the values.
second section of nested for loops will print the inserted values in the matrix form.
References:
The C Programming Language. 2nd Edition Book by Brian Kernighan and Dennis Ritchie
C Programming: A Modern Approach Book by Kim N. King
C Programming Absolute Beginner’s Guide book by S.D Perry