Get up to 80 % extra points for free! More info:

Lesson 7 - Arrays in the C language

In the previous exercise, Solved tasks for C lesson 6, we've practiced our knowledge from previous lessons.

Lesson highlights

Are you looking for a quick reference on arrays in C instead of a thorough-full lesson? Here it is:

Shortened initialization of an array:

int numbers[] = {2, 3, 5, 7};

Writing 1 at the position [0]:

numbers[0] = 1;

Reading the value (now 1) at the position [0]:

printf("%d", numbers[0]);

Printing the whole array:

int i;
for (i = 0; i < 4; i++)
    printf("%d ", numbers[i]);

Creating an empty array and generating the values using a for loop:

#include <stdio.h>
#include <stdlib.h>
#define COUNT 16

int main(int argc, char** argv) {
    // Creates an array
    int numbers[COUNT];
    int i;
    for (i = 0; i < COUNT; i++)
        numbers[i] = i + 1;
     return (EXIT_SUCCESS);
}

Determining the size of a statically allocated array:

int numbers[10]; // Creates a new array of 10 integers
printf("The array size is: %d", sizeof(numbers)/sizeof(int));

Sorting an array using qsort():

#include <stdio.h>
#include <stdlib.h>

int compare(const void * a, const void * b)
{
    return (*(int*)a - *(int*)b);
}

int main(void)
{
    int numbers[] = {15, 8, 3, 10, 9, 2, 2};

    qsort(numbers, 7, sizeof(int), compare);

    int i;
    for (i = 0; i < 7; i++)
    {
        printf("%d ", numbers[i]);
    }
    return (EXIT_SUCCESS);
}

Would you like to learn more? A complete lesson on this topic follows.

In the previous tutorial, Solved tasks for C lesson 6, we introduced loops in the C language. In today's lesson, we're going to introduce you all to the array data structure and show you what it's capable of accomplishing.

Array

Imagine that you want to store some information about multiple items, e.g. you want to keep 10 numbers in a memory, each of the fields of a checkerboard or names of 50 users. Perhaps you realize that there must be an easier way than to start typing variables like user1, user2 ... up until user50. Despite the fact that there may be 1000 of them. How would go about searching for something in there? Definitely not like that! :)

If we need to store a larger amount of variables of the same type, we can solve this problem using an array. We can imagine it as a row of boxes, each of them containing one item. The boxes are numbered by indexes, the first one has index 0.

Array structure in C# .NET - The C Language Basic Constructs

(We see an array of 8 numbers on this picture)

Programming languages are very different in the way they work with arrays. In the lower, compiled languages, to which the C language belongs, we have to specify a fixed size for an array, and we are unable to change it during run-time. Meaning that it is not possible to add more "boxes" to an existing array, so we have to keep this in mind at all times. The C language also allows us to declare dynamically allocated arrays or use things like linked lists to work around this limitation. However, this requires rather complex knowledge and therefore we'll get to it later. On the other hand, some interpreted languages allow us to declare an array of any size and to change this size during run-time. An example of such a language is PHP.

We use loops for mass manipulation of array items.

We declare an array as an ordinary variable and then add brackets with the number of its items after the variable name:

int numbers[10];

Numbers is obviously the name of our variable. Now, there is an array of the size of 10 ints in the numbers variable. We've just created the array and the operating system has allocated memory for it which could've been used by other applications before. Therefore, we cannot be sure that it has all been zeroed out. It could be full of completely random numbers.

We access array items using the brackets as well. Let's access the first index (the index 0) and store the number 1 into it:

int numbers[10];
numbers[0] = 1;

Filling an array manually like this would be too laborious. We'll use a loop and fill the array with numbers from 1 to 10. We'll use the for loop to do so:

int numbers[10];
int i;
for (i = 0; i < 10; i++)
{
    numbers[i] = i + 1;
}

Note: We store i + 1 to the array because i goes from 0 and we want to store numbers from 1.

To write the array to the console, we can add the following code to the end of our program:

for (i = 0; i < 10; i++)
{
    printf("%d ", numbers[i]);
}

The result:

Console application
1 2 3 4 5 6 7 8 9 10

Of course, we can initialize an array manually as well and also without the need to initialize each index gradually. We can specify array items into curly brackets and separate them by commas:

int numbers[] = {15, 8, 3, 10, 9, 2, 2};

Notice that we don't need to specify the array size, the compiler will determine it from the number of elements in the curly brackets.

Arrays are often used for storing intermediate results which we can then use further in the program. If we need to use something 10 times, we won't compute it 10x, but only once. Then, we'll store the results in an array and retrieve them later.

Constants

Since we've to specify the array length in a source code and we usually use this value at multiple places of the program, it'd come in handy to have the value stored somewhere. There's nothing worse than to decide we want an array only 10 items long instead of 15 items long and forget to change some of the numbers 15 in the code, e.g. in the loop which is printing the array to the console. Therefore, we often store array sizes into constants.

