Concepts of Two-Dimensional Numeric Array in C.

 

Introduction.

  • A two-dimensional numeric array in C programming is a structured collection of elements stored in a tabular form consisting of rows and columns.
  • It is widely used to organize numerical data efficiently and enables easy access to elements using row and column indices.
  • In C, a 2D numeric array is beneficial for applications such as matrix operations, data storage, game development, image processing, and numerical computations.

Declaration of a Two-Dimensional Numeric Array in C

A 2D array is declared using the following syntax:

Understanding Two-Dimensional Arrays.

A two-dimensional (2D) array consists of multiple rows and columns, forming a rectangular structure. Each element in the array is identified using two indices:
  • First index (row index): Represents the row number
  • Second index (column index): Represents the column number
Syntax for Declaring a Two-Dimensional Numeric Array.
data_type array_name[rows][columns];
  • data_type → Specifies the type of elements (e.g., int, float, double).
  • array_name → Name of the array.
  • rows → The number of rows in the array.
  • columns → The number of columns in the array.

Declaring a Two-Dimensional Numeric Array

Here are some examples of declaring a 2D numeric array:
Example 1: Declaring a 2D Integer Array.
int numbers[3][4]; // A 3×4 integer array (3 rows and 4 columns)
This declaration creates an integer array with 3 rows and 4 columns. The memory allocation follows a row-major order.
Example 2: Declaring a 2D Floating-Point Array.
float prices[2][5]; // A 2×5 floating-point array.
This array can store 2 rows and 5 columns of floating-point numbers.

 

3. Initializing a Two-Dimensional Numeric Array

A two-dimensional array can be initialized at the time of declaration in multiple ways.
  • Method 1: Explicit Initialization
  • int matrix[2][3] = {{1, 2, 3},{4, 5, 6}};
Here .
  • matrix[0][0] = 1, matrix[0][1] = 2, matrix[0][2] = 3
  • matrix[1][0] = 4, matrix[1][1] = 5, matrix[1][2] = 6
Method 2: Implicit Initialization.
  • int matrix[][3] = {
    {7, 8, 9},
    {10, 11, 12}
    };
  • Here, the compiler automatically determines the number of rows
Method 3: Partial Initialization.
  • int matrix[2][3] = {1, 2, 3};
  • The first row is initialized with {1, 2, 3}
  • The second row will be filled with zeros {0, 0, 0} (default initialization)
4. Accessing Elements in a 2D Array.
  • Each element in a 2D array can be accessed using row and column indices.
  • #include <stdio.h>
    int main() {
    int matrix[2][2] = {
    {10, 20},
    {30, 40}
    };
    // Accessing elements using indices
    printf(“Element at (0,0): %d\n”, matrix[0][0]); // Output: 10
    printf(“Element at (1,1): %d\n”, matrix[1][1]); // Output: 40
    return 0;
    }
5. Traversing a Two-Dimensional Array. 
  • To process all elements in a 2D array, nested loops are used.
  • Example: Traversing a 2D Array
  • #include <stdio.h>
    int main() {
    int numbers[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    };
    // Using nested loops to print elements
    for (int i = 0; i < 3; i++) { // Loop through rows
    for (int j = 0; j < 3; j++) { // Loop through columns
    printf(“%d “, numbers[i][j]); // Print element
    }
    printf(“\n”); // New line after each row
    }
    return 0;
    }
6. Memory Representation of a Two-Dimensional Array.
  • In C, 2D arrays are stored in row-major order. This means elements are stored row by row in contiguous memory locations.
  • int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
    };
7. Taking User Input for a 2D Array.
  • A 2D array can also be filled using user input.
  • Example: Taking Input from the User
  • #include <stdio.h>
    int main() {
    int matrix[2][2];
    // Taking input from the user
    printf(“Enter 4 elements:\n”);
    for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
    scanf(“%d”, &matrix[i][j]);
    }
    }
    // Displaying the elements
    printf(“The matrix is:\n”);
    for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
    printf(“%d “, matrix[i][j]);
    }
    printf(“\n”);
    }
    return 0;
    }
8. Advantages of Using Two-Dimensional Arrays
  • Efficient storage for tabular data (e.g., matrices, grids, tables).
  • Easy to traverse using nested loops.
  • Fast access using indexed addressing.
  • Better memory organization compared to multiple single-dimensional arrays.
