Common mistakes with arrays
Comments and questions to John Rowe.
There are (at least) two versions of this:
Forgetting that the first index is 0 and the last N-1
Wrong
| Right
|
#include <stdio.h>
int main() {
double x = 0, sides[3], y = 1;
sides[1] = 5.2;
sides[2] = 3.1;
sides[3] = 4.6;
return 0;
}
Step through this code
|
#include <stdio.h>
int main() {
double x = 0, sides[3], y = 1;
sides[0] = 5.2;
sides[1] = 3.1;
sides[2] = 4.6;
return 0;
}
Step through this code
|
Using <= in a for() loop, not <
|
Wrong
| Right
|
|
#include <stdio.h>
#define N 3
int main() {
int i, j = 0;
double sides[3], y = 1;
for(i = 0; i < N; ++i)
sides[i] = 2 + i;
return 0;
}
Step through this code
|
Trying to use an array declaration in a function call
Recall that C gives us an easy way to declare a function that
expects the address of an array:
As a convenience to the programmer, when a function expects to be passed the address
of the first element of an array the corresponding parameter
can just be declared with the same declaration as the passed
array with the left-hand dimension being ignored.
So we can declare a function expecting the address of an array as follows:
void printarray(int output[N]);
or:
void printarray(int output[]);
Some students will then sometimes try to call
the function with something like:
Wrong
| Right
|
int num[N] = {1, 2, 3, 4};
printarray(int num[N]);
|
int num[N] = {1, 2, 3, 4};
printarray(num);
|
This has no chance of success as the incorrect call is trying
to say "create a brand new array just for use as an argument to
printarray() and give it the same name as an array that already
exists". This is meaningless and the compiler will disallow it immediately.
The coreect way to to recall the rule:
When an array name is passed to a function, what is passed is the location of the beginning
of the array.
Thus passing the name of the array
actually passes the address of the array as required.
Passing the value of a non-existent array element to a function
A variation of the above, which is much more dangerous, is to
pass the array name and its dimension but without the type (in this
case "int"):
|
Wrong
| Right: same as above
|
int num[N] = {1, 2, 3, 4};
printarray(num[N]);
|
#include <stdio.h>
#define N 4
void printarray(int output[N]);
int main() {
int num[N] = {1, 2, 3, 4};
printarray(num);
return 0;
}
void printarray(int output[N]) {
int i;
for (i = 0; i < N; ++i ) {
printf("%d\n", output[i]);
}
}
Step through this code
|
which forgets the rule:
- int myarray[N] (note
the typename "int") declares a brand new array of N ints.
- myarray[j] on its own (note no "int") refers
to one particular element of the array.
So instead of passing the address of the array as required the
call tries to send the value of fifth element
of a four-element array.
Depending on your compiler options the compiler may or may not allow this,
and if it does your program will crash horribly.
Try stepping through the "good" example first and note how the
function correctly receives the address of the array
num. Then try the bad example and see how it receives a random,
very large number. When it tries to go to that non-existent memory address
the program crashes.
|
Wrong
| Right
|
#include <stdio.h>
#define N 4
void printarray(int output[N]);
int main() {
int num[N] = {1, 2, 3, 4};
printarray(num[N]);
return 0;
}
void printarray(int output[N]) {
int i;
for (i = 0; i < N; ++i ) {
printf("%d\n", output[i]);
}
}
Step through this code
|
#include <stdio.h>
#define N 4
void printarray(int output[N]);
int main() {
int num[N] = {1, 2, 3, 4};
printarray(num);
return 0;
}
void printarray(int output[N]) {
int i;
for (i = 0; i < N; ++i ) {
printf("%d\n", output[i]);
}
}
Step through this code
|