Arrays
Introduction
An array is a data structure used to process multiple elements with the same data type when a number of such elements are known. You would use an array when, for example, you want to find out the average grades of a class based on the grades of 50 students in the class. Here you cannot define 50 variables and add their grades. This is not practical. Using an array, you can store grades of 50 students in one entity, say grades, and you can access each entity by using subscript as grades[1], grades[2]. Thus you have to define the array of grades of the float data type and a size of 50. An array is a composite data structure; that means it had to be constructed from basic data types such as array integers.
Program
#include main() { int a[5]; \A for(int i = 0;i<5;i++) { a[i]=i;\B } printarr(a); } void printarr(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d ",a[i]); } }
Explanation
- Statement A defines an array of integers. The array is of the size 5—that means you can store 5 integers.
- Array elements are referred to using subscript; the lowest subscript is always 0 and the highest subscript is (size –1). If you refer to an array element by using an out-of-range subscript, you will get an error. You can refer to any element as a[0], a[1], a[2], etc.
- Generally, you can use a for loop for processing an array. For the array, consecutive memory locations are allocated and the size of each element is same.
- The array name, for example, a, is a pointer constant, and you can pass the array name to the function and manipulate array elements in the function. An array is always processed element by element.
- When defining the array, the size should be known.
Note |
The array subscript has the highest precedence among all operators thus a[1] * a[2] gives the multiplication of array elements at position 1 and position 2. |
Points to Remember
- An array is a composite data structure in which you can store multiple values. Array elements are accessed using subscript.
- The subscript operator has the highest precedence. Thus if you write a[2]++,it increments the value at location 2 in the array.
- The valid range of subscript is 0 to size −1.
ADDRESS OF EACH ELEMENT IN AN ARRAY
Introduction
Each element of the array has a memory address. The following program prints an array limit value and an array element address.
Program
#include void printarr(int a[]); main() { int a[5]; for(int i = 0;i<5;i++) { a[i]=i; } printarr(a); } void printarr(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d ",a[i]); } } void printdetail(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d and address is %16lu ",a[i],&a[i]); \ A } }
Explanation
- The function printarr prints the value of each element in arr.
- The function printdetail prints the value and address of each element as given in statement A. Since each element is of the integer type, the difference between addresses is 2.
- Each array element occupies consecutive memory locations.
- You can print addresses using place holders %16lu or %p.
Point to Remember
For array elements, consecutive memory locations are allocated.
ACCESSING AN ARRAY USING POINTERS
Introduction
You can access an array element by using a pointer. For example, if an array stores integers, then you can use a pointer to integer to access array elements.
Program
#include void printarr(int a[]); void printdetail(int a[]); main() { int a[5]; for(int i = 0;i<5;i++) { a[i]=i; } printdetail(a); } void printarr(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d ",a[i]); } } void printdetail(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d and address is %8u ",a[i],&a[i]); } } void print_usingptr(int a[]) \ A { int *b; \ B b=a; \ C for(int i = 0;i<5;i++) { printf("value in array %d and address is %16lu ",*b,b); \ D b=b+2; \E } }
Explanation
- The function print_using pointer given at statement A accesses elements of the array using pointers.
- Statement B defines variable b as a pointer to an integer.
- Statement C assigns the base address of the array to b, thus the array's first location (a[0]) is at 100; then b will get the value 100. Other elements of the array will add 102,104, etc.
- Statement D prints two values: *b means the value at the location specified by b, that is, the value at the location 100. The second value is the address itself, that is, the value of b or the address of the first location.
- For each iteration, b is incremented by 2 so it will point to the next array location. It is incremented by 2 because each integer occupies 2 bytes. If the array is long then you may increment it by 4.
Points to Remember
- Array elements can be accessed using pointers.
- The array name is the pointer constant which can be assigned to any pointer variable.
MANIPULATING ARRAYS USING POINTERS
Introduction
When the pointer is incremented by an increment operator, it is always right incremented. That is, if the pointer points to an integer, the pointer is incremented by 2, and, if it is long, it is incremented by 4.
Program
#include void printarr(int a[]); void printdetail(int a[]); void print_usingptr(int a[]); main() { int a[5]; for(int i = 0;i<5;i++) { a[i]=i; } print_usingptr(a); } void printarr(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d ",a[i]); } } void printdetail(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d and address is %8u ",a[i],&a[i]); } } void print_usingptr(int a[]) { int *b; b=a; for(int i = 0;i<5;i++) { printf("value in array %d and address is %16lu ",*b,b); b++; // A } }
Explanation
- This function is similar to the preceding function except for the difference at statement A. In the previous version, b = b+2 is used. Here b++ is used to increment the pointer.
- Since the pointer is a pointer to an integer, it is always incremented by 2.
Point to Remember
The increment operator increments the pointer according to the size of the data type.
ANOTHER CASE OF MANIPULATING AN ARRAY USING POINTERS
Introduction
You can put values in the memory locations by using pointers, but you cannot assign the memory location to an array to access those values because an array is a pointer constant.
Program
#include void printarr(int a[]); void printdetail(int a[]); void print_usingptr_a(int a[]); main() { int a[5]; int *b; int *c; for(int i = 0;i<5;i++) { a[i]=i; } printarr(a); *b=2; \ A b++; \ B *b=4; \ C b++; *b=6; \ D b++; *b=8; \ E b++; *b=10; b++; *b=12; b++; a=c; //error \F printarr(a); } void printarr(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d ",a[i]); } } void printdetail(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d and address is %16lu ",a[i],&a[i]); } } void print_usingptr_a(int a[]) { for(int i = 0;i<5;i++) { printf("value in array %d and address is %16lu ",*a,a); \ F a++; // increase by 2 bytes \ G } }
Explanation
- You can assign a value at the location specified by b using statement A.
- Using statement B, you can point to the next location so that you can specify a value at that location using statement C. Using this procedure, you can initialize 5 locations.
- You cannot assign the starting memory location as given by statement F to access those elements because a is a pointer constant and you cannot change its value.
- The function print_usingptr_a works correctly even though you are writing a++. This is because when you pass a as a pointer in an actual parameter, only the value of a is passed and this value is copied to the local variable. So changing the value in the local variable will not have any effect on the outside function.
Point to Remember
The array limit is a pointer constant and you cannot change its value in the program.
TWO DIMENSIONAL ARRAY
Introduction
You can define two- or multi-dimensional arrays. It is taken as an array of an array. Logically, the two-dimensional array 3 X 2 is taken as
3 1 5 2 8 7
Here there are three arrays, i.e. one array in each row. The values are stored as
3 1 5 2 8 7
This style is called row measure form. Each row array is represented as a[0], which consists of elements 3 and 1. a[1] consists of 5 2 and a[2] consists of 8 7. Each element of a[0] is accessed as a [0] [0] and a[0] [1], thus the value of a[0][0] and a[0][1] is 1.
Program
#include void printarr(int a[][]); void printdetail(int a[][]); void print_usingptr(int a[][]); main() { int a[3][2]; \ A for(int i = 0;i<3;i++) for(int j=0;j<2 ;j++) { { a[i]=i; } } printdetail(a); } void printarr(int a[][]) { for(int i = 0;i<3;i++) for(int j=0;j<2;j++) { { printf("value in array %d ",a[i][j]); } } } void printdetail(int a[][]) { for(int i = 0;i<3;i++) for(int j=0;j<2;j++) { { printf( "value in array %d and address is %8u ", a[i][j],&a[i][j]); } } } void print_usingptr(int a[][]) { int *b; \ B b=a; \ C for(int i = 0;i<6;i++) \ D { printf("value in array %d and address is %16lu ",*b,b); b++; // increase by 2 bytes \ E } }
Explanation
- Statement A declares a two-dimensional array of the size 3 × 2.
- The size of the array is 3 × 2, or 6.
- Each array element is accessed using two subscripts.
- You can use two for loops to access the array. Since i is used for accessing a row, the outer loop prints elements row-wise, that is, for each value of i, all the column values are printed.
- You can access the element of the array by using a pointer.
- Statement B assigns the base address of the array to the pointer.
- The for loop at statement C increments the pointer and prints the value that is pointed to by the pointer. The number of iterations done by the for loop, 6, is equal to the array.
- Using the output, you can verify that C is using row measure form for storing a two-dimensional array.
Points to Remember
- You can define a multi-dimensional array in C.
- You have to provide multiple subscripts for accessing array elements.
- You can access array elements by using a pointer.
THREE DIMENSIONAL ARRAY
Introduction
Just as with a two-dimensional array, you can define three-dimensional arrays and processing in a similar way. Each three-dimensional array is taken as an array of two-dimensional arrays.
Program
#include main() { int a[2][3][4]; \ A int b[3][4]; \ B int c[4]; \ C int cnt=0; for(int i=0;i<2;i++) for(int j=0;j<3;j++) for(int k=0;k<4;k++) { a[i][j][k] = cnt; cnt; } } void print_onedim(int a[]) \ D { for(int i=0;i<4;i++) printf("%d ",a[i]); } void print_twodim(int a[][4]) \ E { for(int j=0;j<3;j++) print_onedim(a[j]); printf(" "); } void print_threedim(int a[][3][4]) \ F { printf("Each two dimension matrix "); for(int j=0;j<2;j++) print_twodim(a[j]);; }
Explanation
- The three-dimensional array consists of two arrays of the size 3 × 4. Each is referred to as a[0] a[1]. Thus a[0] consists of 12 elements and a[1] also consists of 12 elements.
- Each two-dimensional array is taken as three arrays of the size 4.
- The function print_onedim prints a single-dimensional array.
- The function print_twodim prints a two-dimensional array and it calls the function for printing a single-dimensional value.
- The function print_threedim prints a three-dimensional array and calls the function for printing a three-dimensional value.
- Dimension two, which is closer to the array name, is called the outermost dimension, and dimension four, which is far from the array name declaration, is called the innermost dimension.
- When you pass an array to the function, you have to specify the inner dimension. For example, to print two_dim you have to specify the inner dimension, i.e. 4, and for printthree_dim you have to pass 3 and 4 as inner dimensions.
- When you pass a single-dimension array, you need not pass a dimension because the function knows what the best address of the array is.
- In a case of a two-dimensional array, we have to pass the inner dimension because only then does the function know the base address of each array. For example, if the declaration is
int a[3][4]
it is considered as three arrays of the size 4. So the base address of a[0] is a itself. The base address of a[1] is a+8 because the first row has 4 elements of size 2 bytes each; thus we can get the base address of a[1]. Similarly, the base address of a[2] is a+16. Thus, to calculate the base address, you should know the inner dimension, 4.
Points to Remember
- You can declare a multi-dimensional array and access it in a similar way to accessing a two-dimensional array.
- While passing an array to the function, you have to specify the inner dimension to facilitate calculations of the base addresses.
POINTER ARRAYS
Introduction
You can define a pointer array similarly to an array of integers. In the pointer array, the array elements store the pointer that points to integer values.
Program
#include void printarr(int *a[]); void printarr_usingptr(int *a[]); int *a[5]; \ A main() { int i1=4,i2=3,i3=2,i4=1,i5=0; \ B a[0]=&i1; \ C a[1]=&i2; a[2]=&i3; a[3]=&i4; a[4]=&i5; printarr(a); printarr_usingptr(a); } void printarr(int *a[]) \ D { printf("Address Address in array Value "); for(int j=0;j<5;j++) { printf("%16u %16u %d ", a[j],a[j],a[j]); \E } } void printarr_usingptr(int *a[]) { int j=0; printf("using pointer "); for( j=0;j<5;j++) { printf("value of elements %d %16lu %16lu ",**a,*a,a); \ F a++; } }
Explanation
- Statement A declares an array of pointers so each element stores the address.
- Statement B declares integer variables and assigns values to these variables.
- Statement C assigns the address of i1 to element a[0] of the array. All the array elements are given values in a similar way.
- The function print_arr prints the address of each array element and the value of each array element (the pointers and values that are pointed to by these pointers by using the notations &a[i], a[i] and *a[i]).
- You can use the function printarr_usingptr to access array elements by using an integer pointer, thus a is the address of the array element, *a is the value of the array element, and **a is the value pointed to by this array element.
Point to Remember
You can store pointers in arrays. You can access values specified by these values by using the * notations.