9. Limitations of Two-Dimensional Arrays.
  • Fixed size: The size must be known at compile-time.
  • Inefficient for large datasets: Large 2D arrays consume significant memory.
  • No built-in dynamic resizing: Requires manual memory allocation using pointers (malloc/free).
10. Conclusion.
  • A two-dimensional numeric array in C is a fundamental data structure used for representing matrices, grids, and tables.
  • It is declared using data type, row size, and column size, and can be initialized statically or dynamically.
  • Efficient memory representation and traversal using nested loops make 2D arrays a powerful tool in C programming.

Two-Dimensional Numeric Array Operations in C.

  • A two-dimensional (2D) numeric array in C is widely used for mathematical and computational tasks, especially when dealing with matrices.
  • Some of the fundamental operations performed on 2D arrays include Addition, Subtraction, Multiplication, and Transpose.

1. Matrix Addition.

  • Matrix addition is performed by adding corresponding elements of two matrices.
  • If A and B are two matrices of the same size (m × n), the result matrix C is given by:
  • C[i][j]=A[i][j]+B[i][j]
  • where i represents row index and j represents column index.
  • C Program for Matrix Addition
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 3
    int main() {
    int A[ROWS][COLS] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    };
    int B[ROWS][COLS] = {
    {9, 8, 7},
    {6, 5, 4},
    {3, 2, 1}
    };
    int C[ROWS][COLS]; // Resultant matrix
    // Performing matrix addition
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    C[i][j] = A[i][j] + B[i][j];
    }
    }
    // Displaying the result
    printf(“Resultant Matrix (Addition):\n”);
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    printf(“%d “, C[i][j]);
    }
    printf(“\n”);
    }
    return 0;
    }

2. Matrix Subtraction.

  • Matrix subtraction is performed by subtracting corresponding elements of two matrices. If A and B are two matrices of the same size (m × n), the result matrix C is given by:
  • C[i][j]=A[i][j]B[i][j]
  • C Program for Matrix Subtraction
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 3
    int main() {
    int A[ROWS][COLS] = {
    {10, 9, 8},
    {7, 6, 5},
    {4, 3, 2}
    };
    int B[ROWS][COLS] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    };
    int C[ROWS][COLS]; // Resultant matrix
    // Performing matrix subtraction
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    C[i][j] = A[i][j] – B[i][j];
    }
    }
    // Displaying the result
    printf(“Resultant Matrix (Subtraction):\n”);
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    printf(“%d “, C[i][j]);
    }
    printf(“\n”);
    }
    return 0;
    }

3. Matrix Multiplication.

  • Matrix multiplication involves dot product between rows of the first matrix and columns of the second matrix.
  • If A is of size (m × n) and B is of size (n × p), then the resultant matrix C will have size (m × p) and is computed as:
  • C[i][j]=k=0n1A[i][k]×B[k][j]
  • where k iterates over the elements of the row in matrix A and the column in matrix B.
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 3
    int main() {
    int A[ROWS][COLS] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    };
    int B[ROWS][COLS] = {
    {9, 8, 7},
    {6, 5, 4},
    {3, 2, 1}
    };
    int C[ROWS][COLS] = {0}; // Initialize to zero
    // Performing matrix multiplication
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    for (int k = 0; k < COLS; k++) {
    C[i][j] += A[i][k] * B[k][j];
    }
    }
    }
    // Displaying the result
    printf(“Resultant Matrix (Multiplication):\n”);
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    printf(“%d “, C[i][j]);
    }
    printf(“\n”);
    }
    return 0;
    }

4. Matrix Transpose.

  • The transpose of a matrix is obtained by swapping rows with columns.
  • If A is an m × n matrix, then its transpose Aᵀ will be an n × m matrix, where:
  • AT[j][i]=A[i][j]
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 3
    int main() {
    int A[ROWS][COLS] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
    };
    int T[COLS][ROWS]; // Transpose matrix
    // Performing matrix transpose
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    T[j][i] = A[i][j];
    }
    }
    // Displaying the result
    printf(“Transpose of the Matrix:\n”);
    for (int i = 0; i < COLS; i++) {
    for (int j = 0; j < ROWS; j++) {
    printf(“%d “, T[i][j]);
    }
    printf(“\n”);
    }
    return 0;
    }

Element Address in a Two-Dimensional Array (Row-Major and Column-Major Order) in C.

  • In C programming, a two-dimensional (2D) array is stored in contiguous memory locations.
  • The way elements are stored in memory depends on the memory layout strategy:
  • Row-Major Order (Used in C)
  • Column-Major Order (Used in some other languages like Fortran)

