C Edge Cases and Logical Errors
Edge Cases
When you test a program, you should not only test normal values, like 5 or 42. You should also test unusual values, because many bugs hide there.
These unusual values are called edge cases.
Here are edge cases to try for common kinds of input:
| Input | Edge cases to try |
|---|---|
| A number | 0, 1, a negative number, a very large number |
| An array | No values at all, only one value, all values the same |
| A string | An empty string (""), one letter, uppercase letters, spaces |
| A range, like 1 to 100 | The first and last value (1 and 100), and the values just outside (0 and 101) |
You have already seen an edge case: in the Problem Solving chapter, the text "APPLE" showed that the program did not count uppercase vowels.
Logical Errors
A logical error happens when your program runs without any error messages, but gives the wrong result.
The program does exactly what you wrote, but not what you wanted it to do.
The compiler cannot find logical errors for you, because the code is valid C. You find them by testing. Here are some of the most common ones:
| Mistake | Wrong | Correct |
|---|---|---|
| Off by one: the loop runs one time too many (or too few) | for (i = 0; i <= 5; i++) on an array with 5 values |
i < 5 |
= instead of == |
if (x = 5) changes x to 5, and is always true |
if (x == 5) |
| Integer division | 5 / 2 is 2 |
5 / 2.0 is 2.5 |
| Conditions in the wrong order | Checking >= 50 before >= 90 in the grades code |
Check the strictest rule first |
| A counter that is not reset | count keeps the value from the last time |
Set it to 0 before you start counting again |
Worked Problem: Even or Odd
Let's find an edge case and a logical error in a real program. This program should print if each number is even or odd:
Example
#include <stdio.h>
int main() {
int numbers[] = {7, 4, 0, -7};
for (int i = 0; i < 4; i++) {
int n = numbers[i];
if (n % 2 == 1) {
printf("%d is odd\n", n);
} else {
printf("%d is even\n", n);
}
}
return 0;
}
Result:
7 is odd
4 is even
0 is even
-7 is even
Try it Yourself »
It looks right. The numbers also include the edge cases from the table above: 0 and a negative number. Let's compare what the program says with what we expect:
| Number | Expected | The program says |
|---|---|---|
| 7 | odd | odd |
| 4 | even | even |
| 0 | even | even |
| -7 | odd | even (wrong) |
The test with -7 fails. Why? In C, the remainder of a negative number is also negative: -7 % 2 is -1, not 1. So n % 2 == 1 is false, and the program says "even".
This is both an edge case (a negative number) and a logical error (the program runs, but gives the wrong answer).
The fix: check for even numbers instead, with n % 2 == 0. The remainder of an even number is always 0, also for negative numbers:
Example
#include <stdio.h>
int main() {
int numbers[] = {7, 4, 0, -7};
for (int i = 0; i < 4; i++) {
int n = numbers[i];
if (n % 2 == 0) {
printf("%d is even\n", n);
} else {
printf("%d is odd\n", n);
}
}
return 0;
}
Result:
7 is odd
4 is even
0 is even
-7 is odd
Try it Yourself »
Compare the two checks. Choose one, and see what it does with each number:
Code
What happens with each number
Explanation
How to Find Logical Errors
- Know the expected result first. Solve the test by hand, before you run the program.
- Test the edge cases from the table above, not only the normal cases.
- Use
printf()to see what your variables contain while the program runs (see Debugging). - Use a trace table to follow the code by hand.
Testing one input at a time, again and again, is slow. In the next chapter, you will learn how to run many test cases at once.