Fundamentals of C Programming: Data Structures, Memory, and File Handling

Defining Array Types: Array Structure and Union

An array is a data structure that stores a collection of similar data types in contiguous memory locations, where each element can be accessed individually using a unique index (also called a subscript), typically starting from 0. Essentially, it’s a list of values of the same type stored together.

Types of Arrays

  • One-dimensional array: A simple linear list of elements, accessed using a single index.
  • Two-dimensional array: Represents data in rows and columns, accessed using two indices (one for the row, one for the column).
  • Multi-dimensional array: A nested structure of arrays, where each element can be accessed using multiple indices.

A union is a user-defined data type that allows the storage of heterogeneous elements in the same memory location. The size of the union is the size of the largest element in the union.

Functions, Pointers, Call by Value, Call by Reference, Dynamic Memory Allocation, and Data Types

Function

A function is a block of organized, reusable code that performs a specific task. It takes input (arguments), processes it, and optionally returns a value. Functions help in breaking down complex problems into smaller, manageable parts, making code more modular, readable, and maintainable.

Pointer

A pointer is a variable that stores the memory address of another variable. Pointers are primarily used in languages like C and C++ to directly manipulate memory locations. They allow efficient access to data structures and enable functions to modify variables passed as arguments.

Call by Value

In call by value, a copy of the argument’s value is passed to the function. Any changes made to the parameter inside the function do not affect the original argument. This is the default behavior for most programming languages.

Call by Reference

In call by reference, the memory address of the argument is passed to the function. This allows the function to directly access and modify the original variable. In C++, you can use references (&) to implement call by reference.

File Handling in C

File handling in C refers to the process of working with files, which includes:

  • Creating new files: Generating a new file on the system.
  • Opening existing files: Accessing an existing file for reading or writing.
  • Reading data from files: Extracting information stored within a file.
  • Writing data to files: Storing information in a file.
  • Closing files: Releasing the file from the program’s control.

Text Files

A text file contains data in the form of ASCII characters and is generally used to store a stream of characters. Each line in a text file ends with a new line character (‘\n’). It can be read or written by any text editor. They are generally stored with the .txt file extension. Text files can also be used to store the source code.

Binary Files

A binary file contains data in binary form (i.e., 0’s and 1’s) instead of ASCII characters. They contain data that is stored in a similar manner to how it is stored in the main memory. The binary files can be created only from within a program, and their contents can only be read by a program. They are more secure as they are not easily readable. They are generally stored with the .bin file extension.

Generations of Computers: Technology and Advancements

Computer technology is divided into generations based on the evolving hardware and software. Each generation has brought about new advancements in the field of computing.

  • First Generation (1940s-1950s)

    Technology: Vacuum tubes

    Advancements: Large computers with limited storage and processing speed

  • Second Generation (1950s-1960s)

    Technology: Transistors

    Advancements: Computers became smaller, faster, and more reliable

  • Third Generation (1960s-1970s)

    Technology: Integrated circuits (ICs)

    Advancements: Computers became even smaller, faster, and more affordable

  • Fourth Generation (1970s-Present)

    Technology: Microprocessors

    Advancements: Personal computers, the internet, and networking became widely used

  • Fifth Generation (Present and Beyond)

    Technology: Artificial intelligence (AI)

    Advancements: AI, cloud computing, and IoT advanced computing

Enum Data Types in C

In C, an “enum” (enumeration) data type is a user-defined data type that allows you to create a set of named integer constants, essentially assigning meaningful names to specific integer values. This makes your code more readable and maintainable by providing context to the numbers used in your program. It’s a way to define a fixed set of possible values for a variable with descriptive names instead of raw integer values.

Components of a Computer

There are basically three important components of a computer:

  • Input Unit
  • Central Processing Unit (CPU)
  • Output Unit

Input Unit

The input unit consists of input devices that are attached to the computer. These devices take input and convert it into binary language that the computer understands. Some of the common input devices are keyboard, mouse, joystick, scanner, etc. The Input Unit is formed by attaching one or more input devices to a computer. A user inputs data and instructions through input devices such as a keyboard, mouse, etc. The input unit is used to provide data to the processor for further processing.

Central Processing Unit (CPU)

Once the information is entered into the computer by the input device, the processor processes it. The CPU is called the brain of the computer because it is the control center of the computer. It first fetches instructions from memory and then interprets them so as to know what is to be done. If required, data is fetched from memory or input device. Thereafter, the CPU executes or performs the required computation and then either stores the output or displays it on the output device. The CPU has three main components, which are responsible for different functions:

  • Arithmetic Logic Unit (ALU)
  • Control Unit (CU)
  • Memory registers

Output Unit

The output unit consists of output devices that are attached to the computer. It converts the binary data coming from the CPU to a human-understandable form. The common output devices are monitor, printer, plotter, etc. The output unit displays or prints the processed data in a user-friendly format. The output unit is formed by attaching the output devices of a computer. The output unit accepts the information from the CPU and displays it in a user-readable form.

