Credits: 4 | Core Compulsory
Max. Marks: 30 + 70 | Min. Passing Marks: 40
Total No. of Lectures-Tutorials-Practical (in hours per week): 4-0-0
The C programming language was developed in the early 1970s at Bell Labs by Dennis Ritchie. It was originally created for developing the UNIX operating system. C evolved from an earlier language called B, which was developed by Ken Thompson. Over the years, C has influenced many programming languages, such as C++, C#, and Java, and remains widely used due to its efficiency and control over system resources.
Programming languages are formal languages comprising a set of instructions that can be used to produce various kinds of output, such as software applications or algorithms. They can be categorized into:
A C program consists of various components, including:
int main() { ... }
.
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Compiling is the process of translating the C source code into machine code that the computer can execute. This is typically done using a compiler like GCC. The compilation process involves several steps:
gcc -o hello hello.c
The character set in C includes:
Keywords are reserved words that have special meaning in C. They cannot be used as identifiers. Some common keywords include:
int
, float
, char
, return
, if
, else
, while
, for
, etc.
int main() {
return 0; // 'return' is a keyword
}
Operators in C have a defined precedence, which determines the order in which operations are performed. The hierarchy from highest to lowest precedence is:
expr++
, expr--
++expr
, --expr
, +expr
, -expr
, !expr
*
, /
, %
+
, -
<<
, >>
<
, >
, <=
, >=
==
, !=
&
^
|
&&
||
?:
=
, +=
, -=
, etc.
int a = 5, b = 10;
int c = a + b * 2; // b is multiplied by 2 first, then added to a
C has several basic data types:
int age = 20;
float salary = 3000.50;
char grade = 'A';
Qualifiers modify the basic data types in C to provide more precision and control:
unsigned int count = 100;
long int distance = 1000000;
Variables are used to store data that can be modified during program execution. Each variable has a type that determines what kind of data it can hold.
int score = 100;
float temperature = 36.6;
Type declaration is the process of specifying the type of a variable when it is defined. This informs the compiler about the kind of data the variable will hold and how much memory to allocate for it.
int num; // Declares an integer variable
float price; // Declares a float variable
char letter; // Declares a character variable
The primary output function in C is printf()
. It is used to display data on the standard output (usually the console).
#include <stdio.h>
int main() {
int num = 10;
printf("The number is: %d\n", num);
return 0;
}
The primary input function in C is scanf()
, used to read formatted input from the user.
It requires format specifiers to identify the type of data being read.
%d
- for integers%f
- for floats%c
- for characters%s
- for strings
#include <stdio.h>
int main() {
int age;
printf("Enter your age: ");
scanf("%d", &age);
printf("Your age is: %d\n", age);
return 0;
}
Arithmetic operators are used to perform mathematical calculations in C. The main arithmetic operators include:
+
- Addition-
- Subtraction*
- Multiplication/
- Division%
- Modulus (remainder)
#include <stdio.h>
int main() {
int a = 10, b = 5;
printf("Addition: %d\n", a + b);
printf("Subtraction: %d\n", a - b);
printf("Multiplication: %d\n", a * b);
printf("Division: %d\n", a / b);
printf("Modulus: %d\n", a % b);
return 0;
}
Unary operators are operators that operate on a single operand. They can perform various operations, such as incrementing, decrementing, negating, or logical complementing a variable. Common unary operators include:
+
(Unary plus): Indicates a positive value.-
(Unary minus): Negates a value.++
(Increment): Increases the value of a variable by one.--
(Decrement): Decreases the value of a variable by one.Example:
#include <stdio.h>
int main() {
int a = 5;
printf("Original: %d\n", a);
printf("Incremented: %d\n", ++a); // Pre-increment
printf("Decremented: %d\n", --a); // Pre-decrement
return 0;
}
Relational operators are used to compare two values, and they return a boolean value (true or false). Common relational operators include:
==
: Equal to!=
: Not equal to>
: Greater than<
: Less than>=
: Greater than or equal to<=
: Less than or equal toLogical operators combine multiple relational expressions. They include:
&&
(Logical AND)||
(Logical OR)!
(Logical NOT)Example:
#include <stdio.h>
int main() {
int x = 10, y = 20;
if (x < y) {
printf("x is less than y\n");
}
if (x >= 5 && y <= 20) {
printf("x is greater than or equal to 5 AND y is less than or equal to 20\n");
}
return 0;
}
The if statement is a control structure that executes a block of code if the specified condition is true. It allows for conditional execution in programs.
Example:
#include <stdio.h>
int main() {
int num = 10;
if (num > 0) {
printf("The number is positive.\n");
}
return 0;
}
The if-else statement extends the if statement by providing an alternative block of code that executes if the condition is false.
Example:
#include <stdio.h>
int main() {
int num = -5;
if (num > 0) {
printf("The number is positive.\n");
} else {
printf("The number is not positive.\n");
}
return 0;
}
The for statement is used to execute a block of code a specific number of times. It is often used for iterating over arrays or executing a loop a predetermined number of times.
Example:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
printf("Iteration %d\n", i);
}
return 0;
}
The while loop repeatedly executes a block of code as long as a specified condition is true. It is often used when the number of iterations is not known in advance.
Example:
#include <stdio.h>
int main() {
int i = 1;
while (i <= 5) {
printf("Iteration %d\n", i);
i++;
}
return 0;
}
The do-while statement is similar to the while loop, but it guarantees that the block of code will execute at least once before checking the condition.
Example:
#include <stdio.h>
int main() {
int i = 1;
do {
printf("Iteration %d\n", i);
i++;
} while (i <= 5);
return 0;
}
The break statement is used to exit a loop or switch statement prematurely. It terminates the nearest enclosing loop or switch.
Example:
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // Exit the loop when i equals 5
}
printf("%d\n", i);
}
return 0;
}
The continue statement skips the current iteration of a loop and proceeds to the next iteration. It is often used to avoid executing certain code under specific conditions.
Example:
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // Skip even numbers
}
printf("%d\n", i);
}
return 0;
}
The switch statement allows for multi-way branching based on the value of a variable. It provides a cleaner syntax than multiple if-else statements.
Example:
#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;
}
The goto statement allows for an unconditional jump to another point in the program. It is generally discouraged in modern programming due to potential for creating complex, unstructured code.
Example:
#include <stdio.h>
int main() {
int num = 0;
start:
printf("Number: %d\n", num);
num++;
if (num < 5) goto start; // Jump to the 'start' label
return 0;
}
The ternary operator is a shorthand for the if-else statement and takes three operands. It is commonly used for simple conditional assignments.
Syntax:
condition ? expression1 : expression2
If the condition is true, expression1
is executed; otherwise, expression2
is executed.
Example:
#include <stdio.h>
int main() {
int a = 5, b = 10;
int max = (a > b) ? a : b; // Ternary operator
printf("Maximum value: %d\n", max);
return 0;
}
An array is a collection of elements of the same type, stored in contiguous memory locations. It allows you to store multiple values in a single variable and is accessed using indices.
There are several types of arrays in C:
To declare an array, specify the data type followed by the array name and size. The syntax is:
data_type array_name[size];
Example:
#include <stdio.h>
int main() {
int arr[5]; // Declaration of an integer array of size 5
return 0;
}
Arrays can be initialized at the time of declaration. The syntax is:
data_type array_name[size] = {value1, value2, ...};
Example:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5}; // Initialization of an integer array
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // Accessing array elements
}
return 0;
}
Arrays allow you to store multiple values of the same type in a single variable. This simplifies the management of data as it can be accessed using an index. Here are some advantages:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
printf("First element: %d\n", arr[0]);
printf("Second element: %d\n", arr[1]);
return 0;
}
Accessing data from an array is done using the index of the elements. The index starts from 0, meaning the first element is at index 0, the second at index 1, and so on.
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for(int i = 0; i < 5; i++) {
printf("Element at index %d: %d\n", i, arr[i]);
}
return 0;
}
Arrays are stored in contiguous memory locations, which allows the program to calculate the address of each element. The base address is the address of the first element.
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
printf("Address of arr: %p\n", (void*)arr);
printf("Address of arr[0]: %p\n", (void*)&arr[0]);
printf("Address of arr[1]: %p\n", (void*)&arr[1]);
return 0;
}
Multi-dimensional arrays are arrays of arrays. They can be used to represent matrices and higher-dimensional data.
#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;
}
Character arrays are used to store strings in C. They are essentially arrays of characters terminated by a null character ('\\0').
#include <stdio.h>
int main() {
char name[20] = "John Doe";
printf("Name: %s\n", name);
return 0;
}
Array overflow occurs when you try to access an index outside the bounds of the array. This can lead to undefined behavior and memory corruption.
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
// Uncommenting the following line will cause overflow
// printf("%d\n", arr[5]);
return 0;
}
Strings in C are represented as arrays of characters. A string variable is simply an array of characters that ends with a null terminator.
#include <stdio.h>
int main() {
char str[50] = "Hello, World!";
printf("%s\n", str);
return 0;
}
You can read and write strings using standard input/output functions like scanf
and printf
.
#include <stdio.h>
int main() {
char str[50];
printf("Enter a string: ");
scanf("%49s", str); // Limit input to prevent overflow
printf("You entered: %s\n", str);
return 0;
}
C provides several functions to manipulate strings, such as strlen
, strcpy
, strcat
, and strcmp
.
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
strcat(str1, str2); // Concatenates str2 to str1
printf("Concatenated string: %s\n", str1);
return 0;
}
Functions are declared using a specific syntax that includes the return type, function name, and parameters.
#include <stdio.h>
// Function declaration
int add(int a, int b);
int main() {
int result = add(5, 10);
printf("Sum: %d\n", result);
return 0;
}
int add(int a, int b) {
return a + b;
}
A function is called by its name followed by parentheses containing any arguments.
#include <stdio.h>
// Function declaration
void greet();
int main() {
greet(); // Calling the function
return 0;
}
void greet() {
printf("Hello, World!\n");
}
Functions provide several benefits including:
Variables declared within a function are local to that function and cannot be accessed outside it. They are created when the function is called and destroyed when it exits.
#include <stdio.h>
void demo() {
int localVar = 5; // Local variable
printf("Local variable: %d\n", localVar);
}
int main() {
demo();
// printf("%d", localVar); // Error: localVar not accessible here
return 0;
}
You can pass arguments to functions either by value or by reference. Passing by value means a copy of the variable is sent, while passing by reference means the function can modify the original variable.
#include <stdio.h>
void byValue(int x) {
x = x + 10; // Modifies local copy
}
void byReference(int *x) {
*x = *x + 10; // Modifies original value
}
int main() {
int a = 5;
byValue(a);
printf("By value: %d\n", a); // Output: 5
byReference(&a);
printf("By reference: %d\n", a); // Output: 15
return 0;
}
Functions can be called from within other functions, creating a nested structure. However, C does not support function nesting directly; you must define functions separately.
#include <stdio.h>
void functionA() {
printf("Function A called\n");
}
void functionB() {
printf("Function B called\n");
functionA(); // Calling function A from B
}
int main() {
functionB();
return 0;
}
Arrays can be passed to functions by providing the array name. Inside the function, the array can be accessed as a pointer.
#include <stdio.h>
void printArray(int arr[], int size) {
for(int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
printArray(numbers, 5);
return 0;
}
Recursion is a programming technique where a function calls itself to solve a problem. It consists of a base case that stops the recursion and a recursive case that continues the recursion.
#include <stdio.h>
// Recursive function to calculate factorial
int factorial(int n) {
if (n == 0) // Base case
return 1;
else // Recursive case
return n * factorial(n - 1);
}
int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}
In C, functions can receive parameters by value or by reference. In "call by value," a copy of the actual parameter is passed to the function. In "call by reference," the address of the actual parameter is passed, allowing the function to modify the original value.
#include <stdio.h>
// Function that demonstrates call by value
void increment(int x) {
x++;
printf("Inside increment (call by value): %d\n", x);
}
int main() {
int num = 10;
increment(num);
printf("After increment (in main): %d\n", num);
return 0;
}
#include <stdio.h>
// Function that demonstrates call by reference
void increment(int *x) {
(*x)++;
printf("Inside increment (call by reference): %d\n", *x);
}
int main() {
int num = 10;
increment(&num);
printf("After increment (in main): %d\n", num);
return 0;
}
Pointers can be passed to functions, allowing the function to modify the original data. This is particularly useful for working with large data structures without making copies.
#include <stdio.h>
// Function that modifies the value using a pointer
void modifyValue(int *x) {
*x = 20;
}
int main() {
int num = 10;
modifyValue(&num);
printf("Modified value: %d\n", num);
return 0;
}
An array of pointers is an array where each element is a pointer. This can be useful for dynamic memory allocation and managing arrays of strings.
#include <stdio.h>
int main() {
const char *fruits[] = {"Apple", "Banana", "Cherry"}; // Array of pointers
for (int i = 0; i < 3; i++) {
printf("%s\n", fruits[i]); // Accessing strings via pointers
}
return 0;
}
Strings in C are represented as arrays of characters terminated by a null character (`'\0'`). A pointer can be used to manipulate strings efficiently.
#include <stdio.h>
int main() {
char str[] = "Hello, World!";
char *ptr = str; // Pointer to the string
while (*ptr) { // Iterate through the string
putchar(*ptr++);
}
putchar('\n');
return 0;
}
Structures in C allow you to group related variables. A pointer to a structure can be used to access and modify the structure's members.
#include <stdio.h>
struct Student {
char name[50];
int age;
};
int main() {
struct Student student = {"Alice", 20};
struct Student *ptr = &student; // Pointer to structure
printf("Name: %s, Age: %d\n", ptr->name, ptr->age);
return 0;
}
Structures can contain pointers as members. This allows for dynamic data structures such as linked lists.
#include <stdio.h>
struct Node {
int data;
struct Node *next; // Pointer to the next node
};
int main() {
struct Node node1;
struct Node node2;
node1.data = 10;
node1.next = &node2; // Linking nodes
node2.data = 20;
node2.next = NULL;
printf("Node1: %d, Node2: %d\n", node1.data, node1.next->data);
return 0;
}
Static memory allocation is done at compile time, while dynamic memory allocation is done at runtime using functions like `malloc`, `calloc`, `realloc`, and `free`.
#include <stdio.h>
int main() {
int arr[5]; // Static allocation
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
DMA allows you to allocate memory at runtime. It is particularly useful when the size of data is not known at compile time. `malloc` allocates uninitialized memory, while `calloc` allocates memory and initializes it to zero.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(5 * sizeof(int)); // Allocate memory
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
printf("%d ", arr[i]);
}
free(arr); // Free allocated memory
printf("\n");
return 0;
}
The most common DMA functions in C are:
malloc(size_t size)
: Allocates a specified number of bytes.calloc(size_t num, size_t size)
: Allocates memory for an array of elements, initializes all bytes to zero.realloc(void *ptr, size_t size)
: Changes the size of previously allocated memory.free(void *ptr)
: Deallocates previously allocated memory.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(5 * sizeof(int));
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
// Reallocate memory to hold 10 integers
arr = (int *)realloc(arr, 10 * sizeof(int));
for (int i = 5; i < 10; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
free(arr);
printf("\n");
return 0;
}
The malloc()
function is used to allocate a specified amount of memory at runtime. It returns a pointer to the beginning of the allocated memory block. If the allocation fails, it returns NULL
.
#include
#include
int main() {
int *arr;
int n = 5;
arr = (int *)malloc(n * sizeof(int)); // Allocating memory for 5 integers
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
for (int i = 0; i < n; i++) {
arr[i] = i + 1; // Initializing array elements
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
free(arr); // Freeing allocated memory
return 0;
}
The sizeof
operator is used to determine the size, in bytes, of a data type or a variable. It can be used with both built-in and user-defined data types.
#include
struct MyStruct {
int a;
double b;
};
int main() {
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of double: %zu bytes\n", sizeof(double));
printf("Size of MyStruct: %zu bytes\n", sizeof(struct MyStruct));
return 0;
}
A structure in C is a user-defined data type that allows the grouping of variables of different data types under a single name. Structures are defined using the struct
keyword.
#include
struct Student {
char name[50];
int roll_no;
float marks;
};
After defining a structure, you can declare variables of that structure type. This is done after the structure definition.
#include
struct Student {
char name[50];
int roll_no;
float marks;
};
int main() {
struct Student s1; // Declaration of a structure variable
return 0;
}
Structures can be initialized at the time of declaration using an initializer list. This sets the values of the structure members.
#include
struct Student {
char name[50];
int roll_no;
float marks;
};
int main() {
struct Student s1 = {"Alice", 101, 89.5}; // Initialization
printf("Name: %s, Roll No: %d, Marks: %.2f\n", s1.name, s1.roll_no, s1.marks);
return 0;
}
Structure members can be accessed using the dot operator (.
) for structure variables and the arrow operator (->
) for pointers to structures.
#include
struct Student {
char name[50];
int roll_no;
float marks;
};
int main() {
struct Student s1 = {"Bob", 102, 76.5};
printf("Name: %s\n", s1.name); // Accessing member using dot operator
struct Student *ptr = &s1;
printf("Roll No: %d\n", ptr->roll_no); // Accessing member using arrow operator
return 0;
}
A structure can contain another structure as a member. This is called a nested structure.
#include
struct Address {
char street[100];
char city[50];
};
struct Student {
char name[50];
int roll_no;
struct Address addr; // Nested structure
};
int main() {
struct Student s1 = {"Charlie", 103, {"123 Main St", "Springfield"}};
printf("Name: %s, City: %s\n", s1.name, s1.addr.city);
return 0;
}
Structures can contain arrays as members, allowing for the storage of multiple values of the same type.
#include
struct Student {
char name[50];
int grades[5]; // Array of grades
};
int main() {
struct Student s1 = {"David", {85, 90, 78, 92, 88}};
printf("Grades of %s: ", s1.name);
for (int i = 0; i < 5; i++) {
printf("%d ", s1.grades[i]);
}
return 0;
}
Structures can have pointer members, allowing for dynamic memory allocation and efficient data management.
#include
#include
struct Student {
char *name; // Pointer to char
int roll_no;
};
int main() {
struct Student s1;
s1.name = (char *)malloc(50 * sizeof(char)); // Dynamic allocation for name
snprintf(s1.name, 50, "Eve");
s1.roll_no = 104;
printf("Name: %s, Roll No: %d\n", s1.name, s1.roll_no);
free(s1.name); // Free allocated memory
return 0;
}
A union is a user-defined data type that allows storing different data types in the same memory location. Only one member can store a value at any time.
#include
union Data {
int intVal;
float floatVal;
char charVal;
};
After defining a union, you can declare variables of that union type similarly to structures.
#include
union Data {
int intVal;
float floatVal;
char charVal;
};
int main() {
union Data data; // Declaration of a union variable
return 0;
}
Unions can be initialized at the time of declaration using an initializer list, similar to structures.
#include
union Data {
int intVal;
float floatVal;
char charVal;
};
int main() {
union Data data = {10}; // Initialization
printf("Integer: %d\n", data.intVal);
return 0;
}
Union members can be accessed using the dot operator (.
). However, only one member can be used at a time, as they share the same memory location.
#include
union Data {
int intVal;
float floatVal;
char charVal;
};
int main() {
union Data data;
data.intVal = 10;
printf("Integer: %d\n", data.intVal);
data.floatVal = 15.5; // Assigning to another member
printf("Float: %.2f\n", data.floatVal); // Previous value is overwritten
return 0;
}
The primary difference between structures and unions is that in a structure, each member has its own memory, while in a union, all members share the same memory. Thus, a structure can store multiple values simultaneously, whereas a union can only store one value at a time.
#include
struct MyStruct {
int a;
float b;
};
union MyUnion {
int a;
float b;
};
int main() {
printf("Size of MyStruct: %zu bytes\n", sizeof(struct MyStruct)); // Outputs size of struct
printf("Size of MyUnion: %zu bytes\n", sizeof(union MyUnion)); // Outputs size of union
return 0;
}
In C, file structure refers to the organization of data in files. C provides functions for file handling through the FILE
structure. You can open, read, write, and close files using these functions.
#include
int main() {
FILE *file;
file = fopen("example.txt", "w"); // Opening a file in write mode
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
fprintf(file, "Hello, World!\n"); // Writing to the file
fclose(file); // Closing the file
return 0;
}
In C, file mode refers to the way a file is opened and how the data in it will be accessed. There are several modes available for opening files:
To open a file, you use the fopen()
function, which takes two arguments: the filename and the mode. It returns a pointer to a FILE
object.
#include
int main() {
FILE *file;
file = fopen("example.txt", "r"); // Open for reading
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
fclose(file); // Close the file
return 0;
}
You can create a new file or overwrite an existing file by using the w
mode with fopen()
. If the file already exists, its contents will be erased.
#include
int main() {
FILE *file;
file = fopen("newfile.txt", "w"); // Create or overwrite a file
if (file == NULL) {
printf("Error creating file\n");
return 1;
}
fprintf(file, "This is a new file.\n");
fclose(file); // Close the file
return 0;
}
To read from a file, use fgets()
for strings or fscanf()
for formatted input. Remember to check for errors.
#include
int main() {
FILE *file;
char buffer[100];
file = fopen("example.txt", "r"); // Open for reading
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer); // Print each line
}
fclose(file); // Close the file
return 0;
}
To write to a file, you can use fprintf()
for formatted output or fputs()
for strings. Ensure the file is opened in a mode that allows writing.
#include
int main() {
FILE *file;
file = fopen("output.txt", "w"); // Open for writing
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
fprintf(file, "Hello, World!\n"); // Write formatted text
fputs("Writing to a file using fputs.\n", file); // Write string
fclose(file); // Close the file
return 0;
}
After finishing file operations, it is crucial to close the file using fclose()
. This flushes buffers and frees up resources.
#include
int main() {
FILE *file;
file = fopen("example.txt", "w");
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
// File operations here...
fclose(file); // Close the file
printf("File closed successfully.\n");
return 0;
}
To perform random access in files, use fseek()
to move the file pointer to a specific location. This allows you to read/write data at any position in the file.
#include
int main() {
FILE *file;
file = fopen("random_access.txt", "w+"); // Open for read/write
if (file == NULL) {
printf("Error opening file\n");
return 1;
}
fprintf(file, "Hello, Random Access!\n");
fseek(file, 0, SEEK_SET); // Move to the beginning
char buffer[50];
fgets(buffer, sizeof(buffer), file); // Read from the file
printf("%s", buffer); // Print content
fclose(file); // Close the file
return 0;
}
You can copy the contents of one file to another by reading from the source file and writing to the destination file.
#include
int main() {
FILE *source, *dest;
char buffer[100];
source = fopen("source.txt", "r");
dest = fopen("copy.txt", "w");
if (source == NULL || dest == NULL) {
printf("Error opening files\n");
return 1;
}
while (fgets(buffer, sizeof(buffer), source) != NULL) {
fputs(buffer, dest); // Write to destination file
}
fclose(source);
fclose(dest);
printf("File copied successfully.\n");
return 0;
}
Proper error handling is essential when working with files. Check the return value of fopen()
, fgets()
, etc., to ensure operations succeed.
#include
int main() {
FILE *file;
file = fopen("nonexistent.txt", "r"); // Attempt to open a non-existent file
if (file == NULL) {
perror("Error opening file"); // Print error message
return 1;
}
fclose(file); // Close the file if opened successfully
return 0;
}
C programs can accept command line arguments which are passed when executing the program. They are accessible via argc
(argument count) and argv
(argument vector).
#include
int main(int argc, char *argv[]) {
printf("Number of arguments: %d\n", argc);
for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
return 0;
}
Preprocessor directives are instructions processed before compilation. They begin with a #
and are used for including files, defining macros, and conditional compilation.
#include
#define PI 3.14 // Define a macro
int main() {
printf("Value of PI: %f\n", PI);
return 0;
}
Macros are a way to define constants or functions that are expanded at compile time. They can improve code readability and reduce redundancy.
#include
#define SQUARE(x) ((x) * (x)) // Macro for square
int main() {
int num = 5;
printf("Square of %d: %d\n", num, SQUARE(num));
return 0;
}