1. Understanding Memory Layout of 2D Arrays in C.

  • A two-dimensional array in C is declared as:
  • data_type array_name[rows][columns];
  • Each element is stored in a single memory block, and the memory address of an element is calculated based on its position in the array.
  • For example:
  • int A[3][3] = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
    };

2. Row-Major Order (Used in C).

  • In row-major order, the elements of a row are stored contiguously in memory, followed by the next row.
  • For a 2D array A[m][n], the memory layout looks like:
  • A[0][0], A[0][1], A[0][2], …, A[1][0], A[1][1], A[1][2], …, A[m-1][n-1]
  • The first row is stored first.
  • The second row follows immediately in memory.
  • This continues until all rows are stored.
Address Calculation in Row-Major Order
  • The address of an element A[i][j] in row-major order is given by:
  • Address(A[i][j])=Base Address+[(i×Total Columns)+j]×Element Size
Where
  • Base Address = Address of A[0][0]
  • i = Row index
  • j = Column index
  • Total Columns = Number of columns in the array
  • Element Size = Size of one element (in bytes)
  • Example Calculation
  • int A[3][3] = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
    };
  • Assume Base Address = 1000 and int size = 4 bytes.
  • Address of A[1][2] (2nd row, 3rd column) is:

3. Column-Major Order (Used in Fortran, MATLAB).

  • In column-major order, elements are stored column by column, meaning:
  • The first column is stored first.
  • The second column follows immediately in memory.
  • This continues until all columns are stored.
  • For a 2D array A[m][n], the memory layout looks like:
  • A[0][0], A[1][0], A[2][0], …, A[0][1], A[1][1], A[2][1], …, A[m-1][n-1]
  • Address Calculation in Column-Major Order
  • The address of an element A[i][j] in column-major order is given by:
  • Address(A[i][j])=Base Address+[(j×Total Rows)+i]×Element Size
  • where:
    • Base Address = Address of A[0][0]
    • i = Row index
    • j = Column index
    • Total Rows = Number of rows in the array
    • Element Size = Size of one element (in bytes)

4. Row-Major vs Column-Major Order. (Comparison Table)

Order Type Memory Layout Address Calculation Formula
Row-Major Order (C, C++, Java) Rows stored continuously, left to right Base Address + [(i * Total Columns) + j] * Element Size
Column-Major Order (Fortran, MATLAB) Columns stored continuously, top to bottom Base Address + [(j * Total Rows) + i] * Element Size

5. C Program to Demonstrate Address Calculation.

  • The following C program calculates and prints the memory address of each element using row-major order.
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 3
    int main() {
    int A[ROWS][COLS];
    int *base_address = (int *)A; // Get base address
    printf(“Base Address: %p\n”, base_address);
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
    printf(“Address of A[%d][%d]: %p\n”, i, j, (base_address + (i * COLS) + j));
    }
    }
    return 0;
    }

Declaring & Initializing Two-Dimensional Character Arrays in C.

  • A two-dimensional character array in C is often used to store multiple strings or tabular data where each row represents a separate string or set of characters.
  • This type of array is useful for handling text-based data such as names, messages, and sentences.

1. Declaring a Two-Dimensional Character Array.

  • A 2D character array in C is declared using the following syntax:
  • char array_name[rows][columns];
  • rows specify the number of strings (number of rows).
  • columns specify the maximum number of characters in each string (including the null terminator \0).
  • Example: Declaring a 2D Character Array
  • char names[3][10];
  • This declaration creates a 3 × 10 character array, meaning:
  • It can hold 3 strings (3 rows).
  • Each string can have up to 9 characters (last space reserved for \0).

2. Initializing a Two-Dimensional Character Array.

  • There are multiple ways to initialize a 2D character array in C.

A. Initializing at Declaration (Direct Assignment)

  • char names[3][10] = {
    “Alice”,
    “Bob”,
    “Charlie”
    };
  • C automatically adds the null terminator (\0) at the end of each string.
  • All strings must fit within the column size. If a name exceeds 9 characters, it will cause issues.

B. Initializing Using strcpy().

  • The strcpy() function from <string.h> is used to copy strings into a 2D character array dynamically.
  • #include <stdio.h>
    #include <string.h>
    int main() {
    char names[3][10];
    strcpy(names[0], “Alice”);
    strcpy(names[1], “Bob”);
    strcpy(names[2], “Charlie”);
    printf(“Names: %s, %s, %s\n”, names[0], names[1], names[2]);
    return 0;
    }
  • strcpy() ensures null termination (\0) is included.
  • If a string is longer than the column size, strcpy() may cause buffer overflow.

