The Array in the C Computer Language
Part 15 of Complete C Course
Foreword: The Array in the C Computer Language
By: Chrysanthus Date Published: 3 Jun 2024
Introduction
Array of Integers
The following is an array of 5 integers:
int arrInt[] = {25, 20, 256, 5, 7};
The syntax to define an array is:
Type arrayName[] = {value1, value2, value3, . . .};
It begins with the type for the objects that will be in the array. Then there is a space. Next, there is the name (identifier) of the array. This is followed by the open square and close square brackets. The assignment operator follows. Next, there is a block delimited by curly brackets. Inside the block, there is data for the array. All the data must be of the same type. The data are separated by commas. After the last datum, there is no need for a comma. This last comma is actually optional. Each datum is kept in an object (region) in memory. The objects lie next to another in memory, forming a consecutive set of objects, of the same type.
The data in an array has meaning. For example, an array of ints might be an array of students marks, in a test. The name of the array will have to be related to the meaning of the data. The following is the creation of an array of marks, for 10 students.
int marks[] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};
Arrays of floats, _Bools and chars
The following is the creation of an array of floats:
float arrFlt[] = {12.56, 0.258, 5.4, 456.01};
The number of elements in the float array is 4. For the gcc compiler, each of these floats occupies four bytes (32 bits). The int type object also occupies four bytes (with gcc).
The following is the creation of an array of _Bools:
_Bool arrB[] = {1, 0, 0, 1, 0, 1};
The following is the creation of an array of chars:
char arrChar[] = {'A', 'a', 'C', 'e', 'F', 'Y'};
Note that each char value in the block (array) is in single quotes (of the text editor and not of the word processor).
Declaring an Array
All the above arrays have been created by initialization; and no integer was included between the square brackets. An array can be declared and then, the actual elements assigned later. The syntax to declare an array, without initialization, is:
Type arrayName[size];
It begins with the type, a space, then array name, and then the square brackets, within which is a positive integer. Inside the square brackets, there is the positive integer, which is the size of the array. To define an array of int that will have a size (number of elements) of 15, type something like:
int myArr[15];
Definition means, having the identifier and type, and with the allocation of memory. Without the actual (practical) elements assigned to the array myArr, the 15 in the square brackets, still allocate space for 15 integers: this is 15 X 4 bytes for total number of bytes, since one integer takes 4 bytes. Each of these 15 locations, may or may not have the default value for integer, which is 0 (depending on the compiler). Declaration means, having the identifier and type, with or without memory allocated. In other-words, definition is declaration, but declaration is not necessarily definition.
Index
int marks[] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};
The first element in the array is 43; the second is 29; the third is 35, and so on. The values in an array have positions. These positions are called indices (indexes). Index (position) counting in computing and arrays, begins from zero, not one. So the index of 43 above is zero; that of 29 is 1; that of 35 is 2; and so on.
Accessing an Array Element
To access a value in an array, the index needs to be known. The syntax to access an array element (value) after the array has been defined or initialized is:
arrayName[index]
If the first element of the array is to be accessed, type:
marks[0]
To access the second element, type:
marks[1]
To access the third element, type:
marks[2]
and so on. Always subtract 1 from the English position (ordinal number), to have the index. When accessing an array value, the index should not be more than the array size minus 1.
Assigning and Changing an Array Value
After declaring an array, the size of the array is known. Also, after initializing an array, the size of the array remains the same. After declaring an array without initialization, the array is like empty. However, after initialization of an array with non-default values (practical values), the array is not empty. Whatever is the case, the value of an array element can be assigned or changed as follows:
arrayName[index] = value;
Assume that a value of 47 is wanted, for an int array at index, 5. To assign or change the value at index, 5, type:
marks[5] = 47;
Do not forget the semicolon at the end of the statement. Remember, index 5 means English position (ordinal number) 6.
Example
In the following example, an int array is defined. Five integers are assigned (initialized) to this array and then displayed. The display is done using a for-loop.
#include <stdio.h>
int main(int argc, char *argv[])
{
int myIntArr[5];
myIntArr[0] = 8;
myIntArr[1] = 63;
myIntArr[2] = 55;
myIntArr[3] = 78;
myIntArr[4] = 2;
for (int i = 0; i < 5; i++) {
printf("%i ", myIntArr[i]);
}
printf("\n");
return 0;
}
The output is: 8 63 55 78 2 . An array can still be defined with the initializer_list, and a number in square brackets, as follows:
int marks[10] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};
There are ten elements in this array, so there is 10 in the square brackets. This number should not be less than the maximum number of values needed for the array.
The size of the array means the number of elements in the array. The programmer defining the array would know the size of the array as he defines the array. However, if the array was designed by another programmer, and the current programmer does not know the size, then the current programmer can still determine the size. This is done using the sizeof operator. If the argument of the sizeof operator is an array identifier, then the sizeof operator will return the total number of bytes in the array. This number is divided by the size in bytes, of each element in the array (all elements in an array have the same size in bytes), to give the number of elements in the array. That is:
numberOfElements = sizeof(arrayName) / sizeof(Type);
The size of the first element in the array, is the size of each element in the array, since all elements in an array have the same size, in bytes. By dividing the size of the array in bytes by the size of one element in bytes, the number of elements in the array is obtained, as in the following formula:
numberOfElements = sizeof(arrayName) / sizeof(arrayName[0]);
Remember that index counting starts at 0 and not 1. So the index for the first element is 0. So, when the type of each element is known, the first formula is used. When the type of each element is not known, the second formula is used. The following program illustrates the calculation, for the second formula:
#include <stdio.h>
int main(int argc, char *argv[])
{
int arrInt[] = {25, 20, 256, 5, 7};
int numOfElems = sizeof(arrInt) / sizeof(arrInt[0]);
printf("%i\n", numOfElems);
return 0;
}
The output is 5. There are 5 integers in the array, each occupying four bytes. So the total number of bytes in the array is 20 bytes. 20 / 4 = 5, the number of elements in the array.
Consider the following array:
int arr[] = {000, 100, 200, 300, 400};
The name of the array, arr is actually the identifier that has the address of the first element of the array. The following expression returns the first value of the array:
*arr
With the array, the increment operator, ++ behaves differently. Instead of adding 1, it replaces the address of the pointer, with the address of the next element in the array. However, the name of the array is a constant pointer; meaning its content (address of pointed object) cannot be changed or incremented. So, to increment, the start address of the array has to be assigned to a non-constant pointer as follows:
int *ptr = arr;
Now, ptr can be incremented to point to the next element of the array. ptr has been declared here as a pointer object. Without * here, it would not be a pointer; it would be an identifier to hold an int object and not to hold a memory address (for the pointed object).
The following code segment finally points to the fourth element:
++ptr;
++ptr;
++ptr;
The following code (program) outputs the fourth value of an array:
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[] = {000, 100, 200, 300, 400};
int *ptr = arr;
++ptr;
++ptr;
++ptr;
printf("%i\n", *ptr);
return 0;
}
The output is 300. Note the use of the indirection operator, * in the pointer declaration and the printf() statement. Those are two different uses of the indirection operator.
Adding an Integer to a Pointer
In the previous program, instead of incrementing the pointer three times, 3 could just have been added to the pointer. This makes the pointer point to the third element ahead. Note: 3 is not added to the memory address. Read and test the following program:
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[] = {000, 100, 200, 300, 400};
int *ptr = arr;
ptr = ptr + 3;
printf("%i\n", *ptr);
return 0;
}
The output is still 300 as expected.
Constant Array Content
Consider the following code segment:
float arr[] = {0.0, 1.1, 2.2, 3.3, 4.4};
arr[2] = 2.5;
The array is declared in the normal way for the first statement, and the value at index 2 is changed in the second statement. The array name, arr is a constant pointer, meaning that the address it holds, which points to the first element of the array, cannot be changed. This does not mean that the array element values cannot be changed. In fact, the value of the element at index 2, has been changed.
To prevent the values of an array from being changed, precede the declaration with the reserved word, const, for constant. The following code will not compile, and will issue an error message, because an attempt is made to change an array value, when the declaration was preceded by const:
const float arr[] = {0.0, 1.1, 2.2, 3.3, 4.4};
arr[2] = 2.5;