-
Notifications
You must be signed in to change notification settings - Fork 0
Arrays
Sometimes you need to store a collection of elements of same data type. Array is a data structure that can store a fixed amount of elements, all of the same data type. You can think of an array as a collection of variables.
Imagine you want to get the grades of every student from some class and perform some tasks like calculate the average grade, the maximum grade and the minimum grade. That doesn't require an array, you can have a loop that asks for the grades, sums them and then calculates the average. For the maximum and minimum grade, you only to compare the actual minimum and maximum with the inserted grade and update the variables as needed.
#include <stdio.h>
int main()
{
// assuming the class has 5 students, just to simplify
const unsigned int n_students = 5;
// variables declartion
float sum = 0, max = 0, min = 20; // grades range [0,20]
for(unsigned int i = 0; i < n_students; i++)
{
float grade;
printf("Student %d grade ? ", i+1);
scanf("%f", &grade);
sum += grade;
if(grade > max) max = grade;
else if (grade < min) min = grade;
}
printf("Average : %f\n", sum/n_students); // sum is float type, n_students is int type -> the result is float
printf("Max : %f\n", max);
printf("Min : %f\n", min);
}
Now imagine that the teacher will review the exams. Every time an exam is reviewed the grade on the program needs to be updated and the average, minimum and maximum needs to be determined. If you used the code above you would need to ask for all grades again. Every time a grade is entered the previous grade is lost. This is an example where you need to store a collection of data and an array is used for that.
#include <stdio.h>
float avg(float grades[], unsigned int n);
float max(float grades[], unsigned int n);
float min(float grades[], unsigned int n);
int main()
{
const unsigned int n_students = 5; // assuming the class has 5 students, just to simplify
float grades[5];
for(unsigned int i = 0; i < n_students; i++)
{
float aux;
printf("Student %d grade ? ", i+1);
scanf("%f", &aux);
grades[i] = aux;
}
// calculate average, maximum and minimum
printf("Average : %f\n", avg(grades, n_students));
printf("Max : %f\n", max(grades, n_students));
printf("Min : %f\n", min(grades, n_students));
// loop to update grades
while(1)
{
unsigned int studentID;
char c;
float studentGrade;
printf("Update grade <Y/N> ? ");
scanf(" %c", &c); // why " %c" and not "%c" ?
if(c == 'n' || c == 'N') break;
// asks the student id
printf("Student number ? ");
scanf("%u", &studentID);
printf("New grade ? ");
scanf("%f", &studentGrade);
// updates grade on array
grades[studentID-1] = studentGrade; // students id start at 1
// shows new average, maximum and minimum
printf("Average : %f\n", avg(grades, n_students));
printf("Max : %f\n", max(grades, n_students));
printf("Min : %f\n", min(grades, n_students));
}
}
float avg(float grades[], unsigned int n)
{
float sum = 0;
for(unsigned int i = 0; i < n; i++)
{
sum += grades[i];
}
return sum/n;
}
float max(float grades[], unsigned int n)
{
float max = 0;
for(unsigned int i = 0; i < n; i++)
{
if(grades[i] > max)
max = grades[i];
}
return max;
}
float min(float grades[], unsigned int n)
{
float min = 20;
for(unsigned int i = 0; i < n; i++)
{
if(grades[i] < min)
min = grades[i];
}
return min;
}
Declaring an array is similar to declare a variable. You tell the elements data type, provide a name and specify the array size.
data_type array_name[size];
The array size needs to a defined value at compiling time. Therefore, you can't use a variable to determine the array size.
#include <stdio.h>
int main()
{
unsigned int a;
scanf("%u", &a);
int array[a]; // illegal
}
Moreover, array size is constant through the program lifetime. You would need to use dynamic memory to resize the array.
When you declare an array, a contiguous block of memory is reserved for the array elements. If the array elements are int
, each element has 4 bytes. Then, if the array size is 10, 40 bytes are reserved for the array elements. Because elements are contiguous on memory you can access every element if you know the memory address of the first element.
int a[10];
If the first element (a[0]) address is 0, the second element (a[1]) is located at adress 4. This is how indexs let's you access the array elements. The address of the N element is calculated &a[0] + (N * 4)
.
The elements on an array are indexed. The first element has index 0, the second has index 1, ... the last element has index n-1, where n is the array size. To access some element on the array, you type the array name followed by rectangular brackets with a index inside.
int a[10];
int fifthElement = a[4];
When you declare a variable it will contain "junk". The same applies for an array. Unless you initialize the array elements they will hold a value without meaning for your program.
You can declare and initialize an array on the same statement:
int a[5] = {1,2,3,4,5};
int b[10] = {1,2}; // the first element is 1, the second is two, the other elements are zero
int c[] = {1,2,3}; // the array size is determined by the amount of elements between curly brackets
You can also initialize individual elements of the array, with user input for example. You just type the array name, index and assign a value that matches the data type.
int a[5];
printf("Number ? ");
scanf("%d", &a[2]);
There are some key notes about declaring a function that gets an array on the parameter list. This is how you do it:
void showElements(int a[])
{
// ...
}
And to pass an array to the function:
int bananas[] = {1,666,2,551,2522};
showElements(bananas);
It's as simple as passing any other variable to a function. However, there's a problem. In function showElements
you don't have a way to acknowledge the array size. There's an operator, sizeof, that returns the amount of bytes used by a variable. If each integer uses 4 bytes, you could easily calculate the number of elements.
#include <stdio.h>
void showElements(int a[])
{
printf("Size of argument a[] = %d\n", sizeof(a));
int numberElements = sizeof(a)/sizeof(int);
}
int main()
{
int a[5] = {666,22,5,89,7};
printf("Size of a[5] = %d\n", sizeof(a));
showElements(a);
}
/*OUTPUT
Size of a[5] = 20
Size of argument a[] = 4
*/
The size of the array on the function showElements
is 4 bytes, and not 20 bytes as expected (5 elements * 4 bytes). This is because the function actually gets the address of the first element in the array (pointers 🙈), not the actual array. For that reason, using sizeof operator doesn't solve the problem. The only way is passing an additional parameter with the number of elements.
#include <stdio.h>
void showElements(int a[], unsigned int n)
{
for(int i = 0; i < n; i++)
printf("a[%d]:%d\n", i, a[i]);
}
int main()
{
int a[5] = {666,22,5,89,7};
showElements(a, 5);
}
- Write a program that fills two arrays of some pre-defined size (at your choice) with user input, adds the two arrays and outputs the new array elements.
This problem has three common tasks. Fill an array, add two arrays and display an array. Therefore, you should write at least three functions to solve the problem.
First array
Element 0 ? 5
Element 1 ? 5
Element 2 ? 5
Element 3 ? 5
Element 4 ? 5
Second array
Element 0 ? 1
Element 1 ? 2
Element 2 ? 3
Element 3 ? 4
Element 4 ? 5
Sum : { 6 7 8 9 10 }
Soon...