Flowcharts and Algorithms

The word Algorithm means “a process or set of rules to be followed in calculations or other problem-solving operations”. Therefore, an algorithm refers to a set of rules/instructions that step-by-step define how a work is to be executed in order to get the expected results. Let’s take a look at an example for a better understanding. As a programmer, we are all aware of the Linear Search program.

A flowchart is a graphical representation of an algorithm. Programmers often use it as a program-planning tool to solve a problem. It makes use of symbols that are connected among them to indicate the flow of information and processing. The process of drawing a flowchart for an algorithm is known as “flowcharting”.

Example: Draw a flowchart to input two numbers from the user and display the largest of two numbers.

Flowchart to Print First 32 Odd and Even Numbers

Start
|
——————-
| |
Initialize Initialize
i=1 j=2
countOdd=0 countEven=0
|
——————-
| |
Is countOdd < 32? Is countEven < 32?
| |
Yes Yes
| |
Print i Print j
| |
Increment i=i+2 Increment j=j+2
| |
Increment Increment
countOdd=countOdd+1 countEven=countEven+1
| |
No No
| |
End

Function Declaration and Uses

Function Declaration

A function declaration, also known as a function prototype, tells the compiler about a function’s name, return type, and parameters before its actual definition.

Syntax for a function declaration:

return_type function_name(parameter_type1 parameter1, parameter_type2 parameter2, ...);

Example function declaration:

int calculateArea(int length, int width);

Uses of Functions

  • Code Reusability: Functions allow you to write a block of code once and call it multiple times throughout your program, avoiding repetitive code.
  • Modularity: Breaking down complex tasks into smaller, manageable functions improves code organization and readability.
  • Abstraction: Functions hide implementation details, allowing you to focus on the overall functionality by simply calling the function with the necessary input.
  • Encapsulation: Grouping related operations within a function helps to maintain data integrity and control access to variables.

Example of how to use a function:

#include <stdio.h>

int calculateArea(int length, int width) {
    return length * width;
}

int main() {
    int area = calculateArea(5, 3); // Call the function with values
    printf("Area: %d\n", area);
    return 0;
}

Pointer Declaration

Pointer Declaration: To declare a pointer, we use the (*) dereference operator before its name. In pointer declaration, we only declare the pointer but do not initialize it.

Pointer Initialization: Pointer initialization is the process where we assign some initial value to the pointer variable. We use the (&) address-of operator to get the memory address of a variable and then store it in the pointer variable.

Pointer Dereferencing: Dereferencing a pointer is the process of accessing the value stored in the memory address specified in the pointer. We use the same (*) dereferencing operator that we used in the pointer declaration.

C Program to Transpose a 3×4 Matrix

#include <stdio.h>

#define ROWS 3
#define COLS 4

int main() {
    int matrix[ROWS][COLS] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    int transpose[COLS][ROWS];

    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            transpose[j][i] = matrix[i][j];
        }
    }

    printf("Original Matrix:\n");
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    printf("\nTransposed Matrix:\n");
    for (int i = 0; i < COLS; i++) {
        for (int j = 0; j < ROWS; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }

    return 0;
}

C Program to Transpose a 4×4 Matrix

#include <stdio.h>

#define SIZE 4

int main() {
    int matrix[SIZE][SIZE] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };

    int transpose[SIZE][SIZE];

    // Transposing the matrix
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            transpose[j][i] = matrix[i][j];
        }
    }

    // Printing the original matrix
    printf("Original Matrix:\n");
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // Printing the transposed matrix
    printf("\nTransposed Matrix:\n");
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }

    return 0;
}

C Program to Transpose a 2×4 Matrix

#include <stdio.h>

#define ROWS 2
#define COLS 4

int main() {
    int matrix[ROWS][COLS] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8}
    };

    int transpose[COLS][ROWS];

    // Transposing the matrix
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            transpose[j][i] = matrix[i][j];
        }
    }

    // Printing the original matrix
    printf("Original Matrix:\n");
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // Printing the transposed matrix
    printf("\nTransposed Matrix:\n");
    for (int i = 0; i < COLS; i++) {
        for (int j = 0; j < ROWS; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }

    return 0;
}

C Program to Calculate Average Marks of 50 Students

#include <stdio.h>

int main() {
    int marks[50];
    int sum = 0;
    float average;

    // Input marks for 50 students
    for (int i = 0; i < 50; i++) {
        printf("Enter marks for student %d: ", i + 1);
        scanf("%d", &marks[i]);
        sum += marks[i];
    }

    // Calculate average
    average = sum / 50.0;

    // Print the average
    printf("The average marks of the class is: %.2f\n", average);

    return 0;
}

C Program to Print Multiples of 5 from 1 to 100

#include <stdio.h>

int main() {
    // Loop through numbers from 1 to 100
    for (int i = 1; i <= 100; i++) {
        // Check if the number is a multiple of 5
        if (i % 5 == 0) {
            printf("%d\n", i);
        }
    }

    return 0;
}