3. Accessing Elements in a 2D Character Array.

  • Each character in a 2D character array can be accessed using row and column indices.
  • #include <stdio.h>
    int main() {
    char names[3][10] = {
    “Alice”,
    “Bob”,
    “Charlie”
    };
    printf(“First letter of first name: %c\n”, names[0][0]);
    printf(“Second letter of second name: %c\n”, names[1][1]);
    printf(“Third letter of third name: %c\n”, names[2][2]);
    return 0;
    }
  • names[0][0] accesses ‘A’ from “Alice”.
  • names[1][1] accesses ‘o’ from “Bob”.
  • names[2][2] accesses ‘a’ from “Charlie”.

4. Inputting Strings into a 2D Character Array.

  • We can use scanf() or gets() to input strings.
  • Using scanf() (with %s)
  • #include <stdio.h>
    int main() {
    char names[3][10];
    printf(“Enter three names:\n”);
    for (int i = 0; i < 3; i++) {
    scanf(“%9s”, names[i]); // Read string (max 9 characters)
    }
    printf(“You entered:\n”);
    for (int i = 0; i < 3; i++) {
    printf(“%s\n”, names[i]);
    }
    return 0;
    }

5. Using Pointers with 2D Character Arrays.

  • Instead of using a fixed-size 2D array, we can use an array of pointers for flexibility.
  • #include <stdio.h>
    int main() {
    char *names[] = {
    “Alice”,
    “Bob”,
    “Charlie”
    };
    printf(“First name: %s\n”, names[0]);
    printf(“Second name: %s\n”, names[1]);
    printf(“Third name: %s\n”, names[2]);
    return 0;
    }
  • Uses less memory because names are stored dynamically.
  • No need to declare column size, since each string has its own memory.

6. Key Differences: Static vs Dynamic 2D Character Arrays.

 
Feature Traditional 2D Array Array of Pointers
Memory Usage Fixed memory for all strings Flexible memory allocation
Size Limitation Requires predefined row & column size No need to specify column size
Efficiency Less efficient if space is wasted More efficient for variable-length strings
Initialization Uses direct assignment or strcpy() Uses string literals

Two-Dimensional Character Array Operations in C,

  • A two-dimensional (2D) character array is often used to store and manipulate multiple strings in C.
  • Some of the common operations performed on 2D character arrays include:
  • Searching an element (character or string)
  • Copying strings
  • Merging strings
  • Finding the length of a given string
  • These operations are essential for text processing, name handling, or working with tabular character data.

1. Searching an Element (Character or String).

(A) Searching for a Character in a 2D Character Array.

  • To search for a specific character in a 2D array, we loop through all rows and columns.
  • Example: Searching for a Character
  • #include <stdio.h>
    #define ROWS 3
    #define COLS 10
    int main() {
    char words[ROWS][COLS] = { “Hello”, “World”, “CProg” };
    char searchChar;
    int found = 0;
    printf(“Enter a character to search: “);
    scanf(” %c”, &searchChar);
    for (int i = 0; i < ROWS; i++) {
    for (int j = 0; words[i][j] != ‘\0’; j++) {
    if (words[i][j] == searchChar) {
    printf(“Character ‘%c’ found at row %d, column %d\n”, searchChar, i, j);
    found = 1;
    }
    }
    }
    if (!found) {
    printf(“Character ‘%c’ not found in array.\n”, searchChar);
    }
    return 0;
    }
  • The program checks each character and prints its position if found.

(B) Searching for a String in a 2D Character Array.

  • To search for a word in a 2D character array, we compare each row with the target string using strcmp().
  • Example: Searching for a String
  • #include <stdio.h>
    #include <string.h>
    #define ROWS 4
    #define COLS 20
    int main() {
    char names[ROWS][COLS] = { “Alice”, “Bob”, “Charlie”, “David” };
    char searchWord[COLS];
    int found = 0;
    printf(“Enter a string to search: “);
    scanf(“%s”, searchWord);
    for (int i = 0; i < ROWS; i++) {
    if (strcmp(names[i], searchWord) == 0) {
    printf(“String ‘%s’ found at row %d\n”, searchWord, i);
    found = 1;
    break;
    }
    }
    if (!found) {
    printf(“String ‘%s’ not found in array.\n”, searchWord);
    }
    return 0;
    }
  • strcmp() is used for string comparison.
  • If a match is found, we print the row index.