A constant is a value of any type which cannot be changed. We can understand it as a read-only variable. We use constants for storing values which don't change at the run-time but we as programmers want to keep an option to change them easily in the code in case of a change needed. We define constants using the #define directive, there's a convention to name them with UPPERCASE_NAMES. We specify the value of a constant just after its name, separated by a space or a tab character, there is no "=". We define them straight after the #include directives. Let's show the complete source code of the program above using a constant for specifying the array length:

#include <stdio.h>
#include <stdlib.h>
#define COUNT 10

int main(int argc, char** argv) {
    // Creates an array
    int numbers[COUNT];

    // Fills the array
    int i;
    for (i = 0; i < COUNT; i++)
    {
    numbers[i] = i + 1;
    }

    // Prints the array
    for (i = 0; i < COUNT; i++)
    {
        printf("%d ", numbers[i]);
    }
    return (EXIT_SUCCESS);
}

Note: Commands which start with # are not the compiler commands, but commands for the preprocessor. It's a program which gets to the source code first and inserts some code snippets there to make it easier for the compiler. In our case, the preprocessor inserts the definitions of the functions from the stdio.h and stdlib.h system libraries and then replaces every occurrence of COUNT with the value 10. More precisely, the constant is a macro and there are several more things which the preprocessor can do. However, we won't bother with them now.

Array bounds

Beware! The C language doesn't make verify that we're working within the array bounds. It was made this way to maintain the high program speed. Meaning that we're able to do things like store data at the 15th index even when an array is only 10 indexes long. An array is stored as a block of bytes in memory and the C language computes the address at which it'll write based on a given index. In other words, we're able to write at an index which is too high, to a memory which it doesn't belong to. We can corrupt other data stored by our application through an array which isn't related to our current array at all. It's generally very hard to spot such errors, so we're better off avoiding them.

An array of a length specified during run-time

The C99 standard allows us to declare so-called VLA (Variable Length Array) which are arrays of a length specified after the program has begun running. Meaning that code like this will work:

int size;
printf("Enter the array size and I'll create it: ");
scanf("%d", &size);
int numbers[size];

Although it's the current standard, it's possible that the code won't work on all compilers. We can achieve a similar functionality with dynamic arrays which we'll get familiar with in the next course. Even with VLAs, once we create an array, its size can't be changed.

Array size

The arrays which we've created were allocated statically. We're able to determine the size of array of this kind using the following approach:

int numbers[10]; // Creates a new array of 10 integers
printf("The array size is: %d", sizeof(numbers)/sizeof(int));

We simply determine how many bytes the whole array occupies and then divide this number by the size of the data type of a single item. This way, we get the number of items within it.

The result:

Console application
The array size is: 10

This approach cannot be used with dynamic arrays and texts, so it's better not to stick to it.

Sorting an array

We often need to sort items in an array. For example, when we need to get the highest/lowest wage, number of points, costs, the number of pieces, etc. Although this a task was often given to students to train for algorithms, the standard C library provides the qsort() function for these purposes. Calling it is a bit complicated, we're going to describe it rather intuitively. Nothing is stopping us from using the function now (you'll understand it better further along in the courses).

#include <stdio.h>
#include <stdlib.h>

int compare(const void * a, const void * b)
{
    return (*(int*)a - *(int*)b);
}

int main(void)
{
    int numbers[] = {15, 8, 3, 10, 9, 2, 2};

    qsort(numbers, 7, sizeof(int), compare);

    int i;
    for (i = 0; i < 7; i++)
    {
        printf("%d ", numbers[i]);
    }
    return (EXIT_SUCCESS);
}

Aside from the main() function, we also have a comparing function which defines how to compare two array items. This is because qsort() internally compares pairs of array items, and is able to sort the array in doing so. Don't mind the asterisk syntax, it's only about returning a - b, which would be positive for a > b, zero if a equals b and negative for a < b. qsort() will be able to compare items according to this value. If we wanted to sort the array as descending, we'd enter b - a.

Creating the array should be clear to you all. When calling qsort(), it's necessary to specify an array, and also the size of a single element in bytes, and the comparing function. The array items are now sorted. However, we'll write them to the console just to make sure.

The result:

Console application
2 2 3 8 9 10 15

That's enough for today, you can play with arrays for a while if you'd like. In the next lesson, Solved tasks for C lesson 7, we'll finally learn how to work with texts in the C programming language ;-)

In the following exercise, Solved tasks for C lesson 7, we're gonna practice our knowledge from previous lessons.


 

Previous article
Solved tasks for C lesson 6
All articles in this section
The C Language Basic Constructs
Skip article
(not recommended)
Solved tasks for C lesson 7
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities