All C Language Keywords Explained with Examples
Read on to explore all c language keywords explained with examples — a beginner-friendly walkthrough by Codekilla.
Keywords are reserved words in C that have special meanings to the compiler. You can't use them as variable names, function names, or any other identifiers. Think of them as the fundamental building blocks of the C language—they're the vocabulary the compiler understands directly. C has exactly 32 keywords, and each one serves a specific purpose in controlling program flow, defining data types, or managing memory. When you write int x = 5;, that int isn't just a random word—it's a keyword telling the compiler you're creating an integer variable.
Understanding keywords is your first real step into C programming. While libraries and functions can be created, modified, or ignored, keywords are non-negotiable. They're baked into the language specification itself, which means every C compiler on every platform recognizes them the same way.
- Foundation of syntax: Every C program you write relies on keywords—you literally cannot write valid C code without them
- Compiler communication: Keywords are how you tell the compiler what type of data you're working with and what operations to perform
- Portability guarantee: Because keywords are standardized, your code behaves consistently across different systems and compilers
- Memory management control: Keywords like
static,extern, andregistergive you precise control over where and how data is stored - Career requirement: Job interviews for C/embedded positions almost always test your understanding of storage classes and type qualifiers
C provides keywords that define what kind of data you're working with. These determine how much memory gets allocated and what operations are valid.
The basic types are int, char, float, and double. The void keyword indicates "no type" and is used for functions that don't return values or pointers that can point to any type.
| Keyword | Purpose | Typical Size |
|---|---|---|
char | Single character or small integer | 1 byte |
int | Integer numbers | 4 bytes |
float | Single-precision decimal | 4 bytes |
double | Double-precision decimal | 8 bytes |
void | No type/generic pointer | N/A |
cchar grade = 'A'; int age = 25; float price = 19.99; double pi = 3.14159265359; void *generic_ptr; // Can point to any data type printf("Grade: %c, Age: %d\n", grade, age); printf("Price: %.2f, Pi: %.10f\n", price, pi);
Modifiers change the behavior of basic data types. The short and long keywords adjust size, while signed and unsigned control whether numbers can be negative.
cshort int small_num = 100; // Usually 2 bytes long int big_num = 1000000L; // Usually 4-8 bytes unsigned int always_positive = 50; // Can't be negative, doubles positive range signed char temperature = -15; // Can be negative (default for char varies) printf("Unsigned range for int: 0 to %u\n", UINT_MAX); printf("Signed range for int: %d to %d\n", INT_MIN, INT_MAX);
These keywords control the lifetime and visibility of variables. Understanding auto, static, extern, and register separates beginners from intermediate programmers.
| Keyword | Scope | Lifetime | Storage Location |
|---|---|---|---|
auto | Block | Function execution | Stack (default) |
static | Block/File | Entire program | Data segment |
extern | Global | Entire program | Data segment |
register | Block | Function execution | CPU register (hint) |
cvoid counter() { static int count = 0; // Retains value between function calls count++; printf("Called %d times\n", count); } int main() { counter(); // Prints: Called 1 times counter(); // Prints: Called 2 times counter(); // Prints: Called 3 times register int i; // Hint to compiler for fast access for (i = 0; i < 1000000; i++) { // Fast loop iteration } return 0; }
These keywords determine the order in which code executes. They're the decision-makers and loop creators.
The if, else, and switch keywords handle conditional execution. The for, while, and do keywords create loops. You control these loops with break (exit immediately) and continue (skip to next iteration).
cint score = 85; // Conditional execution if (score >= 90) { printf("Grade: A\n"); } else if (score >= 80) { printf("Grade: B\n"); } else { printf("Grade: C or lower\n"); } // Switch for multiple specific values switch (score / 10) { case 10: case 9: printf("Excellent!\n"); break; case 8: printf("Very good!\n"); break; default: printf("Keep trying!\n"); break; } // Loop with break and continue for (int i = 0; i < 10; i++) { if (i == 3) continue; // Skip 3 if (i == 7) break; // Stop at 7 printf("%d ", i); // Prints: 0 1 2 4 5 6 }
The goto, return, and continue keywords transfer control to different parts of your program. While goto is controversial, return is essential for functions.
cint divide(int a, int b) { if (b == 0) { printf("Error: Division by zero\n"); return -1; // Exit function early with error code } return a / b; } // goto example (use sparingly!) int main() { int error_code = divide(10, 0); if (error_code == -1) { goto cleanup; } printf("Result: %d\n", error_code); cleanup: printf("Program ending\n"); return 0; }
The const and volatile keywords modify how variables can be used. The const keyword prevents modification, while volatile tells the compiler a value might change unexpectedly (important for embedded systems).
cconst double GRAVITY = 9.81; // Cannot be changed // GRAVITY = 10; // Compiler error! const char *message = "Hello"; // Pointer to constant data // message[0] = 'h'; // Error: can't modify the string char * const ptr = &message; // Constant pointer // ptr = NULL; // Error: can't change where ptr points volatile int sensor_value; // Hardware might change this while (sensor_value < 100) { // Compiler won't optimize this away }
The struct, union, enum, and typedef keywords let you create custom data types.
c// Structure: members get their own memory struct Student { char name[50]; int id; float gpa; }; // Union: members share the same memory union Data { int i; float f; char str[20]; }; // Enumeration: named integer constants enum Color { RED, GREEN, BLUE }; // RED=0, GREEN=1, BLUE=2 // typedef creates type aliases typedef struct Student Student; typedef unsigned long ulong; Student alice = {"Alice", 12345, 3.8}; enum Color favorite = BLUE; ulong big_number = 1000000UL; printf("Student: %s, ID: %d, GPA: %.2f\n", alice.name, alice.id, alice.gpa);
While sizeof looks like a function, it's actually a keyword and compile-time operator that returns the size in bytes.
cprintf("Size of int: %zu bytes\n", sizeof(int)); printf("Size of double: %zu bytes\n", sizeof(double)); int arr[10]; printf("Array size: %zu bytes\n", sizeof(arr)); // 40 bytes (10 * 4) printf("Array length: %zu elements\n", sizeof(arr) / sizeof(arr[0])); struct Point { int x; int y; }; printf("Struct Point size: %zu bytes\n", sizeof(struct Point));
| Need | Reach for |
|---|---|
| Store whole numbers | int, long, short |
| Store decimals | float, double |
| Store single character | char |
| Make decision | if, else, switch |
| Create loop | for, while, do |
| Exit function | return |
| Prevent modification | const |
| Variable persists between calls | static |
| Share variable across files | extern |
| Create custom type | struct, typedef |
| Group alternatives | union, enum |
-
Forgetting break in switch statements — Without
break, execution falls through to the next case. This is rarely what you want and creates hard-to-find bugs. -
Using goto excessively — While
gotohas legitimate uses (error handling, breaking out of nested loops), overusing it creates "spaghetti code" that's impossible to follow. -
Confusing const pointer positions —
const int *ptrmeans the data is constant, butint * const ptrmeans the pointer is constant. Get this wrong and you'll fight the compiler. -
Assuming register actually uses registers — Modern compilers ignore the
registerkeyword. It's a hint, not a command, and optimizers are smarter than manual suggestions. -
Modifying const through pointers — Casting away
constand modifying the data invokes undefined behavior. Just because it compiles doesn't mean it's safe. -
Treating sizeof as a function — Writing
sizeof arrworks, butsizeof(arr)is more consistent. Remember it evaluates at compile-time, so you can't use it dynamically with VLAs reliably across compilers.
💡 Think Like a Programmer: Keywords aren't just syntax rules to memorize—they're your interface to the machine. Master them, and you're speaking the compiler's native language fluently.
Keep Reading
C Preprocessor Directives Explained with Examples
Read on to explore c preprocessor directives explained with examples — a beginner-friendly walkthrough by Codekilla.
C stdio.h Functions List with Examples
Read on to explore c stdio.h functions list with examples — a beginner-friendly walkthrough by Codekilla.
All C Math Functions with Examples and Outputs
Read on to explore all c math functions with examples and outputs — a beginner-friendly walkthrough by Codekilla.