2. Copying Strings in a 2D Character Array.

  • To copy one string into another row of a 2D character array, we use strcpy().
  • Example: Copying Strings
  • #include <stdio.h>
    #include <string.h>
    #define ROWS 3
    #define COLS 20
    int main() {
    char names[ROWS][COLS] = { “Alice”, “Bob” };

    // Copy first string to third row
    strcpy(names[2], names[0]);
    printf(“After copying:\n”);
    for (int i = 0; i < ROWS; i++) {
    printf(“%s\n”, names[i]);
    }
    return 0;
    }
  • strcpy(destination, source) copies one row into another.
  • No need to manually loop through characters.

3. Merging (Concatenating) Strings.

  • To merge two strings from different rows, we use strcat().
  • To merge two strings from different rows, we use strcat().
  • Example: Merging Two Strings
  • #include <stdio.h>
    #include <string.h>
    #define ROWS 3
    #define COLS 40
    int main() {
    char names[ROWS][COLS] = { “Hello”, “World” };

    // Merge first and second row into third row
    strcpy(names[2], names[0]); // Copy “Hello”
    strcat(names[2], ” “); // Add space
    strcat(names[2], names[1]); // Append “World”
    printf(“Merged string: %s\n”, names[2]);
    return 0;
    }
  • strcpy() initializes the destination.
  • strcat() appends another string.
  • A space is added manually to separate words.

4. Finding the Length of Strings.

  • We use strlen() to determine the length of each string stored in a 2D character array.
  • Example: Finding String Lengths
  • #include <stdio.h>
    #include <string.h>
    #define ROWS 3
    #define COLS 20
    int main() {
    char words[ROWS][COLS] = { “Programming”, “C Language”, “Code” };
    for (int i = 0; i < ROWS; i++) {
    printf(“Length of ‘%s’: %ld\n”, words[i], strlen(words[i]));
    }
    return 0;
    }
  • strlen() counts characters before the null terminator (\0).
  • Works efficiently without looping manually.

5. Combining All Operations.

  • Here’s a complete program that demonstrates searching, copying, merging, and length finding.
  • #include <stdio.h>
    #include <string.h>
    #define ROWS 3
    #define COLS 40
    int main() {
    char words[ROWS][COLS] = { “Hello”, “World” };
    char searchWord[COLS];
    int found = 0;
    // Search for a string
    printf(“Enter a word to search: “);
    scanf(“%s”, searchWord);

    for (int i = 0; i < ROWS – 1; i++) {
    if (strcmp(words[i], searchWord) == 0) {
    printf(“String ‘%s’ found at row %d\n”, searchWord, i);
    found = 1;
    }
    }
    if (!found) printf(“String not found.\n”);
    // Copy first string to third row
    strcpy(words[2], words[0]);
    printf(“Copied string: %s\n”, words[2]);
    // Merge first and second string
    strcat(words[2], ” “);
    strcat(words[2], words[1]);
    printf(“Merged string: %s\n”, words[2]);
    // Find length of each string
    for (int i = 0; i < ROWS; i++) {
    printf(“Length of ‘%s’: %ld\n”, words[i], strlen(words[i]));
    }
    return 0;
    }
  • Searching: Use strcmp() for full strings and loop for characters.
  • Copying: Use strcpy(destination, source).
  • Merging: Use strcat(destination, source).
  • Finding Length: Use strlen(string).

Concepts of structure and Union.

1. Introduction to Structures and Unions.

  • C provides two important user-defined data types:
  • Structure (struct): A collection of different data types grouped together under a single name.
  • Union (union): Similar to a structure but shares memory among all members, meaning only one member can hold a value at a time.
  • Both structures and unions help organize complex data in a single variable.

2. Structures in C.

  • A structure (struct) is a collection of variables (of different data types) grouped together under a single name.
  • It allows storing multiple pieces of related data in a single entity.

2.1 Defining a Structure.

  • A structure is defined using the struct keyword. The syntax is:
  • struct StructureName {
    data_type member1;
    data_type member2;
    };
  • struct Student {
    int rollNo;
    char name[50];
    float marks;
    };
  • rollNo → Integer (stores roll number).
  • name → Character array (stores name).
  • marks → Float (stores marks).

