Let’s be honest — getting started with C programming often feels harder than it should be. You try installing TurboC, only to end up stuck with an outdated interface from the 90s. You switch to DevC++, but then it crashes or won’t compile properly. Even setting up MinGW and VS Code can feel overwhelming when all you really want is to write your first printf("Hello, World!");.
That’s where we make things simple.
With our Online C Compiler, you can skip the boring setup entirely. It runs right in your browser — no downloads, no configuration, no errors. Just open it, type your code, and hit Run. You’ll see your output instantly, just like that.
Whether you’re learning the basics, experimenting with pointers, or testing algorithms, our compiler gives you everything you need to learn faster and code smarter. So before you install another outdated IDE, try the modern way to practice C ⇒ Start Coding Now
Introduction to C
C is a powerful general-purpose programming language that remains one of the most important foundations of modern software development. It’s widely used in system programming, embedded systems, and applications that demand high performance.
What makes C so special is its efficiency, close-to-hardware control, and portability — you can write a program on one machine and run it almost anywhere. C gives you the tools to understand how memory works, how data moves through a computer, and how to write programs that perform with precision and speed.
Learning C isn’t just about mastering another programming language — it’s about understanding the building blocks of technology itself. Many modern languages like C++, Java, and Python trace their roots back to C. Mastering it will give you a rock-solid foundation for everything else you learn in programming.
History Of C
- Developed by Dennis Ritchie at Bell Labs in the early 1970s.
- Known for its efficiency, simplicity, and low-level system access.
- Follows a procedural programming paradigm.
- Focuses on functions and structured programming.
- Highly portable language, allowing programs written in C to run on different platforms with minimal modifications.
- C uses a syntax that includes variables, data types, operators, and control structures (loops and conditionals).
Features Of C
Installation Of C
To run C/C++ in your system you need two things:
- MinGW compiler: Search for "mingw compiler downloader" in Google, install it, and set the environment variable by giving the compiler path.
- Code Editor/IDE: Download VS Code. (Avoid DevC++/Turbo C as they are discontinued.)
- Create a file in your editor with a
.cextension. - Install Code Runner Plugin in VS Code to easily run code in the IDE, or use the terminal for manual compilation.
Jobs And Applications Of C
Jobs Of C
- C is in high demand , especially for:
- System Programmer
- Embedded Systems Engineer
- Software Developer
- Experienced developers (3–5 years) can earn around 110,000/year in the U.S. (varies by location).
- Top companies using C:
- Microsoft
- Intel
- Red Hat
- IBM
Applications Of C
- C is a general-purpose programming language.
- Widely used in various domains, including: - Operating Systems: - Used in developing OS kernels like Windows, Linux, macOS, and Android. - Real-Time Systems: - Found in robotics, industrial automation, and avionics where time-sensitive tasks are required. - Compilers and Interpreters - Cybersecurity , Reverse Engineering and more
Our First Program In C
hello.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Hello, World!
1. Basic Syntax
C shares similarities with other programming languages like Python, Java and C++, but it also introduces some distinct differences that set it apart.
It is known for its simplicity, efficiency, and closeness to hardware.
Let’s dive into writing and executing our first C program, and explore the different modes in which C can be executed.
Steps Of Formation Of Executable Code From Source Code
C is a compiled language. Let’s see how the compilation process works:
The steps involved in compiling a C program are:
- Preprocessing: Handles directives like
#includeand#define. - Compilation: Converts source code to object code.
- Assembly: Translates object code to machine code.
- Linking: Links libraries and object files to produce the final executable.
- Loading: Loads the executable into memory for execution.
Variables
- Named memory location used to store a value that can be modified during program execution.
- It is identified by names, used to hold data.
- It acts as a container for data, and each variable is associated with a specific data type that determines the size and layout of its memory.
Rules for Declaring Variables:
- Must begin with a letter
(A-Z or a-z)or an underscore(_). Cannot start with a digit. - The rest of the name may consist of
letters,digits, orunderscores. - Cannot use C keywords (like int, main, return).
- Case sensitive (Age and age are different).
Syntax For Creating Variables
Variable.c
#include <stdio.h>
int main() {
int age = 20; // Integer variable
float height = 5.9; // Floating-point variable
char grade = 'A'; // Character variable
// Printing the values
printf("Age: %d\n", age);
printf("Height: %.1f\n", height);
printf("Grade: %c\n", grade);
return 0;
}
Age: 20
Height: 5.9
Grade: A
C Operators
C operators are symbols that perform operations on variables and values.
They are essential for performing arithmetic, logical, comparative, and many other operations.
Types Of Operators
C operators are categorized into the following categories −
Operator Types
- Arithmetic Operators:
+,-,*,/,% - Relational Operators:
==,!=,>,<,>=,<= - Logical Operators:
&&,||,! - Bitwise Operators:
&,|,^,~,<<,>> - Assignment Operators:
=,+=,-=,*=,/=,%= - Increment/Decrement Operators:
++,--
Operator Precedence & Associativity
In programming languages, the associativity of an operator determines how operators of the same precedence are grouped together in the absence of parentheses.
| Operator | Associativity | Description |
|---|---|---|
++, -- |
Right to Left | Increment, Decrement |
*, /, % |
Left to Right | Multiplication, Division |
+, - |
Left to Right | Addition, Subtraction |
==, != |
Left to Right | Equality, Inequality |
&& |
Left to Right | Logical AND |
= |
Right to Left | Assignment |
Assignment Operators
The assignment operator is used to assign values to variables.
| Operator | Example | Meaning |
|---|---|---|
= |
x = y |
Assign y to x |
+= |
x += y |
x = x + y |
-= |
x -= y |
x = x - y |
*= |
x *= y |
x = x * y |
/= |
x /= y |
x = x / y |
%= |
x %= y |
x = x % y |
&= |
x &= y |
x = x & y |
^= |
x ^= y |
x = x ^ y |
<<= |
x <<= y |
x = x << y |
>>= |
x >>= y |
x = x >> y |
Bitwise Operators
Bitwise operators operate on individual bits of data.
&→ Bitwise AND|→ Bitwise OR^→ Bitwise XOR~→ Bitwise NOT<<→ Left shift>>→ Right shift
Logical Operators
- Logical AND (
&&) → Returns true if both operands are true. - Logical OR (
||) → Returns true if at least one operand is true. - Logical NOT (
!) → Returns true if the operand is false.
Code Example Of Operators
operators.c
#include <stdio.h>
int main() {
int a = 10, b = 5, result;
int x = 1, y = 0;
// Arithmetic Operators
result = a + b;
printf("Addition: %d + %d = %d\n", a, b, result);
result = a - b;
printf("Subtraction: %d - %d = %d\n", a, b, result);
result = a * b;
printf("Multiplication: %d * %d = %d\n", a, b, result);
result = a / b;
printf("Division: %d / %d = %d\n", a, b, result);
result = a % b;
printf("Modulus: %d %% %d = %d\n", a, b, result);
// Relational Operators
printf("a > b: %d\n", a > b);
printf("a < b: %d\n", a < b);
printf("a == b: %d\n", a == b);
printf("a != b: %d\n", a != b);
// Logical Operators
printf("x && y: %d\n", x && y); // AND
printf("x || y: %d\n", x || y); // OR
printf("!x: %d\n", !x); // NOT
// Assignment Operators
result = a; // Assignment
result += 5; // result = result + 5
printf("Result after += 5: %d\n", result);
result *= 2; // result = result * 2
printf("Result after *= 2: %d\n", result);
return 0;
}
Output:
Addition: 10 + 5 = 15
Subtraction: 10 - 5 = 5
Multiplication: 10 * 5 = 50
Division: 10 / 5 = 2
Modulus: 10 % 5 = 0
a > b: 1
a < b: 0
a == b: 0
a != b: 1
x && y: 0
x || y: 1
!x: 0
Result after += 5: 15
Result after *= 2: 30
2. Control Statements in C
Control statements control the flow of execution of a program.
These statements help to make decisions, repeat tasks, or jump to specific parts of code.
Types of Control Statements in C
if Statement
A conditional statement used to execute a block of code only if a given condition is true.
if (condition) {
// code
}
if-else Statement
Extends the if statement to execute one block if the condition is true and another block if it is false.
if (condition) {
// true block
} else {
// false block
}
if-else if Statement
Allows multiple conditions to be checked in sequence. The first condition that evaluates to true is executed.
if (number > 0) {
// block 1
} else if (number < 0) {
// block 2
} else {
// default block
}
switch Statement
Allows multi-way branching — executing one block of code out of many possible options based on a variable's value.
switch(expression) {
case value1:
// code
break;
case value2:
// code
break;
default:
// code
}
Example Program
#include <stdio.h>
int main() {
int number = 0;
if (number > 0) {
printf("The number is positive.\n");
} else if (number < 0) {
printf("The number is negative.\n");
} else {
printf("The number is zero.\n");
}
int choice = 2;
switch (choice) {
case 1:
printf("You selected option 1.\n");
break;
case 2:
printf("You selected option 2.\n");
break;
case 3:
printf("You selected option 3.\n");
break;
default:
printf("Invalid option.\n");
}
return 0;
}
Output
The number is zero.
You selected option 2.
3. Loops
Loops are control structures that allow the execution of a block of code repeatedly as long as a specified condition is met.
Common types of loops in C are: for, while, and do-while.
-
for Loop:Repeats a block of code a specific number of times. It is also known as Entry-Controlled loop as the condition is checked before the execution of code inside the loop body {}.for (initialization; condition; increment/decrement) { // code block }
-
while Loop:Repeats a block of code while a condition is true. It is also Entry-Controlled loopwhile (condition) { // code block }
-
do-while Loop:Executes code block at least once, then repeats while condition is true. It is also known as Exit-Controlled loop as the condition is checked after loop is executeddo { // code block } while (condition);
Code Example
#include <stdio.h>
int main(){
printf("\n\n*******Loop in C*********\n\n");
int index = 0;
for(int j = 0; j <= 10; j++) {
//FOR LOOP=> A for loop is a repetition control structure that allows us to efficiently write a loop that will execute a specific number of times.
printf("%d\n", j);
}
while (index <= 10) {
// WHILE LOOP =>The while loop allows code to be executed multiple times, depending upon a boolean condition that is given as a test expression. While studying for loop, we have seen that the number of iterations is known, whereas while loops are used in situations where we do not know the exact number of iterations of the loop. The while loop execution is terminated on the basis of the Boolean (true or false) test condition.
printf("%d\n", index);
index++;
}
int j=0;
do {
printf("do while loop is runnig"); //DOWHILE LOOP => The main difference between the do-while loop and while loop is that, in the do-while loop, the condition is tested at the end of the loop body, whereas the other two loops are entry controlled loops.
//Note: In do-while loop, the loop body will execute at least once irrespective of the test condition.
} while (j>5);
return 0;
}
Output:
*******Loop in C*******
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
do while loop is running
Nested Loop:
- A loop inside another loop.
- The inner loop runs completely every time the outer loop runs once.
#include <stdio.h>
int main() {
int i, j;
// Outer loop for rows
for (i = 1; i <= 5; i++) {
// Inner loop for columns
for (j = 1; j <= i; j++) {
printf("* ");
}
printf("\n"); // Move to the next line
}
return 0;
}
Output
*
* *
* * *
* * * *
* * * * *
More Few Things
-
An Infinite Loop:An infinite loop also known as an endless loop occurs when a condition always evaluates to true. Usually, this is considered an error. Sometimes, while executing a loop, it becomes necessary to jump out of the loop. For this, we will use the break statement or continue statement. -
break statement:When a break statement is encountered inside a loop whether it is a for loop or a while loop, the loop is terminated and the program continues with the statement immediately following the loop. -
continue statement:Using a continue statement in the loop will cause the control to go directly to the test-condition and then it will continue the loop process.
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue;
}
if (i == 8) {
break;
}
printf("%d ", i);
}
return 0;
}
Output
1 2 3 4 6 7
4. Functions & Recursion:
A function is a block of code that performs a specific task. It simplifies programming by breaking a large program into smaller, reusable pieces. This improves readability, modularity, and code reuse.
Prototype:
- A declaration that specifies the function name, return type, and parameter types without the body.
- Tells the compiler about the function before its definition.
Syntax Example:
int add(int, int);
Function Call:
- The statement that executes the function.
- Transfers control to the function.
result = add(5, 3);
User-Defined Functions:
- A user-defined function is created by the programmer to perform a specific task.
- Provides code reusability and modularity.
- Unlike built-in functions, their logic is defined by the user, and no extra header file is required.
Types of User-Defined Functions:
- Function with no arguments and no return value
- Function with arguments and no return value
- Function with arguments and a return value
- Function with no arguments and a return value
Recursion:
- A recursive function is a function that calls itself.
- Useful for problems that can be broken into smaller sub-problems (e.g., factorial, Fibonacci).
- Not always efficient because it may cause stack overflow if used excessively.
#include <stdio.h>
// Function Declarations
int sum(int a, int b); // With arguments and with return value
void printstar(int n); // With arguments and without return value
int takenumber(); // Without arguments and with return value
void Star_pattern(); // Without arguments and without return value
int factorial(int n); // Recursion example
// Function Definitions
void printstar(int n) // With arguments and without return value
{
for (int i = 0; i < n; i++)
{
printf("*\n");
}
}
int takenumber() // Without arguments and with return value
{
int i = 12; // Predefined number
return i;
}
void Star_pattern() // No argument and no return value
{
int a = 3; // Predefined number
for (int i = 0; i < a; i++)
{
printf("*\n");
}
}
int sum(int a, int b) // With arguments and with return value
{
return a + b;
}
int factorial(int n) // Recursion example
{
if (n == 0 || n == 1)
return 1;
else
return n * factorial(n - 1); // Recursive call
}
// Main Function
int main()
{
int a = 9, b = 87;
int c = sum(a, b); // With arguments and return value
printf("The sum of %d and %d is %d \n", a, b, c);
printstar(5); // With arguments and without return value
int d = takenumber(); // Without arguments and with return value
printf("The predefined number taken is %d \n", d);
Star_pattern(); // No argument and no return value
int num = 5; // Predefined number for factorial
printf("Factorial of %d is %d \n", num, factorial(num));
return 0;
}
Output:
The sum of 9 and 87 is 96
*
*
*
*
*
The predefined number taken is 12
*
*
*
Factorial of 5 is 120
5. Array
Array are collection of elements of the same data type.
- An array of structures is a collection of structures, all of the same type, stored in contiguous memory locations.
- It is useful for storing data sets with multiple attributes, like a list of students, employees, or products.
Features:
- Same Data Type: All elements must have the same type.
- Fixed Size: Declared at compile-time, cannot be resized dynamically.
- Indexing: Elements are accessed using zero-based indexing (0 to n-1).
- Contiguous Memory Allocation: Faster access.
Types of Arrays:
- One-Dimensional (1D) Array
- Two-Dimensional (2D) Array
- Multi-Dimensional Arrays
One-Dimensional Array: A single row of elements.
#include <stdio.h>
int main() {
int numbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}
return 0;
}
Output:
10 20 30 40 50
Two-Dimensional Array (Matrix): Stores data in rows and columns (table-like structure).
#include <stdio.h>
int main() {
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
Output:
1 2 3
4 5 6
Multi-Dimensional Array: Extension of 2D arrays into 3D or more.
#include <stdio.h>
int main() {
int cube[2][2][2] = {
};
}
Limitations of Arrays:
- Fixed size (cannot grow/shrink dynamically).
- All elements must be of the same type.
- Memory waste if declared too large.
Benefits of Array:
- Organizes data: Keeps related data together in a structured form.
- Easy access: Access each element using the array index and each member using the dot operator.
- Scalability: Easy to add more structures to the array without changing the code structure significantly.
Example
#include <stdio.h>
int main() {
// Initialize a 2x4 array named 'marks' with some sample values
int marks[2][4] = {{45, 234, 2, 3},
{3, 2, 3, 3}};
// for(int i = 0; i < 4; i++)
// {
// printf("Enter the value of %d element of the array\n", i);
// scanf("%d", &marks[i]);
// }
// Loop to display the values of the 'marks' array
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++){
// printf("The value of %d, %d element of the array is %d\n", i, j, marks[i][j]);
// This code now prints the values of the 'marks' array in a tabular format.
printf("%d ", marks[i][j]);
}
printf("\n"); // Move to the next line after printing a row
}
// marks[0] = 34;
// printf("Marks of student 1 is %d\n", marks[0]);
// marks[0] = 4;
// marks[1] = 24;
// marks[2] = 34;
// marks[3] = 44;
// printf("Marks of student 1 is %d\n", marks[0]);
return 0;
}
Output:
45 234 2 3
3 2 3 3
6. Pointers
Pointers are nothing but variable storing the address of another variable.
- Every variable is stored at a specific memory location, identified by an address.
- A pointer stores this address, not the actual value.
Pointer Arithmetic:
-
Incrementing a pointer moves to the next memory location of the data type it points to.There is total 4 arithmetic operators that can be used on pointer:
-
Pointers support arithmetic operations like:
++→ Move to next memory location--→ Move to previous memory location+→ Add an integer to a pointer-→ Subtract an integer from a pointer
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d ", *p);
p++;
printf("%d ", *p);
return 0;
}
Output:
10 20
Types of Pointers:
- Null Pointer: Points to nothing, int *ptr = NULL;
- Void Pointer: Can point to any data type, void *ptr;
- Dangling Pointer: Points to a memory location that has been freed.
Usage Of Pointers:
- Accessing array elements
- Dynamic memory allocation
- Passing arguments to functions by reference
- Implementing data structures like linked lists and trees
- Accessing and manipulating memory directly
Dereferencing:
- Accessing the value stored at the memory address held by the pointer.
- Use the asterisk (*) operator to dereference a pointer.
Significance in Memory Management:
- Pointers allow direct access to memory, which can lead to more efficient and flexible code.
- Enable dynamic memory allocation (malloc, calloc, free).
- Facilitate the creation of complex data structures.
Common Pitfalls:
- Dangling Pointers: Using pointers that point to freed memory.
- Null Pointers: Dereferencing null pointers leading to crashes.
- Memory Leaks: Not freeing dynamically allocated memory.
- Pointer Arithmetic Errors: Miscalculations leading to invalid memory access.
- Buffer Overflows: Accessing memory beyond allocated limits.
Pass by Value:
- Copies the actual value of an argument into the formal parameter of the function.
- Changes made to the parameter inside the function do not affect the actual argument.
#include <stdio.h>
void changeValue(int x) {
x = 50;
printf("Inside function: x = %d\n", x);
}
int main() {
int a = 10;
printf("Before function call: a = %d\n", a);
changeValue(a);
printf("After function call: a = %d\n", a);
return 0;
}
Output:
Before function call: a = 10
Inside function: x = 50
After function call: a = 10
Pass by Reference (using pointers):
- Copies the address of an argument into the formal parameter of the function.
- Changes made to the parameter affect the actual argument.
#include <stdio.h>
void changeValue(int *x) {
*x = 50;
printf("Inside function: *x = %d\n", *x);
}
int main() {
int a = 10;
printf("Before function call: a = %d\n", a);
changeValue(&a);
printf("After function call: a = %d\n", a);
return 0;
}
Before function call: a = 10
Inside function: *x = 50
After function call: a = 50
Example
#include <stdio.h>
int main() {
printf("Lets learn about pointers\n");
int a=76;
int *ptra = &a;
int *ptr2 = NULL;
printf("The address of pointer to a is %p\n", &ptra);
printf("The address of a is %p\n", &a);
printf("The address of a is %p\n", ptra);
printf("The address of some garbage is %p\n", ptr2);
printf("The value of a is %d\n", *ptra);
printf("The value of a is %d\n", a);
return 0;
}
Output:
Lets learn about pointers
The address of pointer to a is 0x7fff1a4b1a98
The address of a is 0x7fff1a4b1aa4
The address of a is 0x7fff1a4b1aa4
The address of some garbage is (nil)
The value of a is 76
The value of a is 76
7. Actual & Formal Parameters:
Actual Parameters
Arguments passed to a function.
- They exist in the calling function (where the function is called).
- They supply input data to the function.
- They can be constants, variables, or expressions.
Formal Parameters
Parameters received by the function.
- They exist inside the function (local to the function).
- They store copies or references of actual parameters depending on the method of passing (value or reference).
- They terminate when the function ends.
#include <stdio.h>
void display(int x) { // x is formal parameter
printf("Value: %d\n", x);
}
int main() {
int num = 10;
display(num); // num is the actual parameter
return 0;
}
Value: 10
Actual Argument
- Definition: It refers to the expression used within the function call to pass a value or reference.
- Usage: Acts as input values during function execution.
- Example: In
foo(x),xis the actual argument.
Formal Argument
- Definition: It refers to the parameters declared in the function definition.
- Usage: Serves as placeholders for receiving values from actual arguments.
- Example: In
void foo(int y),yis the formal argument.
Call by Value
- Copies the value of the actual parameter.
- Does not affect the actual parameter.
- Default method in C.
#include <stdio.h>
void swap(int x, int y) {
int temp;
temp = x;
x = y;
y = temp;
printf("\nInside swap function:");
printf("\nValue of x: %d", x);
printf("\nValue of y: %d", y);
}
int main() {
int r = 10, v = 20;
swap(r, v); // passing values (call by value)
printf("\n\nInside main function:");
printf("\nValue of r: %d", r);
printf("\nValue of v: %d", v);
return 0;
}
Output:
Inside swap function:
Value of x: 20
Value of y: 10
Inside main function:
Value of r: 10
Value of v: 20
Call by Reference
- Passes the address of the actual parameter.
- Changes to the formal parameter affect the actual parameter.
- Implemented using pointers in C.
#include <stdio.h>
void changeValue(int* address)
{
*address = 36979898;
}
int main()
{
int a = 34, b =56;
printf("The value of a now is %d\n", a);
changeValue(&a);
printf("The value of a now is %d\n", a);
return 0;
}
Output:
The value of a now is 34
The value of a now is 36979898
Example
#include <stdio.h>
void greetUser(char name[], int age) {
printf("Hello %s! You are %d years old.\n", name, age);
}
int main() {
greetUser("Akash", 25);
greetUser("Shruti", 30);
return 0;
}
Output:
Hello Akash! You are 20 years old.
Hello Shruti! You are 19 years old.
8. Strings
In C, a string is a sequence of characters stored in contiguous memory, terminated by a special null character ('\0'). Unlike modern languages (like Python or Java) that have a built-in string type, C uses character arrays to represent strings.
Example:
char str[] = "Hello";
Memory representation:
| Index | Value |
|---|---|
| 0 | H |
| 1 | e |
| 2 | l |
| 3 | l |
| 4 | o |
| 5 | \0 |
- Every string in C must end with
'\0'.
Characteristics of Strings:
- Stored in contiguous memory.
- Terminated with null character.
- Can be manipulated using
<string.h>library functions. - Must allocate enough space for all characters plus one for
'\0'.
Ways to Declare and Initialize Strings
String Literal
char str[] = "Hello";
- Compiler adds
'\0'automatically.
Character Array
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[20] = "Hello"; // extra space available
- Always allocate an extra byte for '\0'.
Input and Output of Strings
Using printf and scanf
char name[20];
scanf("%s", name); // stops at space
printf("Name: %s", name);
Using gets()
gets(name);
Using fgets()
fgets(name, sizeof(name), stdin);
- Reads full line, including spaces.
- Safer than
gets().
Remove trailing newline:
name[strcspn(name, "\n")] = '\0';
String Output
printf("%s", str);
puts(str); //adds newline automatically.
- Pointer points to string literal in read-only memory.
- Modifying this is undefined behavior.
String Handling Functions (<string.h>)
| Function | Description |
|---|---|
strlen(s) |
Length of string (without '\0'). |
strcpy(dest, src) |
Copy string. |
strncpy() |
Copy up to n characters. |
strcat() |
Append one string to another. |
strcmp(s1, s2) |
Compare two strings. |
strchr() |
Find first occurrence of a character. |
strstr() |
Find substring. |
- Always include:
#include <string.h>
Examples of String Functions
String Length
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "C Programming";
printf("Length: %zu", strlen(str));
return 0;
}
Length: 13
Copy String
char src[] = "Hello";
char dest[20];
strcpy(dest, src);
Concatenate Strings
char str1[20] = "Hello ";
char str2[] = "World";
strcat(str1, str2);
Compare Strings
if(strcmp("abc", "abc") == 0)
printf("Equal");
Manual Implementation of String Functions
strlen()
int my_strlen(char *str) {
int length = 0;
while(str[length] != '\0')
length++;
return length;
}
Strings vs Character Arrays
| Aspect | String Literal | Character Array |
|---|---|---|
| Mutability | Cannot modify (read-only) | Can modify |
| Storage | Stored in text segment | Stored in stack or heap |
| Null Required | Yes | Yes |
Advantages
- Efficient representation of text.
- Wide library support.
Disadvantages
- Manual memory management.
- Risk of buffer overflow if not careful.
Real-World Applications
- Text processing (editors, compilers).
- File paths handling.
- Command-line argument parsing.
- Network protocols (message parsing).
Example
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char str[100];
int count = 0;
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
for(int i = 0; str[i] != '\0'; i++) {
char ch = tolower(str[i]);
if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')
count++;
}
printf("Vowel count: %d\n", count);
return 0;
}
Enter a string: hello
Vowel count: 2
9. Structures, Union & Typedef
Structures in C
A structure in C is a collection of variables (called members) of different data types grouped together under one name.
Advantages of Structures:
- Handles complex data easily.
- Groups different data types logically.
- Useful in real-world applications like databases.
Disadvantages:
- Cannot directly compare two structures using ==.
- Takes more memory than arrays (because of padding).
Example
#include <stdio.h>
#include <string.h>
struct Student {
int roll;
char name[50];
float marks;
};
int main() {
struct Student s;
s.roll = 1;
strcpy(s.name, "Akash");
s.marks = 92.5;
printf("Roll: %d\nName: %s\nMarks: %.2f\n", s.roll, s.name, s.marks);
return 0;
}
Roll: 1
Name: Akash
Marks: 92.50
Unions
A union is similar to a structure but uses shared memory for all its members.
- Only one member can hold a value at a time.
- Size of union = size of largest member.
- memory = size of largest member.
Advantages of Union:
- Memory efficient (used in embedded systems).
- Useful for interpreting the same memory differently.
Disadvantages:
- Only one member can be used at a time.
- Risk of data overwrite.
Example
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data d;
d.i = 10;
printf("i: %d\n", d.i);
d.f = 220.5; // overwrites i
printf("f: %.2f\n", d.f);
return 0;
}
i: 10
f: 220.50
Memory Layout:
- Structure: memory = sum of all members (with padding).
- Union: memory = size of largest member.
typedef in C
typedef is used to create a new name (alias) for an existing data type.
Advantages of typedef:
- Makes code shorter and readable.
- Useful for portability (changing data types easily).
Example
#include <stdio.h>
typedef unsigned int uint;
typedef struct {
int id;
char name[50];
} Student;
int main() {
uint age = 25;
Student s = {101, "Shruti"};
printf("Age: %u, Name: %s\n", age, s.name);
return 0;
}
Age: 25, Name: Shruti
Real-World Applications:
- Structures – Database records (students, employees).
- Unions – Device drivers, protocol headers, embedded systems.
- typedef – Portable code for operating systems and libraries.
Dynamic Memory Allocation:
The memory is allocated at compile-time (known as static memory allocation) and size cannot be changed at runtime. DMA allows you to allocate memory at runtime (during program execution), and free it when no longer needed.
- Memory is allocated on the heap (not stack).
- Gives flexibility to allocate memory as per program needs.
- You must free the memory manually after use, or you’ll create a memory leak.
C provides 4 main functions in <stdlib.h>:
| Function | Purpose |
|---|---|
malloc() |
Allocates memory block. |
calloc() |
Allocates memory block and initializes to zero. |
realloc() |
Resizes previously allocated memory. |
free() |
Frees allocated memory. |
malloc() – Memory Allocation
ptr = (cast_type*) malloc(size_in_bytes);
- Allocates size_in_bytes of memory.
- Returns a pointer to void (must be typecast).
- Contents are uninitialized (garbage values).
Example
int *ptr;
ptr = (int*) malloc(5 * sizeof(int)); // allocate memory for 5 integers
for(int i=0; i<5; i++)
ptr[i] = i+1;
for(int i=0; i<5; i++)
printf("%d ", ptr[i]);
free(ptr); // always free after use
- If forget to call free(), the memory remains occupied → Memory Leak.
calloc() – Contiguous Allocation
ptr = (cast_type*) calloc(n, size_of_each_element);
- Allocates memory for n elements, each of size size_of_each_element.
- Initializes all bytes to zero.
Example
int *ptr;
ptr = (int*) calloc(5, sizeof(int)); // all values start as 0
for(int i=0; i<5; i++)
printf("%d ", ptr[i]); // prints 0 0 0 0 0
free(ptr);
-
When to use:
Use
calloc()when you want initialized memory.
realloc() – Resize Memory
ptr = (cast_type*) realloc(ptr, new_size_in_bytes);
- Changes the size of previously allocated memory block.
- Old values remain unchanged (up to the smaller of old/new size).
- If it cannot expand in place, it allocates a new block and copies old data.
Example
int *ptr = (int*) malloc(3 * sizeof(int));
ptr[0]=10; ptr[1]=20; ptr[2]=30;
ptr = (int*) realloc(ptr, 5 * sizeof(int)); // expand to 5 integers
ptr[3]=40; ptr[4]=50;
for(int i=0; i<5; i++)
printf("%d ", ptr[i]);
free(ptr);
- Always check if
realloc()returns NULL before using the new pointer.
free() – Free Memory
free(ptr);
- Deallocates memory previously allocated by
malloc(),calloc(), orrealloc(). - Does not set pointer to NULL automatically (do it manually).
Example
free(ptr);
ptr = NULL; // Best practice
- Why set NULL: Accessing a freed pointer (dangling pointer) can crash the program.
Common Mistakes Beginners Make
- Forgetting to free memory → Memory Leak.
- Accessing memory after
free()→ Dangling Pointer. - Using
malloc()without checking if it returned NULL. - Allocating less memory than required (e.g., forgetting sizeof(type)).
Best Practices from My 35+ Years of Experience
- Always check return value of
malloc()/calloc():
if(ptr == NULL) {
printf("Memory allocation failed!");
exit(1);
}
- Always free memory when no longer needed.
- For large programs, track allocations with comments or logs.
- Use
calloc()when you need zero-initialized memory (e.g., arrays). - Avoid memory leaks by setting ptr = NULL after
free(). - Never use uninitialized pointers with DMA.
Real-World Applications:
- Dynamic arrays (e.g., resizing array when data grows).
- Linked lists, stacks, queues.
- Trees and graphs.
- Dynamic string handling (for unknown input sizes).
- Loading large files dynamically.
Advantages:
- Memory allocated as per need → saves memory.
- Flexible – can resize using realloc().
- Enables advanced data structures.
Disadvantages:
- Manual management (forgetting free() causes leaks).
- Slower than static allocation (because it uses heap).
- Fragmentation in long-running programs.
Practical Example – Dynamic Array:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
int *arr = (int*) malloc(n * sizeof(int));
if(arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for(int i=0; i<n; i++) {
printf("Enter element %d: ", i+1);
scanf("%d", &arr[i]);
}
printf("You entered: ");
for(int i=0; i<n; i++)
printf("%d ", arr[i]);
free(arr);
return 0;
}
Enter number of elements: 5
Enter element 1: 45
Enter element 2: 90
Enter element 3: 100
Enter element 4: 70
Enter element 5: 95
You entered: 45 90 100 70 95
10. File I/O
In C programming, File I/O (Input/Output) refers to reading from and writing to files stored on secondary storage (like hard disks), rather than working only with console (keyboard/screen).
Why is this important:
- Data persists even after the program ends.
- Allows handling large data.
- Used in real-world applications like databases, log systems, and configuration files.
File Handling in C
C uses a file pointer (FILE *) to manage files. All file operations are performed through this pointer.
The header file:
#include <stdio.h>
is required for file operations.
Key Steps in File I/O:
Open a file (fopen) -> Perform operations (read/write/append) -> Close the file (fclose) -> File Modes in C
When opening a file using fopen(filename, mode), the mode defines what you can do.
| Mode | Meaning |
|---|---|
"r" |
Read (file must exist) |
"w" |
Write (create new or overwrite existing) |
"a" |
Append (write at end of file) |
"r+" |
Read + Write (file must exist) |
"w+" |
Read + Write (create new or overwrite) |
"a+" |
Read + Append |
- For binary files, add "b" → e.g., "rb", "wb", "ab".
Opening a File
FILE *fp;
fp = fopen("data.txt", "r"); // open for reading
if(fp == NULL) {
printf("Error opening file!\n");
return 1;
}
- Always check if file opened successfully.
Closing a File
fclose(fp);
- Frees resources and ensures data is written properly.
Writing to a File
Using fprintf()
FILE *fp = fopen("data.txt", "w");
fprintf(fp, "Hello, World!\n");
fclose(fp);
Using fputs()
fputs("Hello, File Handling!", fp);
Using fputc()
fputc('A', fp);
Reading from a File
Using fscanf()
FILE *fp = fopen("data.txt", "r");
char str[50];
fscanf(fp, "%s", str);
- Problem: Stops at whitespace.
Using fgets()
fgets(str, sizeof(str), fp);
Using fgetc()
char ch = fgetc(fp);
Using fread() and fwrite() (Binary Files)
fread(buffer, size, count, fp);
fwrite(buffer, size, count, fp);
- Used for structures, images, and other non-text data.
File Positioning Functions
| Function | Purpose |
|---|---|
ftell(fp) |
Returns current position in file |
fseek(fp, offset, origin) |
Move file pointer |
rewind(fp) |
Reset pointer to beginning |
Example:
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
Detecting End of File (EOF)
while(!feof(fp)) {
char ch = fgetc(fp);
if(ch != EOF)
putchar(ch);
}
- Better approach: Check return value of fgetc() instead of feof().
Error Handling in File I/O
- Use perror() or strerror(errno) for descriptive errors.
if(fp == NULL) {
perror("File opening failed");
}
Conclusion
You’ve now explored the essential building blocks of C Programming — from variables, loops, and arrays to pointers, functions, and file handling. But remember: reading about code isn’t enough. Real learning happens when you start writing, testing, and debugging your own programs.
That’s exactly where our Online C Compiler at https://www.akashhalder.in/code-compiler comes in. It’s fast, beginner-friendly, and works right in your browser — no installation, no setup, just code and run instantly. Whether you’re experimenting with a new concept, revising examples from this guide, or solving coding challenges, our compiler gives you everything you need to turn theory into practice.
Want to level up even faster? Try creating mini-projects, explore standard libraries, or push your logic with algorithmic challenges — all directly in the compiler. Each line you write strengthens your foundation and moves you closer to mastering C.
So don’t just read — start coding now. Open the compiler, test your ideas, and watch your skills grow with every program you build. Practice daily. Code smart. Learn faster.
Short on Time?? Want to read Offline??
We have got you covered, Download the PDF version of this Blog!

