C Programming
This guide provides an introduction to the C programming language. It covers foundational concepts, syntax, and core programming structures, ranging from basic setup to memory management.
1. Introduction to C
C is a general-purpose, procedural programming language developed in 1972 by Dennis Ritchie at Bell Labs. It is widely used for system programming, operating systems, embedded devices, and performance-critical applications because of its efficiency and close-to-hardware control.
Key Features of C:
- Procedural Language: Instructions are executed step-by-step using functions.
- Fast and Efficient: Compiles directly to machine code, providing high execution speed.
- Low-level Manipulation: Allows direct access to memory using pointers.
- Portability: C programs written on one system can often be compiled and run on another with minimal modifications.
2. Setting Up the Environment
To write and run C programs, you need a text editor (to write code) and a C compiler (to translate code into machine-executable format).
Popular Compilers:
- GCC (GNU Compiler Collection): Widely used on Linux, macOS, and Windows (via MinGW).
- Clang: A modern, fast compiler available on multiple platforms.
- MSVC (Microsoft Visual C++): Included with Visual Studio on Windows.
Installation Quick-Start:
- Linux: Install GCC via your package manager (e.g.,
sudo apt install build-essential). - macOS: Install Xcode Command Line Tools by running
xcode-select --installin the terminal. - Windows: Install MinGW-w64 or install Visual Studio Community Edition.
3. Your First C Program
Create a file named hello.c and enter the following code:
#include <stdio.h>
int main() {
// This is a single-line comment
printf("Hello, World!\n");
return 0;
}
Explanation:
#include <stdio.h>: A preprocessor command that includes the Standard Input/Output library, which allows the use of functions likeprintf.int main(): The entry point of every C program. Execution starts here.printf("Hello, World!\n");: Prints the text to the screen.\nrepresents a newline character.return 0;: Terminates themainfunction and returns0to the operating system, indicating successful execution.
Compiling and Running:
In your terminal, navigate to the folder containing hello.c and run:
gcc hello.c -o hello
./hello
4. Variables and Data Types
Variables are containers for storing data. In C, you must declare the type of a variable before using it.
Basic Data Types:
| Data Type | Keyword | Size (typical) | Format Specifier | Example |
|---|---|---|---|---|
| Integer | int | 4 bytes | %d or %i | 10, -500 |
| Character | char | 1 byte | %c | 'A', 'z' |
| Floating Point | float | 4 bytes | %f | 3.14f |
| Double Precision | double | 8 bytes | %lf | 3.14159265 |
Code Example:
#include <stdio.h>
int main() {
int age = 25;
double pi = 3.14159;
char grade = 'A';
printf("Age: %d\n", age);
printf("Pi: %lf\n", pi);
printf("Grade: %c\n", grade);
return 0;
}
5. Input and Output
C uses printf() for output and scanf() for input.
#include <stdio.h>
int main() {
int userAge;
printf("Enter your age: ");
// The '&' operator (address-of) is used to store the input into the userAge variable
scanf("%d", &userAge);
printf("You are %d years old.\n", userAge);
return 0;
}
6. Operators
Operators are symbols used to perform operations on variables and values.
1. Arithmetic Operators:
+ (Addition), - (Subtraction), * (Multiplication), / (Division), % (Modulus/Remainder)
2. Relational Operators:
== (Equal to), != (Not equal to), > (Greater than), < (Less than), >= (Greater than or equal to), <= (Less than or equal to)
3. Logical Operators:
&& (Logical AND), || (Logical OR), ! (Logical NOT)
7. Control Flow
Control flow statements allow your program to make decisions and repeat blocks of code.
Conditional Statements (if-else and switch)
#include <stdio.h>
int main() {
int score = 85;
// If-Else Statement
if (score >= 90) {
printf("Grade: A\n");
} else if (score >= 80) {
printf("Grade: B\n");
} else {
printf("Grade: C\n");
}
// Switch Statement
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;
}
Loops (for, while, do-while)
#include <stdio.h>
int main() {
// For loop: used when the number of iterations is known
printf("For Loop: ");
for (int i = 0; i < 5; i++) {
printf("%d ", i);
}
printf("\n");
// While loop: runs as long as the condition is true
printf("While Loop: ");
int count = 0;
while (count < 5) {
printf("%d ", count);
count++;
}
printf("\n");
// Do-While loop: guarantees the block runs at least once
printf("Do-While Loop: ");
int num = 0;
do {
printf("%d ", num);
num++;
} while (num < 5);
printf("\n");
return 0;
}
8. Functions
Functions are reusable blocks of code that perform specific tasks.
Structure of a Function:
return_type function_name(parameter_list) {
// Body of the function
return value;
}
Example:
#include <stdio.h>
// Function Declaration (Prototype)
int add(int a, int b);
int main() {
int sum = add(10, 20); // Function Call
printf("Sum: %d\n", sum);
return 0;
}
// Function Definition
int add(int a, int b) {
return a + b;
}
9. Arrays and Strings
Arrays
An array is a collection of elements of the same data type stored in contiguous memory locations.
#include <stdio.h>
int main() {
// Declaration and Initialization
int numbers[5] = {10, 20, 30, 40, 50};
// Accessing elements (0-indexed)
printf("First element: %d\n", numbers[0]);
// Modifying an element
numbers[1] = 25;
// Looping through an array
for (int i = 0; i < 5; i++) {
printf("Element %d: %d\n", i, numbers[i]);
}
return 0;
}
Strings
In C, a string is an array of characters terminated by a null character (\0).
#include <stdio.h>
#include <string.h> // Include string library for manipulation functions
int main() {
char name[] = "Alice"; // The compiler automatically appends '\0'
printf("Name: %s\n", name);
// Common string functions
printf("Length: %lu\n", strlen(name));
return 0;
}
10. Pointers
A pointer is a variable that stores the memory address of another variable. Pointers are a key feature of C, enabling manual memory management and efficient array handling.
#include <stdio.h>
int main() {
int num = 42;
int *ptr = # // ptr stores the memory address of num
printf("Value of num: %d\n", num);
printf("Address of num (&num): %p\n", (void*)&num);
printf("Value stored in ptr: %p\n", (void*)ptr);
printf("Value pointed to by ptr (*ptr): %d\n", *ptr); // Dereferencing
// Modifying value via pointer
*ptr = 100;
printf("New value of num: %d\n", num);
return 0;
}
Pointer Operators:
&(Address-of Operator): Returns the memory address of a variable.*(Dereference Operator): Accesses the value at the address stored in the pointer.
11. Structures (structs)
A structure allows you to group variables of different data types together under a single name.
#include <stdio.h>
#include <string.h>
// Defining a structure
struct Student {
char name[50];
int id;
double gpa;
};
int main() {
struct Student s1;
// Assigning values
strcpy(s1.name, "John Doe");
s1.id = 12345;
s1.gpa = 3.8;
// Accessing values
printf("Student Name: %s\n", s1.name);
printf("Student ID: %d\n", s1.id);
printf("GPA: %.2f\n", s1.gpa);
return 0;
}
12. Dynamic Memory Allocation
Sometimes you do not know how much memory you will need until runtime. C provides memory management functions in the <stdlib.h> library.
malloc(size): Allocates specified bytes of memory. Returns a void pointer.calloc(num, size): Allocates memory and initializes all bytes to zero.realloc(ptr, size): Resizes previously allocated memory.free(ptr): Releases allocated memory back to the system.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
int *arr;
// Dynamically allocate memory for 5 integers
arr = (int*) malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize and print array
for (int i = 0; i < n; i++) {
arr[i] = (i + 1) * 10;
printf("%d ", arr[i]);
}
printf("\n");
// Always free dynamically allocated memory
free(arr);
return 0;
}
13. File Handling
C allows you to read from and write to external files using the FILE structure.
Writing to a File:
#include <stdio.h>
int main() {
FILE *fptr;
// Open file in write mode ("w")
fptr = fopen("example.txt", "w");
if (fptr == NULL) {
printf("Error opening file!\n");
return 1;
}
fprintf(fptr, "Hello, this is written to a file.\n");
fclose(fptr); // Always close the file
printf("File written successfully.\n");
return 0;
}
Reading from a File:
#include <stdio.h>
int main() {
FILE *fptr;
char buffer[100];
// Open file in read mode ("r")
fptr = fopen("example.txt", "r");
if (fptr == NULL) {
printf("Error opening file or file does not exist.\n");
return 1;
}
// Read and print file contents
while (fgets(buffer, 100, fptr) != NULL) {
printf("%s", buffer);
}
fclose(fptr);
return 0;
}
Best Practices and Tips
1. Always Initialize Variables: Uninitialized variables contain garbage values, which can lead to unpredictable behavior.
2. Prevent Buffer Overflows: Use functions like fgets instead of gets to avoid writing past the bounds of an array.
3. Avoid Memory Leaks: Every call to malloc, calloc, or realloc must eventually have a corresponding call to free.
4. Compile with Warnings: Use compiler flags such as -Wall (all warnings) to identify potential bugs early:
gcc -Wall program.c -o program
The guide was created in June 2026.