README
Comments and Documentation in C
📖 Introduction
Comments are explanatory text that the compiler ignores. They help make code understandable for humans - including your future self! Good documentation is a hallmark of professional code.
🎯 Types of Comments
C Comments
│
┌─────────────┴─────────────┐
│ │
Single-Line Multi-Line
// ... /* ... */
│ │
C99 and later C89 compatible
One line only Can span lines
📝 Single-Line Comments (//)
Single-line comments start with // and continue to the end of the line.
// This is a single-line comment
int count = 10; // Initialize counter
// You can have multiple
// single-line comments
// in a row
Characteristics:
- •Available since C99 (borrowed from C++)
- •Cannot span multiple lines
- •Often used for brief explanations
📋 Multi-Line Comments (/* */)
Multi-line comments start with /* and end with */.
/* This is a multi-line comment.
It can span multiple lines.
Very useful for longer explanations. */
/*
* This is a more stylized
* multi-line comment with
* asterisks on each line.
*/
int x = 5; /* inline comment */ int y = 10;
Characteristics:
- •Available since C89 (original C)
- •Can span multiple lines
- •Can appear anywhere in code
- •Cannot be nested!
⚠️ Nesting Problem:
/* Outer comment
/* Inner comment */ <- This ends the outer comment!
More text here causes an error
*/ // ERROR: This is now outside the comment
🏗️ Documentation Comments
Function Documentation:
/**
* @brief Calculates the factorial of a number.
*
* This function computes n! (n factorial) using
* an iterative approach. For n = 0, returns 1.
*
* @param n The non-negative integer to compute factorial for
* @return The factorial of n, or -1 if n is negative
*
* @warning For n > 12, result may overflow 32-bit int
* @see power(), fibonacci()
*
* @example
* int result = factorial(5); // result = 120
*/
int factorial(int n) {
if (n < 0) return -1;
if (n == 0) return 1;
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
Common Documentation Tags:
| Tag | Description |
|---|---|
@brief | Short description |
@param | Parameter description |
@return | Return value description |
@warning | Warning about usage |
@note | Additional notes |
@see | Reference to related items |
@example | Usage example |
@author | Author information |
@date | Date created/modified |
@version | Version number |
@deprecated | Marks as deprecated |
@todo | Pending tasks |
📄 File Header Comments
Every source file should start with a header comment:
/**
* @file calculator.c
* @brief Simple calculator implementation
*
* This file contains functions for basic arithmetic
* operations including addition, subtraction,
* multiplication, and division.
*
* @author John Smith
* @date 2024-01-15
* @version 1.0
*
* @copyright Copyright (c) 2024 Example Corp
* @license MIT License
*
* Revision History:
* 1.0 - Initial release
* 1.1 - Added error handling for division by zero
*/
#include <stdio.h>
#include <stdlib.h>
// Rest of the code...
🔧 Function Header Comments
/**
* @brief Searches for a value in a sorted array using binary search.
*
* @param arr Pointer to the sorted array (must be ascending order)
* @param size Number of elements in the array
* @param target Value to search for
*
* @return Index of target if found, -1 otherwise
*
* @pre arr must not be NULL
* @pre arr must be sorted in ascending order
* @pre size must be > 0
*
* @post Array is unchanged
*
* @note Time complexity: O(log n)
* @note Space complexity: O(1)
*
* @example
* int arr[] = {1, 3, 5, 7, 9};
* int idx = binarySearch(arr, 5, 7); // idx = 3
*/
int binarySearch(int *arr, int size, int target) {
int left = 0;
int right = size - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Not found
}
📐 Inline Comments
Good Inline Comments:
// Calculate the area of a circle: A = πr²
float area = 3.14159f * radius * radius;
// Handle the edge case where divisor is zero
if (divisor == 0) {
return ERROR_DIVIDE_BY_ZERO;
}
// Use bitwise AND to check if number is odd
// (odd numbers have LSB = 1)
if (n & 1) {
printf("Odd number\n");
}
Bad Inline Comments:
// BAD: States the obvious
int x = 5; // Set x to 5
// BAD: Doesn't explain WHY
count++; // Increment count
// BAD: Outdated comment (code says otherwise)
// Add 10 to the value
value = value - 10;
🏷️ Section Comments
Divide your code into logical sections:
/* ============================================================
* INCLUDES AND DEFINITIONS
* ============================================================ */
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
/* ============================================================
* TYPE DEFINITIONS
* ============================================================ */
typedef struct {
int x, y;
} Point;
/* ============================================================
* GLOBAL VARIABLES
* ============================================================ */
static int globalCounter = 0;
/* ============================================================
* HELPER FUNCTIONS
* ============================================================ */
static int helper(int n) {
return n * 2;
}
/* ============================================================
* PUBLIC FUNCTIONS
* ============================================================ */
int publicFunction(int n) {
return helper(n) + 1;
}
/* ============================================================
* MAIN FUNCTION
* ============================================================ */
int main() {
// ...
}
🔄 TODO and FIXME Comments
Mark work in progress:
// TODO: Add error handling for null pointer
void processData(int *data) {
// ...
}
// FIXME: This causes memory leak when buffer is full
char* readFile(const char* filename) {
// ...
}
// HACK: Temporary workaround for bug #123
// Remove after library update
data[0] = data[0] & 0xFF;
// NOTE: This assumes little-endian architecture
int value = *(int*)buffer;
// XXX: Potential security vulnerability - review
strcpy(dest, src);
Common Markers:
| Marker | Purpose |
|---|---|
TODO | Feature to add |
FIXME | Bug to fix |
HACK | Temporary workaround |
NOTE | Important information |
XXX | Needs attention |
BUG | Known bug |
OPTIMIZE | Optimization opportunity |
📊 Documenting Data Structures
/**
* @struct Student
* @brief Represents a student record in the system.
*
* Contains personal information and academic data
* for a single student enrolled in the institution.
*/
typedef struct {
char name[50]; /**< Full legal name of student */
int id; /**< Unique 6-digit student ID */
float gpa; /**< Current GPA (0.0 to 4.0) */
int credits; /**< Total credit hours completed */
int isActive; /**< 1 if currently enrolled, 0 otherwise */
} Student;
/**
* @enum ErrorCode
* @brief Return codes for library functions.
*/
typedef enum {
SUCCESS = 0, /**< Operation completed successfully */
ERROR_NULL_POINTER, /**< NULL pointer passed as argument */
ERROR_OUT_OF_MEMORY, /**< Memory allocation failed */
ERROR_INVALID_INPUT, /**< Input validation failed */
ERROR_FILE_NOT_FOUND /**< Specified file does not exist */
} ErrorCode;
/**
* @def MAX_STUDENTS
* @brief Maximum number of students the system can handle.
*
* This limit is based on available memory and database
* constraints. Increase with caution.
*/
#define MAX_STUDENTS 1000
⚙️ Conditional Compilation Comments
#ifdef DEBUG
// This code only runs in debug builds
printf("Debug: x = %d\n", x);
#endif
#if 0
// This code is "commented out" using preprocessor
// Useful for large blocks of code
printf("This will never run\n");
int unused = 42;
#endif
/* Commented out - keeping for reference
void oldFunction() {
// Old implementation
}
*/
📏 Comment Style Guidelines
Do's:
- •
Explain WHY, not WHAT
// Bad: Increment counter // Good: Increment counter to skip the header row counter++; - •
Keep comments updated with code
- •
Comment complex algorithms
// Using Euclidean algorithm to find GCD: // gcd(a, b) = gcd(b, a % b) until b = 0 while (b != 0) { int temp = b; b = a % b; a = temp; } - •
Document function contracts
- •
Use consistent style throughout project
Don'ts:
- •
Don't state the obvious
// Bad i++; // Add 1 to i - •
Don't leave commented-out code (use version control)
- •
Don't write misleading comments
- •
Don't over-comment
- •
Don't use comments to excuse bad code
// Bad int a; // This is the number of apples // Good int numberOfApples; // Self-documenting
🛠️ Documentation Tools
Doxygen:
Generate documentation from comments:
/**
* @mainpage My Project Documentation
*
* @section intro Introduction
* This is my awesome C project...
*
* @section install Installation
* Follow these steps...
*/
Run: doxygen Doxyfile
Example Doxyfile Configuration:
PROJECT_NAME = "My C Project"
OUTPUT_DIRECTORY = ./docs
INPUT = ./src
RECURSIVE = YES
GENERATE_HTML = YES
GENERATE_LATEX = NO
✅ Best Practices Summary
- •Header comments for every file
- •Function documentation for all public functions
- •Inline comments for complex or non-obvious code
- •Use consistent style throughout the project
- •Keep comments updated when code changes
- •Prefer self-documenting code with clear names
- •Document assumptions and constraints
- •Use TODO/FIXME markers for pending work
- •Don't over-comment obvious code
- •Review comments during code review
🔑 Key Takeaways
- •Single-line
//comments for brief notes (C99+) - •Multi-line
/* */comments for longer explanations - •Document WHY, not just WHAT
- •Use documentation tags (
@param,@return, etc.) - •Keep comments synchronized with code
- •Self-documenting code reduces need for comments
- •Use section dividers in larger files
- •Consider using documentation generators like Doxygen
⏭️ Next Module
Continue to Module 3: Control Structures to learn about decision making and loops.