Skip to main content

Command Palette

Search for a command to run...

Structure of a C program

Updated
9 min read
J

I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class.

At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out.

In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.

Welcome to one of the most fundamental concepts in C programming! Before you start writing complex programs, it's essential to understand how a C program is organized. Think of the structure of a C program like the blueprint of a house — every part has a specific purpose and place.

C, created by Dennis Ritchie at Bell Labs in the early 1970s, has a clean and logical structure that has influenced countless programming languages. Once you understand this structure, writing C programs becomes much more intuitive.

A Simple C Program

Let's start with the classic "Hello, World!" program and understand each part:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

Even this simple program contains all the essential structural elements. Let's explore each one in detail.


The Six Main Components of a C Program

A complete C program can have up to six major sections. Not all sections are required in every program, but understanding each one is crucial.

1. Documentation Section (Comments)

The documentation section contains comments that describe the program. Comments are ignored by the compiler but are invaluable for humans reading your code.

/*
 * Program Name: Temperature Converter
 * Author: Your Name
 * Date: December 2024
 * Description: This program converts temperature from 
 *              Celsius to Fahrenheit and vice versa.
 */

Why is this important?

  • Helps others (and your future self) understand what the program does

  • Documents the author, date, and version information

  • Explains complex logic or algorithms

Two types of comments in C:

TypeSyntaxUse Case
Single-line// commentBrief explanations
Multi-line/* comment */Longer descriptions, headers
// This is a single-line comment

/* This is a
   multi-line comment
   spanning several lines */

Preprocessor directives are instructions to the C preprocessor, which processes your code before compilation. They always begin with a # symbol.

#include <stdio.h>    // Standard Input/Output functions
#include <stdlib.h>   // Standard Library functions
#include <string.h>   // String handling functions
#include <math.h>     // Mathematical functions

#define PI 3.14159    // Constant definition
#define MAX_SIZE 100  // Maximum array size

Understanding #include:

The #include directive tells the compiler to include the contents of another file. Think of it as copying and pasting the contents of that file into your program.

  • <filename> — Searches in standard system directories (for standard library headers)

  • "filename" — Searches in the current directory first, then system directories (for your own header files)

#include <stdio.h>      // System header file
#include "myheader.h"   // Your custom header file

Understanding #define:

The #define directive creates symbolic constants or macros. The preprocessor replaces every occurrence of the identifier with its defined value.

#define GRAVITY 9.8
#define SQUARE(x) ((x) * (x))

// Usage:
float force = mass * GRAVITY;      // GRAVITY becomes 9.8
int result = SQUARE(5);            // Becomes ((5) * (5)) = 25

Common Header Files You Should Know:

Header FilePurposeCommon Functions
stdio.hInput/Output operationsprintf(), scanf(), fopen()
stdlib.hGeneral utilitiesmalloc(), free(), exit()
string.hString manipulationstrlen(), strcpy(), strcmp()
math.hMathematical functionssqrt(), pow(), sin()
ctype.hCharacter handlingisalpha(), toupper()
time.hDate and timetime(), clock()

3. Global Declaration Section

This section is used to declare global variables and function prototypes that can be accessed from anywhere in the program.

#include <stdio.h>

// Global variables
int globalCounter = 0;
float taxRate = 0.18;
char programName[] = "My Application";

// Function prototypes (declarations)
void displayMenu();
int calculateSum(int a, int b);
float calculateArea(float radius);

int main() {
    // main function code
    return 0;
}

Global Variables:

  • Declared outside all functions

  • Accessible from any function in the program

  • Exist for the entire duration of the program

  • Should be used sparingly (prefer local variables when possible)

Function Prototypes:

A function prototype tells the compiler about a function's name, return type, and parameters before the actual function definition appears. This is also called a function declaration.

// Function prototype (declaration)
int add(int x, int y);

int main() {
    int result = add(5, 3);  // Compiler knows about add() from prototype
    printf("Sum: %d\n", result);
    return 0;
}

// Function definition (comes after main)
int add(int x, int y) {
    return x + y;
}

Why use function prototypes?

  • Allows you to call functions before defining them

  • Helps the compiler catch errors (wrong number or type of arguments)

  • Makes your code more organized (main function can appear first)


4. The main() Function

The main() function is the heart of every C program. It's where program execution begins and ends.

int main() {
    // Your code goes here
    return 0;
}

Anatomy of main():

ComponentMeaning
intReturn type (main returns an integer to the operating system)
mainFunction name (must be exactly this)
()Parameter list (can be empty or contain command-line arguments)
{ }Function body (contains all executable statements)
return 0;Returns 0 to indicate successful execution

Two valid forms of main():

// Form 1: No command-line arguments
int main() {
    return 0;
}

// Form 2: With command-line arguments
int main(int argc, char *argv[]) {
    // argc = argument count
    // argv = argument vector (array of strings)
    return 0;
}

Understanding the return value:

  • return 0; — Program executed successfully

  • return 1; (or any non-zero) — Program encountered an error

The operating system uses this return value. For example, in shell scripting, you can check if a program succeeded or failed.


5. User-Defined Functions

Beyond main(), you can create your own functions to organize code into reusable, logical blocks.

#include <stdio.h>

// Function to calculate the area of a rectangle
float calculateRectangleArea(float length, float width) {
    float area = length * width;
    return area;
}

// Function to display a greeting
void greetUser(char name[]) {
    printf("Hello, %s! Welcome to the program.\n", name);
}

// Function to check if a number is even
int isEven(int number) {
    if (number % 2 == 0) {
        return 1;  // True
    } else {
        return 0;  // False
    }
}

