Learn C programming step-by-step with examples.
C is a general-purpose, procedural programming language developed by Dennis Ritchie in 1972 at Bell Labs to build the UNIX operating system. It’s known for its efficiency, low-level memory access, and clean syntax, making it ideal for system programming, embedded systems, and high-performance applications like operating systems, compilers, and game engines.
Copy#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; } // Output: Hello, World!
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; } // Output: Hello, World!
If you want to run C program download DEV-C sofware or if you want to run on vs code editor then download minGw compailer and set it up in your vs code editor.
Download link for DEV C : DEV C++.
download link for minGw and vs code editor : minGw and Vs Code.
The C programming language uses a defined character set to represent source code and data. A character set is the collection of valid characters that C programs can use in identifiers, strings, and character constants. C’s character set is primarily based on the ASCII standard, which has been consistent since C’s creation in 1972 for UNIX development, ensuring portability across systems.
Components of the C Character Set:
+
-
*
/
%
&
|
!
\n
\t
\'
\"
Note: C uses the char data type to store characters, typically as 1-byte ASCII values (0 to 127 for signed, 0 to 255 for unsigned). Since the C99 standard, C also supports extended character sets like Unicode via wide characters (wchar_t).
char
wchar_t
Copy#include <stdio.h> int main() { char letter = 'A'; char digit = '5'; char symbol = '#'; char newline = '\n'; printf("Letter: %c\n", letter); printf("Digit: %c\n", digit); printf("Symbol: %c\n", symbol); printf("Escape Sequence (newline): %cHello after newline\n", newline); printf("ASCII value of 'A': %d\n", letter); return 0; }
#include <stdio.h> int main() { char letter = 'A'; char digit = '5'; char symbol = '#'; char newline = '\n'; printf("Letter: %c\n", letter); printf("Digit: %c\n", digit); printf("Symbol: %c\n", symbol); printf("Escape Sequence (newline): %cHello after newline\n", newline); printf("ASCII value of 'A': %d\n", letter); return 0; }
Output:
Letter: A Digit: 5 Symbol: # Escape Sequence (newline): Hello after newline ASCII value of 'A': 65
In C, a variable is a named storage location in memory used to hold data that can be modified during program execution. Variables must be declared with a specific data type before use, reflecting C’s structured and type-safe design, established in 1972 by Dennis Ritchie for UNIX development. Variables are fundamental to manipulating data, such as numbers, characters, or user input.
Key Rules for Variables:
int age;
int age = 20;
Age
age
auto
register
static
extern
Note: C’s variable declaration syntax, formalized in the C89 standard, ensures type safety and efficient memory use. Variable sizes depend on data types (e.g., int is typically 4 bytes on 64-bit systems).
int
Copy#include <stdio.h> int global_var = 100; // Global variable int main() { int age = 20; // Local variable float salary = 2500.50; char grade = 'B'; static int counter = 0; // Static variable retains value between calls counter++; printf("Global variable: %d\n", global_var); printf("Local variable (age): %d\n", age); printf("Local variable (salary): %.2f\n", salary); printf("Local variable (grade): %c\n", grade); printf("Static variable (counter): %d\n", counter); return 0; }
#include <stdio.h> int global_var = 100; // Global variable int main() { int age = 20; // Local variable float salary = 2500.50; char grade = 'B'; static int counter = 0; // Static variable retains value between calls counter++; printf("Global variable: %d\n", global_var); printf("Local variable (age): %d\n", age); printf("Local variable (salary): %.2f\n", salary); printf("Local variable (grade): %c\n", grade); printf("Static variable (counter): %d\n", counter); return 0; }
Global variable: 100 Local variable (age): 20 Local variable (salary): 2500.50 Local variable (grade): B Static variable (counter): 1
C provides a set of basic data types for storing different kinds of values. These types are fundamental to C’s efficiency and low-level control, designed to work closely with hardware. Below are the core data types, their typical sizes (on a 64-bit system), and their uses:
Modifiers: Use signed, unsigned, short, or long to adjust range or size (e.g., unsigned int, long long int). Note that sizes may vary by platform (e.g., 32-bit vs. 64-bit systems), a consideration since C’s early days in the 1970s.
signed
unsigned
short
long
unsigned int
long long int
Copy#include <stdio.h> int main() { int age = 20; float pi = 3.14; double large_pi = 3.14159265359; char grade = 'A'; _Bool is_valid = 1; printf("Integer (int): %d, Size: %zu bytes\n", age, sizeof(age)); printf("Float: %.2f, Size: %zu bytes\n", pi, sizeof(pi)); printf("Double: %.10f, Size: %zu bytes\n", large_pi, sizeof(large_pi)); printf("Character (char): %c, Size: %zu bytes\n", grade, sizeof(grade)); printf("Boolean (_Bool): %d, Size: %zu bytes\n", is_valid, sizeof(is_valid)); return 0; }
#include <stdio.h> int main() { int age = 20; float pi = 3.14; double large_pi = 3.14159265359; char grade = 'A'; _Bool is_valid = 1; printf("Integer (int): %d, Size: %zu bytes\n", age, sizeof(age)); printf("Float: %.2f, Size: %zu bytes\n", pi, sizeof(pi)); printf("Double: %.10f, Size: %zu bytes\n", large_pi, sizeof(large_pi)); printf("Character (char): %c, Size: %zu bytes\n", grade, sizeof(grade)); printf("Boolean (_Bool): %d, Size: %zu bytes\n", is_valid, sizeof(is_valid)); return 0; }
Output (on a 64-bit system):
Integer (int): 20, Size: 4 bytes Float: 3.14, Size: 4 bytes Double: 3.1415926536, Size: 8 bytes Character (char): A, Size: 1 byte Boolean (_Bool): 1, Size: 1 byte
In C, a constant is a value that cannot be modified during program execution. Constants are used to define fixed values, such as mathematical constants or configuration settings, ensuring code reliability and readability. Introduced in C’s design in 1972 by Dennis Ritchie for UNIX, constants leverage C’s type system to provide immutable data, formalized in the C89 standard.
Types of Constants:
42
3.14
'A'
"Hello"
const
const int MAX = 100;
#define PI 3.14
enum
enum { RED = 1, GREEN, BLUE };
Note: Constants enhance code clarity and prevent accidental changes. The const keyword, introduced in C89, ensures type safety, while #define is a legacy approach from C’s early days. Use const for type-checked constants in modern C (2025).
#define
Copy#include <stdio.h> #define PI 3.14159 // Preprocessor constant int main() { const int MAX_AGE = 150; // Const variable enum colors { RED = 1, GREEN, BLUE }; // Enumeration constants printf("Literal Integer: %d\n", 42); printf("Literal Float: %.2f\n", 2.718); printf("Literal Character: %c\n", 'X'); printf("Literal String: %s\n", "Hello, C!"); printf("Const Variable (MAX_AGE): %d\n", MAX_AGE); printf("Preprocessor Constant (PI): %.5f\n", PI); printf("Enum Constant (GREEN): %d\n", GREEN); // MAX_AGE = 200; // Error: cannot modify const // PI = 3.14; // Error: PI is a preprocessor constant return 0; }
#include <stdio.h> #define PI 3.14159 // Preprocessor constant int main() { const int MAX_AGE = 150; // Const variable enum colors { RED = 1, GREEN, BLUE }; // Enumeration constants printf("Literal Integer: %d\n", 42); printf("Literal Float: %.2f\n", 2.718); printf("Literal Character: %c\n", 'X'); printf("Literal String: %s\n", "Hello, C!"); printf("Const Variable (MAX_AGE): %d\n", MAX_AGE); printf("Preprocessor Constant (PI): %.5f\n", PI); printf("Enum Constant (GREEN): %d\n", GREEN); // MAX_AGE = 200; // Error: cannot modify const // PI = 3.14; // Error: PI is a preprocessor constant return 0; }
Literal Integer: 42 Literal Float: 2.72 Literal Character: X Literal String: Hello, C! Const Variable (MAX_AGE): 150 Preprocessor Constant (PI): 3.14159 Enum Constant (GREEN): 2
In C, operators are symbols that perform operations on variables and values, such as arithmetic calculations, comparisons, or logical operations. Operators are a core part of C’s syntax, designed in 1972 by Dennis Ritchie to enable efficient manipulation of data in UNIX system programming. They work with C’s data types and variables, providing flexibility and control.
Types of Operators:
==
!=
>
<
>=
<=
&&
||
^
~
<<
>>
=
+=
-=
*=
/=
sizeof
?:
Note: Operators follow a precedence order, with parentheses () used to override it. The C89 standard formalized operator behavior, ensuring portability across platforms, a key feature for C’s use in 2025.
()
Copy#include <stdio.h> int main() { int a = 10, b = 3; int sum = a + b; // Arithmetic int mod = a % b; // Arithmetic int is_equal = (a == b); // Relational int logical = (a > 0 && b > 0); // Logical int bitwise = a & b; // Bitwise a += 5; // Assignment printf("Arithmetic (+): %d\n", sum); printf("Arithmetic (%%): %d\n", mod); printf("Relational (==): %d\n", is_equal); printf("Logical (&&): %d\n", logical); printf("Bitwise (&): %d\n", bitwise); printf("Assignment (+=): %d\n", a); printf("Ternary (?:): %s\n", (a > b) ? "a is greater" : "b is greater"); return 0; }
#include <stdio.h> int main() { int a = 10, b = 3; int sum = a + b; // Arithmetic int mod = a % b; // Arithmetic int is_equal = (a == b); // Relational int logical = (a > 0 && b > 0); // Logical int bitwise = a & b; // Bitwise a += 5; // Assignment printf("Arithmetic (+): %d\n", sum); printf("Arithmetic (%%): %d\n", mod); printf("Relational (==): %d\n", is_equal); printf("Logical (&&): %d\n", logical); printf("Bitwise (&): %d\n", bitwise); printf("Assignment (+=): %d\n", a); printf("Ternary (?:): %s\n", (a > b) ? "a is greater" : "b is greater"); return 0; }
Arithmetic (+): 13 Arithmetic (%): 1 Relational (==): 0 Logical (&&): 1 Bitwise (&): 2 Assignment (+=): 15 Ternary (?:): a is greater
In C, the Boolean type, represented by _Bool, is used to store true or false values, primarily for logical operations and conditions. Introduced in the C99 standard, _Bool is a fundamental data type that holds 0 (false) or any non-zero value (true). Before C99, C used integers (0 for false, non-zero for true) for Boolean logic, reflecting its minimalist design from 1972 by Dennis Ritchie for UNIX.
_Bool
0
Key Points about Boolean:
1
<stdbool.h>
bool
true
false
Note: Before C99, programmers used int for Boolean logic, a common practice in early UNIX programming. In modern C (2025), use bool with <stdbool.h> for clarity and portability.
Copy#include <stdio.h> #include <stdbool.h> int main() { _Bool is_active = 1; // Native _Bool bool is_valid = true; // Using stdbool.h int value = 42; bool is_positive = value > 0; // Relational operator bool logical_and = (value > 0 && is_valid); // Logical operator printf("Native _Bool (is_active): %d\n", is_active); printf("bool (is_valid): %d\n", is_valid); printf("Relational (is_positive): %d\n", is_positive); printf("Logical AND (logical_and): %d\n", logical_and); printf("Size of _Bool: %zu bytes\n", sizeof(_Bool)); return 0; }
#include <stdio.h> #include <stdbool.h> int main() { _Bool is_active = 1; // Native _Bool bool is_valid = true; // Using stdbool.h int value = 42; bool is_positive = value > 0; // Relational operator bool logical_and = (value > 0 && is_valid); // Logical operator printf("Native _Bool (is_active): %d\n", is_active); printf("bool (is_valid): %d\n", is_valid); printf("Relational (is_positive): %d\n", is_positive); printf("Logical AND (logical_and): %d\n", logical_and); printf("Size of _Bool: %zu bytes\n", sizeof(_Bool)); return 0; }
Native _Bool (is_active): 1 bool (is_valid): 1 Relational (is_positive): 1 Logical AND (logical_and): 1 Size of _Bool: 1
C supports user input through standard library functions like scanf and getchar from <stdio.h>, allowing programs to read data from the user. Introduced in 1972, input functions were key for interactive UNIX programs.
scanf
getchar
<stdio.h>
Key Points:
scanf("%d", &x);
Note: C89 standardized input functions, but modern C requires careful handling to prevent security issues.
Copy#include <stdio.h> int main() { int age; char name[20]; printf("Enter your age: "); scanf("%d", &age); printf("Enter your name: "); scanf("%s", name); printf("Age: %d, Name: %s\n", age, name); return 0; }
#include <stdio.h> int main() { int age; char name[20]; printf("Enter your age: "); scanf("%d", &age); printf("Enter your name: "); scanf("%s", name); printf("Age: %d, Name: %s\n", age, name); return 0; }
Output (example input):
Enter your age: 25 Enter your name: Alice Age: 25, Name: Alice
In C, loops are control structures that allow repeated execution of a block of code, enabling efficient handling of repetitive tasks. Introduced in C’s 1972 design by Dennis Ritchie for UNIX, loops provide powerful mechanisms for iteration, supporting both definite (known number of iterations) and indefinite (condition-based) looping. C offers three main loop types: while, for, and do-while, along with control statements like switch, break, and continue to manage flow.
while
for
do-while
switch
break
continue
Note: The C89 standard formalized loop behavior, ensuring portability, while C99 enhanced features like loop variable declarations. Loops remain critical for efficient C programming in 2025.
Copy#include <stdio.h> int main() { int i = 1; while (i <= 3) { printf("Loop iteration %d\n", i); i++; } return 0; }
#include <stdio.h> int main() { int i = 1; while (i <= 3) { printf("Loop iteration %d\n", i); i++; } return 0; }
Loop iteration 1 Loop iteration 2 Loop iteration 3
The while loop in C repeatedly executes a block of code as long as a condition is true, ideal for indefinite iteration. Designed in 1972 for UNIX, it provides flexible looping with minimal syntax.
while (condition) { statements; }
while (1)
Note: The C89 standard ensured consistent loop behavior. Always ensure the condition can become false to avoid infinite loops.
Copy#include <stdio.h> int main() { int i = 1; while (i <= 5) { printf("%d ", i); i++; } return 0; }
#include <stdio.h> int main() { int i = 1; while (i <= 5) { printf("%d ", i); i++; } return 0; }
1 2 3 4 5
The for loop in C is used for definite iteration, executing a block of code a specific number of times. Introduced in 1972, it’s compact and widely used for counted loops in C programs.
for (init; condition; update) { statements; }
Note: Standardized in C89, the for loop is ideal for array iteration and precise control, common in modern C applications.
Copy#include <stdio.h> int main() { for (int i = 1; i <= 5; i++) { printf("%d ", i); } return 0; }
#include <stdio.h> int main() { for (int i = 1; i <= 5; i++) { printf("%d ", i); } return 0; }
The do-while loop in C executes a block of code at least once before checking a condition, repeating as long as the condition is true. Introduced in 1972 for UNIX, it’s ideal for scenarios requiring initial execution, like menu-driven programs.
do { statements; } while (condition);
Note: The C89 standard formalized do-while behavior, ensuring portability. Use cautiously to avoid infinite loops.
Copy#include <stdio.h> int main() { int i = 1; do { printf("%d ", i); i++; } while (i <= 5); return 0; }
#include <stdio.h> int main() { int i = 1; do { printf("%d ", i); i++; } while (i <= 5); return 0; }
The switch statement in C executes one of many code blocks based on an expression’s value, offering an alternative to multiple if-else statements. Introduced in 1972, it’s efficient for multi-way branching.
if-else
switch(expression)
case
default
Note: C89 standardized switch behavior. Use break to avoid unintended fall-through.
Copy#include <stdio.h> int main() { int day = 3; switch (day) { case 1: printf("Monday\n"); break; case 2: printf("Tuesday\n"); break; case 3: printf("Wednesday\n"); break; default: printf("Invalid day\n"); } return 0; }
#include <stdio.h> int main() { int day = 3; switch (day) { case 1: printf("Monday\n"); break; case 2: printf("Tuesday\n"); break; case 3: printf("Wednesday\n"); break; default: printf("Invalid day\n"); } return 0; }
Wednesday
The break and continue statements in C control loop and switch execution. break exits a loop or switch, while continue skips to the next iteration. Introduced in 1972, they provide precise flow control.
Note: C89 standardized their behavior, ensuring consistent use.
Copy#include <stdio.h> int main() { for (int i = 1; i <= 5; i++) { if (i == 3) continue; // Skip 3 if (i == 5) break; // Exit at 5 printf("%d ", i); } return 0; }
#include <stdio.h> int main() { for (int i = 1; i <= 5; i++) { if (i == 3) continue; // Skip 3 if (i == 5) break; // Exit at 5 printf("%d ", i); } return 0; }
1 2 4
In C, a function is a block of code that performs a specific task and can be called from other parts of the program. Introduced in C’s 1972 design by Dennis Ritchie for UNIX, functions promote modularity and reusability, making programs more organized.
int add(int a, int b)
main()
return
void
Note: C89 standardized function syntax, with C99 adding inline functions for optimization. Functions are essential for structured programming in 2025.
Copy#include <stdio.h> int add(int a, int b) { return a + b; } int main() { int result = add(5, 3); printf("Sum: %d\n", result); return 0; }
#include <stdio.h> int add(int a, int b) { return a + b; } int main() { int result = add(5, 3); printf("Sum: %d\n", result); return 0; }
Sum: 8
Function parameters in C are variables passed to a function to provide input data. Parameters allow functions to operate on dynamic values, a feature integral to C’s 1972 design for flexible UNIX utilities.
void swap(int *a, int *b)
Note: C89’s function prototypes ensure type checking for parameters, improving safety.
Copy#include <stdio.h> void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main() { int x = 10, y = 20; printf("Before swap: x = %d, y = %d\n", x, y); swap(&x, &y); printf("After swap: x = %d, y = %d\n", x, y); return 0; }
#include <stdio.h> void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main() { int x = 10, y = 20; printf("Before swap: x = %d, y = %d\n", x, y); swap(&x, &y); printf("After swap: x = %d, y = %d\n", x, y); return 0; }
Before swap: x = 10, y = 20 After swap: x = 20, y = 10
Scope in C determines the visibility and lifetime of variables and functions. Defined in C’s 1972 design, scope ensures controlled access to data, preventing unintended modifications in UNIX programs.
Note: C89 standardized scope rules, with C99 enhancing block scope for variables like loop counters.
Copy#include <stdio.h> int global = 100; // Global scope int main() { int local = 50; // Local scope { int block = 10; // Block scope printf("Block scope: %d\n", block); } printf("Local scope: %d\n", local); printf("Global scope: %d\n", global); return 0; }
#include <stdio.h> int global = 100; // Global scope int main() { int local = 50; // Local scope { int block = 10; // Block scope printf("Block scope: %d\n", block); } printf("Local scope: %d\n", local); printf("Global scope: %d\n", global); return 0; }
Block scope: 10 Local scope: 50 Global scope: 100
Recursion in C occurs when a function calls itself to solve a problem by breaking it into smaller instances. A key feature of C’s 1972 design, recursion is powerful for algorithms like factorials or tree traversals.
Note: C89 standardized function call behavior, ensuring reliable recursion.
Copy#include <stdio.h> int factorial(int n) { if (n <= 1) return 1; // Base case return n * factorial(n - 1); // Recursive case } int main() { int n = 5; printf("Factorial of %d: %d\n", n, factorial(n)); return 0; }
#include <stdio.h> int factorial(int n) { if (n <= 1) return 1; // Base case return n * factorial(n - 1); // Recursive case } int main() { int n = 5; printf("Factorial of %d: %d\n", n, factorial(n)); return 0; }
Factorial of 5: 120
C provides math functions in the <math.h> library for operations like trigonometry, logarithms, and rounding. Introduced in C’s early days, these functions support numerical computations in UNIX and beyond.
<math.h>
-lm
gcc -o program program.c -lm
sqrt
pow
sin
ceil
floor
double
float
Note: C99 expanded <math.h> with functions like fmin and fmax, enhancing precision.
fmin
fmax
Copy#include <stdio.h> #include <math.h> int main() { double x = 16.0, y = 2.0; printf("Square root of %.1f: %.1f\n", x, sqrt(x)); printf("Power %.1f^%.1f: %.1f\n", x, y, pow(x, y)); printf("Ceiling of 3.7: %.1f\n", ceil(3.7)); return 0; }
#include <stdio.h> #include <math.h> int main() { double x = 16.0, y = 2.0; printf("Square root of %.1f: %.1f\n", x, sqrt(x)); printf("Power %.1f^%.1f: %.1f\n", x, y, pow(x, y)); printf("Ceiling of 3.7: %.1f\n", ceil(3.7)); return 0; }
Square root of 16.0: 4.0 Power 16.0^2.0: 256.0 Ceiling of 3.7: 4.0
A function declaration in C specifies a function’s name, return type, and parameters without its body, allowing use before definition. Introduced in 1972, declarations were formalized in C89 with prototypes for type safety.
int multiply(int, int);
Note: C89’s prototypes prevent type mismatches, a significant improvement over K&R C.
Copy#include <stdio.h> int multiply(int a, int b); // Declaration int main() { int result = multiply(4, 5); printf("Product: %d\n", result); return 0; } int multiply(int a, int b) { // Definition return a * b; }
#include <stdio.h> int multiply(int a, int b); // Declaration int main() { int result = multiply(4, 5); printf("Product: %d\n", result); return 0; } int multiply(int a, int b) { // Definition return a * b; }
Product: 20