Welcome to the world of C programming! This page covers fundamental concepts and crucial next steps, complete with code examples and explanations.
Every C program begins with a fundamental structure.
#include <stdio.h> // Header file for standard input/output functions
int main() { // Main function: the entry point of every C program
// Your code goes here
printf("Hello, World!\n"); // Prints "Hello, World!" to the console
return 0; // Indicates successful execution of the program
}
Explanation:
Variables store data. In C, you must declare a variable's data type before using it.
#include <stdio.h>
int main() {
// Integer type
int age = 30;
printf("Age: %d\n", age);
// Floating-point types
float price = 19.99;
double pi = 3.1415926535;
printf("Price: %.2f\n", price); // .2f limits to two decimal places
printf("Pi: %lf\n", pi);
// Character type
char grade = 'A';
printf("Grade: %c\n", grade);
// Boolean (using int, as C doesn't have a built-in bool type before C99)
// For C99 and later, you can include <stdbool.h>
int isRaining = 1; // 1 for true, 0 for false
printf("Is it raining? %d (1=Yes, 0=No)\n", isRaining);
return 0;
}
Explanation:
Operators perform operations on variables and values.
#include <stdio.h>
int main() {
int a = 10, b = 5;
int result;
// Arithmetic Operators
result = a + b; // Addition
printf("a + b = %d\n", result);
result = a - b; // Subtraction
printf("a - b = %d\n", result);
result = a * b; // Multiplication
printf("a * b = %d\n", result);
result = a / b; // Division (integer division)
printf("a / b = %d\n", result);
result = a % b; // Modulo (remainder)
printf("a %% b = %d\n", result); // %% to print a literal %
// Relational Operators (return 0 or 1)
printf("a > b: %d\n", a > b); // Greater than
printf("a < b: %d\n", a < b); // Less than
printf("a == b: %d\n", a == b); // Equality check
printf("a != b: %d\n", a != b); // Inequality check
// Logical Operators (return 0 or 1)
int x = 5, y = 10;
printf("(x > 0 && y < 20): %d\n", (x > 0 && y < 20)); // AND
printf("(x < 0 || y < 5): %d\n", (x < 0 || y < 5)); // OR
printf("!(x == 5): %d\n", !(x == 5)); // NOT
// Assignment Operators
int c = 10;
c += 5; // c = c + 5;
printf("c after c += 5: %d\n", c);
// Increment/Decrement Operators
int i = 0;
i++; // i = i + 1; (post-increment)
printf("i after i++: %d\n", i);
++i; // i = i + 1; (pre-increment)
printf("i after ++i: %d\n", i);
return 0;
}
Explanation:
Interact with the user using input and output functions from the <stdio.h> library.
#include <stdio.h>
int main() {
int num;
char name[50]; // Character array to store a string
// Taking integer input
printf("Enter an integer: ");
scanf("%d", &num); // &num is the address of the variable num
printf("You entered: %d\n", num);
printf("Enter your full name (with spaces): ");
// Clear the input buffer before using fgets after scanf
// This consumes the leftover newline character from the previous scanf
while (getchar() != '\n');
fgets(name, sizeof(name), stdin); // Reads up to sizeof(name)-1 chars or until newline
printf("Welcome, %s", name); // name contains the newline character from fgets
return 0;
}
Explanation:
Control flow statements determine the order in which instructions are executed.
#include <stdio.h>
int main() {
int score = 75;
if (score >= 90) {
printf("Grade: A\n");
} else if (score >= 80) {
printf("Grade: B\n");
} else if (score >= 70) {
printf("Grade: C\n");
} else {
printf("Grade: F\n");
}
return 0;
}
Explanation:
#include <stdio.h>
int main() {
char grade = 'B';
switch (grade) {
case 'A':
printf("Excellent!\n");
break; // Exit the switch statement
case 'B':
printf("Good!\n");
break;
case 'C':
printf("Fair.\n");
break;
case 'D':
printf("Needs improvement.\n");
break;
case 'F':
printf("Fail.\n");
break;
default: // If no case matches
printf("Invalid grade.\n");
}
return 0;
}
Explanation:
#include <stdio.h>
int main() {
printf("For loop:\n");
// Initialization; Condition; Iteration
for (int i = 1; i <= 3; i++) {
printf("%d ", i);
}
printf("\n");
printf("While loop:\n");
int j = 1; // Initialization
while (j <= 3) { // Condition
printf("%d ", j);
j++; // Iteration
}
printf("\n");
printf("Do-While loop:\n");
int k = 1; // Initialization
do {
printf("%d ", k);
k++; // Iteration
} while (k <= 3); // Condition checked after first iteration
printf("\n");
return 0;
}
Explanation:
Arrays are collections of elements of the same data type, stored in contiguous memory locations.
#include <stdio.h>
#include <string.h> // For string functions like strcpy
int main() {
// Declaring and initializing an integer array
int numbers[5] = {10, 20, 30, 40, 50};
// Accessing array elements (indexing starts from 0)
printf("First element: %d\n", numbers[0]); // Output: 10
printf("Third element: %d\n", numbers[2]); // Output: 30
// Modifying an element
numbers[1] = 25;
printf("Modified second element: %d\n", numbers[1]);
// Iterating through an array
printf("All elements: ");
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
// Character array (string) - null-terminated
char greeting[] = "Hello"; // Size is automatically determined (6 characters including null)
printf("Greeting: %s\n", greeting);
// Accessing characters in a string
printf("First character of greeting: %c\n", greeting[0]);
return 0;
}
Explanation:
Functions are blocks of code that perform a specific task. They promote code reusability and modularity.
#include <stdio.h>
// Function declaration (prototype) - tells compiler about the function
int add(int a, int b);
void greet(char name[]);
int main() {
int sum = add(5, 7); // Call the add function
printf("Sum: %d\n", sum);
greet("Alice"); // Call the greet function
greet("Bob");
return 0;
}
// Function definition - contains the actual code
int add(int a, int b) {
return a + b; // Returns the sum of a and b
}
void greet(char name[]) {
printf("Hello, %s!\n", name); // Does not return a value (void)
}
Explanation:
Pointers are variables that store memory addresses of other variables. They are fundamental for dynamic memory, arrays, and data structures.
#include <stdio.h>
int main() {
int num = 10;
int *ptr; // Declare a pointer to an integer (ptr will store an address of an int)
ptr = # // Store the memory address of 'num' in 'ptr' (& is "address-of")
printf("Value of num: %d\n", num);
printf("Address of num: %p\n", &num); // %p is for printing addresses
printf("Value of ptr (address stored): %p\n", ptr);
printf("Value at the address pointed by ptr: %d\n", *ptr); // * is "dereference" (access value at address)
// Changing value through pointer
*ptr = 20; // Modify the value at the address pointed to by ptr
printf("New value of num (changed via pointer): %d\n", num);
return 0;
}
Explanation:
Structures allow you to group variables of different data types under a single name, creating custom data types.
#include <stdio.h>
#include <string.h> // For strcpy
// Define a structure named Student
struct Student {
char name[50]; // Member 1: character array for name
int roll_number; // Member 2: integer for roll number
float marks; // Member 3: float for marks
};
int main() {
// Declare a structure variable
struct Student student1;
// Access and assign values to members using the dot operator (.)
strcpy(student1.name, "John Doe"); // Use strcpy for string assignment
student1.roll_number = 101;
student1.marks = 85.5;
// Print structure members
printf("Student Name: %s\n", student1.name);
printf("Roll Number: %d\n", student1.roll_number);
printf("Marks: %.2f\n", student1.marks);
// Another way to initialize a structure variable
struct Student student2 = {"Jane Smith", 102, 92.0};
printf("\nStudent Name: %s\n", student2.name);
printf("Roll Number: %d\n", student2.roll_number);
printf("Marks: %.2f\n", student2.marks);
return 0;
}
Explanation:
Learn how to interact with files on your computer's disk, allowing your program to persist data and read external information.
#include <stdio.h>
#include <stdlib.h> // For exit() (optional, but good for error handling)
int main() {
FILE *filePointer; // Declare a file pointer
char data[100];
// --- Writing to a file ---
// "w" mode: open for writing (creates file if it doesn't exist, overwrites if it does)
filePointer = fopen("example.txt", "w");
if (filePointer == NULL) {
printf("Error opening file for writing!\n");
return 1; // Indicate an error
}
fprintf(filePointer, "Hello, C File I/O!\n"); // Write formatted output to the file
fprintf(filePointer, "This is a new line.\n");
fclose(filePointer); // Close the file
printf("Data written to example.txt\n");
// --- Reading from a file ---
// "r" mode: open for reading
filePointer = fopen("example.txt", "r");
if (filePointer == NULL) {
printf("Error opening file for reading!\n");
return 1;
}
printf("\nReading from example.txt:\n");
// Read line by line until end of file (NULL)
while (fgets(data, sizeof(data), filePointer) != NULL) {
printf("%s", data); // fgets includes the newline character
}
fclose(filePointer); // Close the file
return 0;
}
Explanation:
Allocate memory at runtime (while the program is running) using functions from <stdlib.h>. This is essential when you don't know the exact size of data needed at compile time.
#include <stdio.h>
#include <stdlib.h> // For malloc, free
int main() {
int *arr; // Pointer to an integer array (will be dynamically allocated)
int n;
int i;
printf("Enter the number of elements: ");
scanf("%d", &n);
// Allocate memory for n integers using malloc
// malloc returns void*, so cast it to (int*)
// sizeof(int) determines the bytes needed for one integer
arr = (int *) malloc(n * sizeof(int));
// Check if malloc was successful (returns NULL on failure)
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1; // Indicate an error
}
printf("Enter %d integers:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]); // Populate the dynamically allocated array
}
printf("You entered: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]); // Print elements
}
printf("\n");
// Deallocate the memory when no longer needed
free(arr);
arr = NULL; // Good practice: set pointer to NULL after freeing to prevent dangling pointer issues
printf("Memory freed.\n");
return 0;
}
Explanation:
While `char` arrays cover basic strings, the <string.h> library provides powerful functions for string manipulation. Remember, C strings are null-terminated character arrays.
#include <stdio.h>
#include <string.h> // For string functions
int main() {
char str1[50] = "Hello";
char str2[50] = " World";
char str3[50];
char str4[50] = "Hello";
// strlen(): Returns the length of a string (excluding the null terminator)
printf("Length of str1: %zu\n", strlen(str1)); // %zu is for size_t type
// strcpy(destination, source): Copies one string to another. Beware of buffer overflows!
strcpy(str3, str1);
printf("str3 after strcpy(str3, str1): %s\n", str3);
// strcat(destination, source): Concatenates (joins) two strings. Beware of buffer overflows!
strcat(str1, str2); // str1 is now "Hello World"
printf("str1 after strcat(str1, str2): %s\n", str1);
// strcmp(string1, string2): Compares two strings lexicographically
// Returns 0 if equal, < 0 if string1 is smaller, > 0 if string1 is larger
if (strcmp(str1, str4) == 0) {
printf("str1 and str4 are equal.\n");
} else {
printf("str1 and str4 are not equal.\n"); // This will be printed ("Hello World" vs "Hello")
}
if (strcmp(str3, str4) == 0) {
printf("str3 and str4 are equal.\n"); // This will be printed ("Hello" vs "Hello")
}
// strstr(haystack, needle): Finds the first occurrence of a substring
char *sub = strstr(str1, "World");
if (sub != NULL) {
printf("Found 'World' in str1 starting at: %s\n", sub);
} else {
printf("'World' not found in str1.\n");
}
return 0;
}
Explanation:
Enums (enumerations) allow you to define a set of named integer constants. They improve code readability and make it easier to work with a fixed set of related values.
#include <stdio.h>
// Define an enum for days of the week
// By default, SUNDAY = 0, MONDAY = 1, etc.
enum Day {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
};
// Define an enum for months, explicitly assigning values
// JAN = 1, then FEB automatically becomes 2, MAR = 3, etc.
enum Month {
JAN = 1,
FEB,
MAR,
APR,
MAY,
JUN,
JUL,
AUG,
SEP,
OCT,
NOV,
DEC
};
int main() {
enum Day today = WEDNESDAY;
enum Month currentMonth = JUN;
printf("Today is day number: %d\n", today); // Output: 3 (WEDNESDAY is the 4th element, 0-indexed)
printf("Current month number: %d\n", currentMonth); // Output: 6
if (today == WEDNESDAY) {
printf("It's hump day!\n");
}
switch (currentMonth) {
case JAN:
case FEB:
case DEC:
printf("It's winter (in the Northern Hemisphere).\n");
break;
case JUN:
case JUL:
case AUG:
printf("It's summer (in the Northern Hemisphere).\n");
break;
default:
printf("It's another season.\n");
}
return 0;
}
Explanation:
A union is a special data type that allows you to store different data types in the same memory location. It can only hold one member's value at a time. The size of a union is determined by the size of its largest member.
#include <stdio.h>
#include <string.h> // For strcpy
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data; // Declare a union variable
data.i = 10;
printf("data.i (after int assignment): %d\n", data.i);
// After assigning to 'i', 'f' and 'str' contain garbage/undefined values
printf("data.f (garbage after int assignment): %f\n", data.f);
data.f = 220.5; // Assign to float member - this overwrites the memory shared by 'i' and 'str'
printf("data.f (after float assignment): %f\n", data.f);
printf("data.i (garbage after float assignment): %d\n", data.i); // 'i' is now corrupted
// Assign to string member - this overwrites the memory shared by 'i' and 'f'
strcpy(data.str, "C Programming");
printf("data.str (after string assignment): %s\n", data.str);
// Only the last assigned member is valid! Accessing others will lead to undefined behavior.
printf("data.i (garbage after string assignment): %d\n", data.i);
printf("data.f (garbage after string assignment): %f\n", data.f);
return 0;
}
Explanation:
Command line arguments allow you to pass information to your C program when you run it from the terminal or command prompt. This enables flexible and dynamic program execution.
#include <stdio.h>
#include <stdlib.h> // For atoi() - ASCII to Integer conversion
// The main function can optionally take two parameters for command line arguments
// argc: Argument Count (number of arguments, including the program name itself)
// argv: Argument Vector (an array of strings, where each string is an argument)
int main(int argc, char *argv[]) {
printf("Number of arguments: %d\n", argc);
printf("Arguments received:\n");
// argv[0] is always the program's name
// argv[1] is the first argument, argv[2] the second, and so on.
for (int i = 0; i < argc; i++) {
printf("argv[%d]: %s\n", i, argv[i]);
}
// Example: Taking two numbers from command line and adding them
if (argc == 3) { // Expecting program_name, num1, num2 (total 3 arguments)
// Convert string arguments to integers using atoi()
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
int sum = num1 + num2;
printf("\nSum of %d and %d is: %d\n", num1, num2, sum);
} else if (argc > 1) {
printf("\nUsage: %s <number1> <number2> (for sum example)\n", argv[0]);
} else {
printf("\nNo additional arguments provided.\n");
}
return 0;
}
Explanation:
How to run (after compiling, e.g., `gcc myprogram.c -o myprogram`):
./myprogram # Output will show "No additional arguments"
./myprogram hello world # Output will list "hello" and "world" as arguments
./myprogram 10 20 # Output: "Sum of 10 and 20 is: 30"
Preprocessor directives are instructions to the C preprocessor, which processes your code before compilation. They are not C statements themselves, but rather commands that modify the source code before it reaches the compiler.
#include <stdio.h>
// 1. Symbolic Constant: #define replaces text literally before compilation
#define PI 3.14159
#define GREETING "Hello from the Preprocessor!"
// 2. Simple Function-like Macro: also performs text replacement, supports arguments
// Wrap arguments and the entire macro in parentheses to prevent side effects
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MULTIPLY(x, y) (x * y)
// 3. Conditional Compilation: #ifdef, #ifndef, #if, #else, #elif, #endif
// Code blocks are included or excluded based on whether a macro is defined
#define DEBUG_MODE // Uncomment this line to enable debug messages
int main() {
printf("Value of PI: %f\n", PI);
printf("%s\n", GREETING);
int val1 = 10, val2 = 20;
printf("Max of %d and %d is: %d\n", val1, val2, MAX(val1, val2));
printf("Product of 5 and 4 is: %d\n", MULTIPLY(5, 4));
// This block only gets compiled if DEBUG_MODE is defined
#ifdef DEBUG_MODE
printf("[DEBUG] Debug mode is active. Variable val1 = %d, val2 = %d\n", val1, val2);
#else
printf("[INFO] Debug mode is inactive.\n");
#endif
// Example of #if for standard version check
#if __STDC_VERSION__ >= 199901L
printf("Compiling with C99 or later standard.\n");
#else
printf("Compiling with an older C standard.\n");
#endif
return 0;
}
Explanation:
This HTML page now provides a solid foundation for your C programming journey, with clearer explanations and properly formatted code blocks. Keep practicing and exploring!