2.2 Declaring a Structure Variable.

  • Once defined, we can declare variables of the structure type.
  • struct Student s1, s2;
  • This declares two structure variables s1 and s2 of type Student.
  • struct Student {
    int rollNo;
    char name[50];
    float marks;
    } s1, s2;

2.3 Initializing a Structure.

  • Structures can be initialized at the time of declaration.
  • struct Student s1 = {101, “Alice”, 89.5};
  • struct Student s1 = {101, “Alice”, 89.5}, s2 = {102, “Bob”, 75.0};
  • struct Student s1;
    s1.rollNo = 101;
    strcpy(s1.name, “Alice”);
    s1.marks = 89.5;
  • strcpy() is used to assign strings to character arrays.

2.4 Accessing Structure Members.

  • Use the dot operator (.) to access structure members.
  • #include <stdio.h>
    #include <string.h>
    struct Student {
    int rollNo;
    char name[50];
    float marks;
    };
    int main() {
    struct Student s1;

    s1.rollNo = 101;
    strcpy(s1.name, “Alice”);
    s1.marks = 89.5;
    printf(“Roll No: %d\n”, s1.rollNo);
    printf(“Name: %s\n”, s1.name);
    printf(“Marks: %.2f\n”, s1.marks);
    return 0;
    }

2.5 Structure with Pointers.

  • We can use pointers to access structure members using the arrow operator (->).
  • #include <stdio.h>
    #include <string.h>
    struct Student {
    int rollNo;
    char name[50];
    float marks;
    };
    int main() {
    struct Student s1 = {101, “Alice”, 89.5};
    struct Student *ptr = &s1; // Pointer to structure
    printf(“Roll No: %d\n”, ptr->rollNo);
    printf(“Name: %s\n”, ptr->name);
    printf(“Marks: %.2f\n”, ptr->marks);
    return 0;
    }
  • The -> operator accesses members through a pointer.

3. Unions in C.

  • A union is similar to a structure but shares memory among all its members. Only one member can hold a value at a time.

3.1 Defining a Union.

  • union Data {
    int i;
    float f;
    char str[20];
    };
  • The largest data type decides the memory size.

3.2 Declaring a Union Variable.

  • union Data d1, d2;
  • union Data {
    int i;
    float f;
    char str[20];
    } d1, d2;

3.3 Initializing a Union.

  • union Data d1;
    d1.i = 10; // Assign integer
  • If we assign another value, the previous value gets overwritten.

3.4 Accessing Union Members.

  • #include <stdio.h>
    #include <string.h>

    union Data {
    int i;
    float f;
    char str[20];
    };

    int main() {
    union Data d1;

    d1.i = 10;
    printf(“Integer: %d\n”, d1.i);

    d1.f = 22.5;
    printf(“Float: %.2f\n”, d1.f);

    strcpy(d1.str, “Hello”);
    printf(“String: %s\n”, d1.str);

    return 0;
    }

  • Only the last assigned value is valid, others are lost.

3.5 Union vs Structure.

Feature Structure (struct) Union (union)
Memory Allocation Each member gets separate memory All members share memory
Size Sum of all members’ sizes Size of the largest member
Access All members can store values simultaneously Only one member holds a value at a time
Usage Suitable for complex data storage Useful for memory-efficient data handling

4. Practical Example: Structure vs Union.

  • #include <stdio.h>
    #include <string.h>
    struct Student {
    int rollNo;
    char name[20];
    float marks;
    };
    union Data {
    int i;
    float f;
    char str[20];
    };
    int main() {
    struct Student s1 = {101, “Alice”, 90.5};
    union Data d1;
    printf(“Structure:\n”);
    printf(“Roll No: %d, Name: %s, Marks: %.2f\n”, s1.rollNo, s1.name, s1.marks);
    d1.i = 10;
    printf(“\nUnion:\n”);
    printf(“Integer: %d\n”, d1.i);
    d1.f = 22.5;
    printf(“Float: %.2f\n”, d1.f);
    strcpy(d1.str, “Hello”);
    printf(“String: %s\n”, d1.str);
    return 0;
    }
  • In structures, all values persist.
  • In unions, only the last value remains.

typedef and Accessing Structure Members in C.

1. Introduction to typedef in C.

  • The typedef keyword in C is used to create user-defined data type names, making complex data types more readable and easier to use.
  • It is mainly used with structures, unions, and pointers.
  • It does not create a new data type but provides an alias for an existing type.

