🇯🇵 日本語 | 🇺🇸 English
Advertisement

Lesson 15: Debugging Techniques

How to debug C programs. Practical coverage of printf debugging and common bugs.

πŸ“– What to learn on this page
βœ… Must-know essentials
  • Use printf to inspect values
  • Read warnings too: gcc -Wall -Wextra
  • Tackle errors in order from the first one
⭐ Read if you have time
  • Interactive debugging with gdb
  • Sanitizers (-fsanitize=address,undefined)
  • Static analysis (cppcheck, etc.)

What is Debugging — The Art of Finding and Fixing Bugs

When a program does not work as expected, debugging is the work of finding and fixing the cause. Because C is a compiled language, bugs fall broadly into two categories.
Compile errors
The code does not compile because of syntax mistakes. Compiler messages are your main clue.
Runtime bugs
Compiles, but gives wrong results or crashes. Trace them with printf debugging.

Basic debugging steps

🔍
1. Reproduce
Figure out when it happens
📍
2. Locate
Narrow down with printf
🤔
3. Hypothesize
Why is it wrong?
🛠️
4. Fix & verify
Retest after the fix
Important: Don't fix "probably here" — always confirm the cause before fixing. Guess-fixes create new bugs.

Reading Compile Errors

gcc error messages have the form filename:line:col: error: message. The trick is to fix the first error first.

Common compile errors

error: expected ';' before '}' token
Cause: Forgotten semicolon ;. Check the line before the one reported.
int x = 10   // ← no ; !
printf("%d", x);
error: 'pritnf' was not declared in this scope
Cause: Misspelled function name (pritnf → printf), or missing #include.
error: 'x' undeclared (first use in this function)
Cause: The variable was never declared, or you used it outside its scope.
warning: format '%d' expects argument of type 'int'
Cause: Type mismatch between format specifier and argument. For example using %d where a double needs %f.
Tip: Do not panic if you see a lot of errors! Fixing the first one often makes many of the rest disappear at once.

printf Debugging — The Easiest Technique

Print variable values or "got here" markers with printf to trace program behavior. Beginners can use it immediately.

Techniques

// Technique 1: print variable values
printf("DEBUG: x=%d, y=%d\n", x, y);

// Technique 2: check if execution reached this point
printf("DEBUG: reached before loop\n");

// Technique 3: print loop variables every iteration
for (int i = 0; i < n; i++) {
  printf("DEBUG: i=%d, sum=%d\n", i, sum);
  sum += a[i];
}

// Technique 4: see which branch was taken
if (x > 0) {
  printf("DEBUG: x is positive\n");
} else {
  printf("DEBUG: x is 0 or negative\n");
}

Try it yourself

The code below is supposed to "compute a sum" but has a bug that gives the wrong answer. Use printf debugging to find the cause.
Hint: Look at the DEBUG output. What does i start from? Does a[5] exist?

Common Bug Patterns

Knowing the bug patterns beginners fall into will make your debugging much faster.
Off-by-one errors
Loop bounds off by one. You started at i=1 instead of i=0, or used i<=n instead of i<n, etc.
// NG: accesses a[5] (out of bounds)
for (int i = 0; i <= 5; i++) sum += a[i];
// OK:
for (int i = 0; i < 5; i++) sum += a[i];
Uninitialized variables
Declaring a variable without initializing it leaves indeterminate (garbage) data in it.
int sum;       // ← initial value is garbage!
for (...) sum += a[i]; // garbage + a[i] = ?
// Correct: int sum = 0;
Confusing = with ==
if (x = 5) assigns 5 to x (always true). Use == for comparison.
if (x = 5)  // NG: assigns 5 to x (always true)
if (x == 5) // OK: checks whether x equals 5
Infinite loops
Forgot to update the loop variable, or the condition is always true.
int i = 0;
while (i < 10) {
  printf("%d\n", i);
  // forgot i++! -> i stays 0 forever
}
Missing & in scanf
It is scanf("%d", &x), not scanf("%d", x). Without the address scanf crashes.
scanf("%d", x);   // NG: crash!
scanf("%d", &x);  // OK

Bug Fix Challenge

The code below contains three bugs. Fix them so the output is exactly average = 5.00.
Advertisement
← Previous lesson
Lesson 14: Loops (for/while)
Next lesson →
Lesson 16: Math Functions

Related lessons

Reference
Lesson 31: Compile Errors Dictionary
A catalog of C compile errors and how to fix them. A complete guide to reading gcc messages.
Reference
Lesson 32: Runtime Errors and Segfaults
Causes of segmentation faults in C and how to fix them. A complete guide to runtime errors.

Quiz

Check your understanding!

Q1. What is the purpose of printf debugging?

Decorate the screen
Inspect variable values during execution
Make the program faster

By printing variable values or the execution path with printf, you can locate the cause of a bug. It is the most basic debugging technique.

Q2. What can a debugger (like gdb) do?

Automatically fix the code
Step through the code line by line and inspect variables
Speed up compilation

Debuggers support setting breakpoints, stepping, and watching variables — all the tools needed for detailed program analysis.

Q3. Which is a good habit for avoiding bugs?

Write large amounts of code in one go
Compile and test frequently in small increments
Never write any comments

Writing a little and testing often lets you locate bugs quickly. Comments also matter.

Share this article
Share on X Share on Facebook