int main() {
    greetUser("Student");

    float area = calculateRectangleArea(5.0, 3.0);
    printf("Rectangle area: %.2f\n", area);

    if (isEven(10)) {
        printf("10 is even\n");
    }

    return 0;
}

Parts of a function:

return_type function_name(parameter_list) {
    // Local variable declarations
    // Executable statements
    return value;  // If return_type is not void
}

Common return types:

  • int — Returns an integer

  • float — Returns a floating-point number

  • double — Returns a double-precision floating-point number

  • char — Returns a single character

  • void — Returns nothing


6. Local Declarations and Statements

Within any function (including main()), you have local declarations and executable statements.

int main() {
    // Local variable declarations
    int age;
    float salary;
    char grade;
    int numbers[5];

    // Executable statements
    age = 20;
    salary = 50000.50;
    grade = 'A';

    printf("Age: %d\n", age);
    printf("Salary: %.2f\n", salary);
    printf("Grade: %c\n", grade);

    return 0;
}

Important rules:

  • In older C standards (C89/C90), all variable declarations must appear at the beginning of a block, before any executable statements

  • In modern C (C99 and later), you can declare variables anywhere in the block

  • Local variables only exist within the function or block where they're declared


Complete Program Example

Let's put everything together in a complete, well-structured program:

/*
 * Program: Simple Calculator
 * Author: Jyotiprakash
 * Date: December 2024
 * Description: A basic calculator that performs 
 *              addition, subtraction, multiplication, and division.
 */

// Preprocessor Directives
#include <stdio.h>
#include <stdlib.h>

#define PROGRAM_VERSION "1.0"

// Global Declarations
const char* programName = "Simple Calculator";

// Function Prototypes
void displayWelcome();
void displayMenu();
float add(float a, float b);
float subtract(float a, float b);
float multiply(float a, float b);
float divide(float a, float b);

// Main Function
int main() {
    // Local declarations
    int choice;
    float num1, num2, result;

    // Display welcome message
    displayWelcome();

    // Main program loop
    while (1) {
        displayMenu();

        printf("Enter your choice (1-5): ");
        scanf("%d", &choice);

        if (choice == 5) {
            printf("Thank you for using %s!\n", programName);
            break;
        }

        if (choice < 1 || choice > 5) {
            printf("Invalid choice. Please try again.\n\n");
            continue;
        }

        printf("Enter first number: ");
        scanf("%f", &num1);
        printf("Enter second number: ");
        scanf("%f", &num2);

        switch (choice) {
            case 1:
                result = add(num1, num2);
                printf("Result: %.2f + %.2f = %.2f\n\n", num1, num2, result);
                break;
            case 2:
                result = subtract(num1, num2);
                printf("Result: %.2f - %.2f = %.2f\n\n", num1, num2, result);
                break;
            case 3:
                result = multiply(num1, num2);
                printf("Result: %.2f × %.2f = %.2f\n\n", num1, num2, result);
                break;
            case 4:
                if (num2 == 0) {
                    printf("Error: Division by zero is not allowed!\n\n");
                } else {
                    result = divide(num1, num2);
                    printf("Result: %.2f ÷ %.2f = %.2f\n\n", num1, num2, result);
                }
                break;
        }
    }

    return 0;
}

// User-Defined Functions

void displayWelcome() {
    printf("================================\n");
    printf("   %s v%s\n", programName, PROGRAM_VERSION);
    printf("================================\n\n");
}

void displayMenu() {
    printf("--- Menu ---\n");
    printf("1. Addition\n");
    printf("2. Subtraction\n");
    printf("3. Multiplication\n");
    printf("4. Division\n");
    printf("5. Exit\n");
}

float add(float a, float b) {
    return a + b;
}

float subtract(float a, float b) {
    return a - b;
}

float multiply(float a, float b) {
    return a * b;
}

float divide(float a, float b) {
    return a / b;
}

Structure at a Glance

┌─────────────────────────────────────────┐
│     1. DOCUMENTATION SECTION            │
│     (Comments describing the program)   │
├─────────────────────────────────────────┤
│     2. PREPROCESSOR DIRECTIVES          │
│     (#include, #define)                 │
├─────────────────────────────────────────┤
│     3. GLOBAL DECLARATIONS              │
│     (Global variables, prototypes)      │
├─────────────────────────────────────────┤
│     4. main() FUNCTION                  │
│     ┌─────────────────────────────┐     │
│     │ Local declarations          │     │
│     │ Executable statements       │     │
│     │ return 0;                   │     │
│     └─────────────────────────────┘     │
├─────────────────────────────────────────┤
│     5. USER-DEFINED FUNCTIONS           │
│     (Your custom functions)             │
└─────────────────────────────────────────┘

Key Points

  1. Every C program must have a main() function — This is where execution begins.

  2. Preprocessor directives come first#include and #define are processed before compilation.

  3. Comments are your friends — Document your code generously. Your future self will thank you.

  4. Function prototypes enable flexibility — Declare functions before main(), define them after.

  5. Local vs. Global scope matters — Prefer local variables; use global sparingly.

  6. Consistent structure improves readability — Follow a standard organization for all your programs.

  7. The semicolon is mandatory — Every statement in C ends with a semicolon (except preprocessor directives and function definitions).


Practice Exercise

Try writing a program that follows the complete structure we discussed. Here's a challenge:

Create a program that:

  • Has proper documentation comments

  • Includes necessary header files

  • Defines a constant for PI using #define

  • Declares function prototypes

  • Contains a main() function that calculates the area and circumference of a circle

  • Uses separate functions for calculateArea() and calculateCircumference()

C Programming

Part 1 of 50

More from this blog

Jyotiprakash's Blog

251 posts

I'm Jyotiprakash, a software dev and professor at KIIT, with expertise in system programming.