2. Using typedef with Structures.

  • Normally, a structure is defined and used like this:
  • #include <stdio.h>
    // Define a structure
    struct Student {
    int rollNo;
    char name[50];
    float marks;
    };
    int main() {
    struct Student s1; // Structure variable declaration
    s1.rollNo = 101;
    printf(“Roll No: %d\n”, s1.rollNo);
    return 0;
    }

2.2 Using typedef with Structures.

  • To simplify structure declaration, we can use typedef:
  • #include <stdio.h>
    // Define structure using typedef
    typedef struct {
    int rollNo;
    char name[50];
    float marks;
    } Student; // Alias name “Student”
    int main() {
    Student s1; // No need to write ‘struct Student’
    s1.rollNo = 101;
    printf(“Roll No: %d\n”, s1.rollNo);
    return 0;
    }

Advantages of using typedef:

  • No need to use struct every time we declare a variable.
  • Improves code readability and convenience.

2.3 Another Example: typedef with Pointer to Structure.

  • We can use typedef with pointers to structures:
  • #include <stdio.h>
    #include <string.h>
    // Define structure with typedef
    typedef struct {
    int rollNo;
    char name[50];
    float marks;
    } Student;
    int main() {
    Student s1 = {101, “Alice”, 90.5}; // Declare structure variable
    Student *ptr = &s1; // Pointer to structure
    printf(“Roll No: %d\n”, ptr->rollNo);
    printf(“Name: %s\n”, ptr->name);
    printf(“Marks: %.2f\n”, ptr->marks);
    return 0;
    }
  • Using -> (arrow operator) with pointers makes access easier.

3. Accessing Structure Members.

3.1 Using the Dot (.) Operator

  • For a normal structure variable, we access members using the dot (.) operator.
  • #include <stdio.h>
    typedef struct {
    int id;
    char name[50];
    } Employee;
    int main() {
    Employee emp1 = {1001, “John Doe”};
    // Access members using dot operator
    printf(“Employee ID: %d\n”, emp1.id);
    printf(“Employee Name: %s\n”, emp1.name);
    return 0;
    }

3.2 Using the Arrow (->) Operator.

  • For structure pointers, we access members using the arrow (->) operator.
  • #include <stdio.h>
    #include <string.h>
    typedef struct {
    int id;
    char name[50];
    } Employee;
    int main() {
    Employee emp1 = {1001, “John Doe”};
    Employee *ptr = &emp1; // Pointer to structure
    // Access members using arrow operator
    printf(“Employee ID: %d\n”, ptr->id);
    printf(“Employee Name: %s\n”, ptr->name);
    return 0;
    }
  • The arrow (->) operator is used to access structure members when using a pointer to a structure.

3.3 Accessing Structure Members Inside an Array.

  • When we use an array of structures, we access members using the dot (.) operator.
  • #include <stdio.h>
    typedef struct {
    int id;
    char name[50];
    } Employee;
    int main() {
    Employee empList[3] = {
    {1001, “John”},
    {1002, “Alice”},
    {1003, “Bob”}
    };
    for (int i = 0; i < 3; i++) {
    printf(“Employee ID: %d, Name: %s\n”, empList[i].id, empList[i].name);
    }
    return 0;
    }
  • Using empList[i].member syntax, we access structure members in an array.

3.4 Nested Structures (Structure within Structure).

  • A structure can have another structure inside it.
  • #include <stdio.h>
    typedef struct {
    int houseNo;
    char city[30];
    } Address;
    typedef struct {
    int id;
    char name[50];
    Address addr; // Nested structure
    } Employee;
    int main() {
    Employee emp1 = {1001, “John Doe”, {123, “New York”}};
    printf(“Employee Name: %s\n”, emp1.name);
    printf(“City: %s\n”, emp1.addr.city); // Accessing nested structure
    return 0;
    }
  • Nested structures allow hierarchical data storage.

3.5 Structure with Dynamic Memory Allocation.

  • We can allocate memory dynamically using malloc() for a structure.
  • #include <stdio.h>
    #include <stdlib.h>
    typedef struct {
    int id;
    char name[50];
    } Employee;
    int main() {
    Employee *ptr = (Employee *)malloc(sizeof(Employee));
    ptr->id = 1001;
    printf(“Enter Name: “);
    scanf(“%s”, ptr->name);
    printf(“Employee ID: %d, Name: %s\n”, ptr->id, ptr->name);
    free(ptr); // Free allocated memory
    return 0;
    }
  • malloc() allocates memory dynamically for a structure.
  • free(ptr) releases memory.

