Introduction to C
From Java to C — your first program, gcc, and the four-stage compilation pipeline
Quick check before you start: Can you explain the difference between
javacandgcc? If not, read on. If you can describe the four stages of C compilation, skip to Program Structure.Practice this topic: C Basics skill drill
After this lesson, you will be able to:
- Write, compile, and run a minimal C program
- Explain the four stages of gcc compilation (preprocess, compile, assemble, link)
- Use
gcc -Wall -oto compile with warnings enabled - Identify the role of
#include,main,return, and function prototypes
From Java to C
In CSCD 210, your workflow was:
Hello.java → javac → Hello.class → JVM → CPU
The JVM translated bytecode to machine instructions at runtime. In C, there is no JVM:
hello.c → gcc → hello (executable) → CPU
gcc compiles your source code directly into a native binary that the CPU executes. No interpreter, no virtual machine, no garbage collector. This is why C is fast — and why mistakes are less forgiving.
Your First C Program
Create a file called hello.c:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
Compile and run:
gcc -Wall -o hello hello.c
./hello
# Hello, world!
Breaking down the gcc command:
| Part | Meaning |
|---|---|
gcc |
The GNU C Compiler |
-Wall |
Enable all common warnings — always use this |
-o hello |
Name the output file hello |
hello.c |
The source file |
Why ./hello instead of just hello? The current directory (.) is not in your PATH by default. The ./ tells the shell to look in the current directory.
The Four-Stage Pipeline
gcc does not go straight from source to binary. It runs four stages:
hello.c → Preprocessor → Compiler → Assembler → Linker → hello
(.c → .i) (.i → .s) (.s → .o) (.o → executable)
1. Preprocessing (gcc -E)
The preprocessor handles directives that start with #:
#include <stdio.h>— pastes the contents ofstdio.hinto your file#define PI 3.14— replaces everyPIwith3.14
This is text substitution. No compilation happens yet.
2. Compilation (gcc -S)
The compiler translates C code into assembly language — human-readable instructions for the CPU.
3. Assembly (gcc -c)
The assembler converts assembly into machine code, producing an object file (.o). This is binary, but not yet a complete program.
4. Linking
The linker combines your .o file with library code (like printf from the C standard library) to produce the final executable.
You can see each stage:
gcc -E hello.c -o hello.i # preprocessed output
gcc -S hello.c -o hello.s # assembly code
gcc -c hello.c -o hello.o # object file
gcc hello.o -o hello # link into executable
In practice, gcc -Wall -o hello hello.c runs all four stages automatically.
Program Structure
Every C program you write this quarter follows this pattern:
/* 1. Preprocessor directives */
#include <stdio.h>
/* 2. Function prototypes */
int add(int a, int b);
/* 3. Main function */
int main(void)
{
int result = add(3, 4);
printf("Sum: %d\n", result);
return 0;
}
/* 4. Function definitions */
int add(int a, int b)
{
return a + b;
}
Key differences from Java
| Java | C |
|---|---|
System.out.println() |
printf() |
public static void main(String[] args) |
int main(void) |
| Automatic garbage collection | Manual memory management |
| Classes, objects, inheritance | Functions, structs, pointers |
import java.util.* |
#include <stdio.h> |
Why prototypes?
C reads top to bottom in a single pass. If main calls add but add is defined below main, the compiler has not seen add yet. A prototype declares the function signature before main so the compiler knows what to expect:
int add(int a, int b); /* prototype — no body, just the signature */
Without a prototype, gcc -Wall produces a warning about an implicit function declaration. Always declare before you use.
return 0
main returns an int — the program’s exit status. return 0; means success, matching the Unix convention you learned in the processes lesson. A non-zero return signals an error.
-Wall flag tell gcc to do?-Wall stands for "Warn all" — it enables a broad set of compiler warnings that catch common mistakes like unused variables, missing return values, and implicit function declarations. It does not generate errors (your code still compiles), but you should treat warnings as bugs and fix them. Always compile with -Wall.
What Comes Next
You compiled and ran your first C program. Next, you will learn about C variables, data types, and printf/scanf for input and output.