Skip to content

0. C Naming Conventions

Naming conventions in C programming are critical for writing readable, maintainable, and reliable code. By following a consistent naming strategy, you enhance the clarity of your code, which is especially important when working in teams or on large-scale projects. This article outlines the widely accepted naming conventions in C, focusing on variables, functions, constants, structs, macros, and more.

1. General Guidelines for Naming

1.1 Case Sensitivity

C is case-sensitive, meaning Variable and variable are treated as different identifiers. Care should be taken to follow consistent case usage.

1.2 Allowed Characters

  • Identifiers can include letters (a-z, A-Z), digits (0-9), and underscores (_).
  • An identifier cannot begin with a digit.
  • Avoid using special characters like @, #, $, %, etc.

1.3 Descriptive Names

Names should be descriptive, indicating the purpose or use of the variable or function. Avoid overly generic names like x or data, unless in very limited, appropriate contexts (e.g., loop counters).

2. Variables

2.1 Lowercase with Underscores (snake_case)

  • Variable names should be in lowercase, with words separated by underscores if the name consists of multiple words.

    Examples:

    int total_count;
    float item_price;
    char customer_name[100];

2.2 Avoid Single-character Names

Single-character variable names like i, j, or n should be used only in simple, localized contexts (e.g., loop indices).

2.3 Avoid Reserved Keywords

Ensure that variable names do not conflict with C’s reserved keywords like int, float, return, etc.

3. Constants

Uppercase with Underscores (UPPER_CASE)

  • Constants should be written in all uppercase letters, with words separated by underscores. This convention differentiates constants from regular variables.

    Examples:

    #define MAX_BUFFER_SIZE 1024
    const int DAYS_IN_WEEK = 7;
  • For #define macros, it is common to use UPPER_CASE to avoid naming conflicts.

4. Functions

4.1 Lowercase with Underscores** (snake_case)

  • Function names should be in lowercase, with words separated by underscores. This naming scheme ensures consistency and readability.

    Examples:

    int calculate_total_price(int quantity, float price) {
    return quantity * price;
    }
    void print_customer_details(char* name, int id) {
    // Function body
    }

4.2 Verb-Noun Format

  • It’s a good practice to use verb-noun naming for functions, as it makes the function’s action and object more apparent.

    Examples:

    void update_record();
    int calculate_sum(int a, int b);

4.3 Avoid Abbreviations

  • Avoid ambiguous or non-standard abbreviations to maintain clarity. For example, prefer calculate_average over calc_avg.

5. Structs, Unions, and Enums

5.1 CapWords or PascalCase (CapWords)

  • Structs, unions, and enums are typically named using PascalCase (CapWords), where each word starts with an uppercase letter and no underscores are used between words.

    Examples:

    struct CustomerInfo {
    char name[100];
    int age;
    };
    union DataPacket {
    int id;
    float value;
    };
    enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST
    };

5.2 Member Naming for Structs and Unions

  • Member names within structs or unions should follow the same rules as variable names: lowercase with underscores.

    Example:

    struct CustomerInfo {
    char first_name[50];
    char last_name[50];
    int age;
    };

6. Macros

6.1 Uppercase with Underscores (UPPER_CASE)

  • Macros, especially those defined using #define, should be written in uppercase to distinguish them from normal variables and functions. Use underscores to separate words.

    Examples:

    #define MAX_ARRAY_SIZE 100
    #define SQUARE(x) ((x) * (x))

6.2 Avoid Macros that Look Like Functions

  • To avoid confusion, ensure macros are named clearly to indicate their purpose. Avoid naming them like functions (e.g., avoid square(x) as a macro).

6.3 Use Parentheses in Macros

  • When using macros that involve expressions, always enclose parameters in parentheses to avoid unexpected behavior.

    Example:

    #define SQUARE(x) ((x) * (x)) // Correct

7. Global Variables

7.1 Lowercase with Underscores, Possibly with a Prefix (g_)

  • Global variables should be used sparingly. When necessary, prefix them with g_ to indicate their scope.

    Examples:

    int g_total_count;
    float g_item_price;

7.2 Avoid Excessive Global Variables

  • Global variables should be minimized as they make the code harder to understand and maintain. Prefer passing variables as arguments to functions whenever possible.

8. Local Variables

8.1 Lowercase with Underscores (snake_case)

  • Like regular variables, local variables should follow the snake_case convention.

    Example:

    void calculate_total_price(int quantity, float price) {
    int total_price = quantity * price;
    // Function body
    }

8.2 Short, Contextual Names for Loop Counters

  • For loop counters and small, local scope variables, using single-character names like i, j, or k is acceptable.

    Example:

    for (int i = 0; i < 10; i++) {
    // Loop body
    }

9. Enumerations

9.1 CapWords (CapWords)

  • Enum types should follow the CapWords convention, while enum constants are generally written in uppercase with underscores.

    Examples:

    enum Status {
    STATUS_OK,
    STATUS_ERROR,
    STATUS_PENDING
    };

9.2 Use Descriptive Names for Enum Values

  • Enum constants should be self-descriptive and prefixed with the enum type name (or an abbreviation) to prevent naming conflicts.

    Example:

    enum Color {
    COLOR_RED,
    COLOR_GREEN,
    COLOR_BLUE
    };

10. Pointer Variables

Use ptr_ Prefix (optional)

  • To improve clarity, it’s common to use the ptr_ prefix to denote pointer variables. This is not a strict convention but is often used to make the code clearer.

    Examples:

    int *ptr_total_count;
    char *ptr_name;

11. Boolean Variables

Prefix with is_, has_, or can_

  • Boolean variables (or variables representing a true/false condition) should be prefixed with is_, has_, or can_ to indicate a binary state.

    Examples:

    int is_valid = 1; // 1 for true, 0 for false
    int has_error = 0;

12. File Naming

12.1 Lowercase with Underscores (snake_case)

  • Source and header files should be named in lowercase with words separated by underscores.

    Examples:

    • data_processor.c
    • customer_manager.h

12.2 Header File Guards

  • Use header guards to prevent multiple inclusions of a file.

    Example:

    #ifndef CUSTOMER_MANAGER_H
    #define CUSTOMER_MANAGER_H
    // Declarations
    #endif // CUSTOMER_MANAGER_H