4. Key Differences: typedef vs #define.

Feature typedef #define
Usage Defines a new name for a data type Defines a constant or macro
Type Checking Supports type checking No type checking
Scope Limited to the block where defined Global scope
Example typedef unsigned int uint; #define uint unsigned int

Difference Between Structure and Union in C.

Feature Structure (struct) Union (union)
Memory Allocation Each member gets separate memory space. All members share the same memory space.
Memory Usage Uses more memory as each member has its own storage. Uses less memory since all members share the same space.
Size Calculation Size of structure = Sum of all members’ sizes. Size of union = Size of the largest member.
Access All members can hold values simultaneously. Only one member can hold a value at a time.
Data Loss No data loss, each member retains its value. Data loss occurs when a new member is assigned a value.
Usage Used when we need to store multiple values at once. Used when we need to store only one value at a time to save memory.

User defined functions.

Functions are fundamental building blocks in C programming that allow code modularity, reusability, and better organization. A user-defined function is a function created by the programmer to perform specific tasks.

1.3.1 Function Return Type, Parameter List, and Local Function Variables

Function Return Type
  • Specifies the type of value a function will return.
  • If no value is returned, the return type is void.
  • Example:
int add(int a, int b) { return a + b; }
Parameter List
  • Defines the input values (parameters) a function accepts.
  • If no parameters, the function can be defined as void functionName(void).
  • Example:
void greet(char name[]) { printf("Hello, %s!\n", name); }
Local Function Variables
  • Declared inside a function.
  • Scope is limited to that function.
  • Example:
void display() { int x = 10; // Local variable printf("Value: %d", x); }

1.3.2 Passing Arguments to Functions

Arguments can be passed in two ways:
  1. Call by Value – A copy of the variable is passed. Changes inside the function do not affect the original value.
void square(int num) { num = num * num; printf("Inside function: %d\n", num); } int main() { int a = 5; square(a); printf("Outside function: %d\n", a); return 0; }
Call by Reference – A reference (address) of the variable is passed. Changes inside the function affect the original value.
void square(int *num) { *num = (*num) * (*num); } int main() { int a = 5; square(&a); printf("Updated Value: %d\n", a); return 0; }

1.3.3 Calling a Function from main() or Another Function

Functions can be called:
  1. From main():
void hello() { printf("Hello, World!\n"); } int main() { hello(); // Function call return 0; }
2. From Another Function:
void firstFunction() { printf("This is the first function.\n"); secondFunction(); // Calling another function } void secondFunction() { printf("This is the second function.\n"); } int main() { firstFunction(); return 0; }

1.3.4 Types of Functions Based on Arguments & Return Value

1. Function with No Arguments and No Return Value
void greet() { printf("Hello, Welcome!\n"); } int main() { greet(); return 0; }

2. Function with No Arguments but a Return Value.

int getNumber() { return 10; } int main() { int num = getNumber(); printf("Number: %d\n", num); return 0; }

3. Function with Arguments but No Return Value.

void sum(int a, int b) { printf("Sum: %d\n", a + b); } int main() { sum(4, 6); return 0; }

4. Function with Arguments and a Return Value.

int multiply(int x, int y) { return x * y; } int main() { int result = multiply(3, 5); printf("Multiplication: %d\n", result); return 0; }

1.3.5 Recursive Functions

A recursive function is a function that calls itself to solve a problem.

Example: Factorial Calculation

int factorial(int n) { if (n == 0) return 1; return n * factorial(n - 1); } int main() { int num = 5; printf("Factorial of %d is %d\n", num, factorial(num)); return 0; }

Example: Fibonacci Series

int fibonacci(int n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } int main() { int n = 6; printf("Fibonacci of %d is %d\n", n, fibonacci(n)); return 0; }

Summary Table

Function Type Arguments Return Value Example
No Arguments, No Return No No void greet() {...}
No Arguments, With Return No Yes int getNumber() {...}
With Arguments, No Return Yes No void sum(int a, int b) {...}
With Arguments, With Return Yes Yes int multiply(int x, int y) {...}
Recursive Function Yes Yes int factorial(int n) {...}

Leave a Reply

Your email address will not be published. Required fields are marked *

sign up!

We’ll send you the hottest deals straight to your inbox so you’re always in on the best-kept software secrets.