Advanced C Practice Problem Questions with Solutions

Introduction

Advanced C practice is about combining the concepts you have already learned to solve larger and more realistic problems. In this chapter, you will practice arrays, strings, pointers, structures, functions, recursion, dynamic memory, and file handling together. The questions are designed to move from intermediate problems toward more challenging C programs without jumping into overly complex code. Advanced C Practice Problem questions with solutions to help you understand the concepts.

Q1. Sort an Array Using a Function and Pointers

Problem Statement

Write a C program that accepts numbers into an array and sorts them in ascending order using a function and pointers.

C Program

#include <stdio.h>

void sortArray(int *arr, int size)
{
    int i, j, temp;

    for (i = 0; i < size - 1; i++)
    {
        for (j = 0; j < size - i - 1; j++)
        {
            if (*(arr + j) > *(arr + j + 1))
            {
                temp = *(arr + j);
                *(arr + j) = *(arr + j + 1);
                *(arr + j + 1) = temp;
            }
        }
    }
}

int main()
{
    int numbers[5];
    int i;

    printf("Enter 5 numbers:\n");

    for (i = 0; i < 5; i++)
    {
        scanf("%d", &numbers[i]);
    }

    sortArray(numbers, 5);

    printf("Sorted array: ");

    for (i = 0; i < 5; i++)
    {
        printf("%d ", numbers[i]);
    }

    return 0;
}

Sample Output

Enter 5 numbers:
45 12 78 23 9
Sorted array: 9 12 23 45 78

Explanation

The function receives the address of the first array element:

sortArray(numbers, 5);

Inside the function, pointer arithmetic is used:

*(arr + j)

This accesses the element at index j.

The nested loops compare adjacent elements and exchange them when they are in the wrong order.

Concepts Covered

  • Arrays
  • Functions
  • Pointers
  • Pointer arithmetic
  • Nested loops
  • Sorting

Q2. Find Duplicate Elements in an Array

Problem Statement

Write a C program that finds and displays duplicate elements in an integer array.

C Program

#include <stdio.h>

int main()
{
    int numbers[8];
    int i, j;
    int found = 0;

    printf("Enter 8 numbers:\n");

    for (i = 0; i < 8; i++)
    {
        scanf("%d", &numbers[i]);
    }

    printf("Duplicate elements: ");

    for (i = 0; i < 8; i++)
    {
        for (j = i + 1; j < 8; j++)
        {
            if (numbers[i] == numbers[j])
            {
                printf("%d ", numbers[i]);
                found = 1;
                break;
            }
        }
    }

    if (found == 0)
    {
        printf("No duplicates found.");
    }

    return 0;
}

Sample Output

Enter 8 numbers:
10 20 30 20 40 50 10 60
Duplicate elements: 10 20

Explanation

The outer loop selects one element.

The inner loop compares that element with the elements after it.

For example:

10 → 20 → 30 → 20 → 40 → 50 → 10 → 60

The program finds that 10 and 20 appear more than once.

Concepts Covered

  • Arrays
  • Nested loops
  • Comparison
  • break
  • Duplicate detection

Q3. Check Whether a String Is a Palindrome

Problem Statement

Write a C program that uses a function to check whether a string is a palindrome.

A palindrome reads the same from both directions.

Example:

madam
level
radar

C Program

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

int isPalindrome(char str[])
{
    int start = 0;
    int end = strlen(str) - 1;

    while (start < end)
    {
        if (str[start] != str[end])
        {
            return 0;
        }

        start++;
        end--;
    }

    return 1;
}

int main()
{
    char text[100];

    printf("Enter a string: ");
    scanf("%99s", text);

    if (isPalindrome(text))
    {
        printf("The string is a palindrome.");
    }
    else
    {
        printf("The string is not a palindrome.");
    }

    return 0;
}

Sample Output

Enter a string: madam
The string is a palindrome.

Explanation

Two indexes are used:

start → first character
end   → last character

The program compares:

str[start]

with:

str[end]

If they are different, the string is not a palindrome.

Concepts Covered

  • Strings
  • Functions
  • strlen()
  • while loop
  • Character comparison
  • Return values

Q4. Dynamically Allocate an Array and Find Its Average

Problem Statement

Use malloc() to dynamically create an integer array. Accept the size from the user, store the values, and calculate the average.

C Program

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *numbers;
    int size;
    int i;
    int sum = 0;
    float average;

    printf("Enter array size: ");
    scanf("%d", &size);

    if (size <= 0)
    {
        printf("Invalid array size.");
        return 1;
    }

    numbers = malloc(size * sizeof(int));

    if (numbers == NULL)
    {
        printf("Memory allocation failed.");
        return 1;
    }

    printf("Enter %d numbers:\n", size);

    for (i = 0; i < size; i++)
    {
        scanf("%d", &numbers[i]);
        sum += numbers[i];
    }

    average = (float)sum / size;

    printf("Average = %.2f", average);

    free(numbers);

    return 0;
}

Sample Output

Enter array size: 4
Enter 4 numbers:
10 20 30 40
Average = 25.00

Explanation

Unlike a fixed-size array:

int numbers[10];

dynamic memory allows the size to be decided while the program is running.

Memory is allocated using:

numbers = malloc(size * sizeof(int));

After the memory is no longer needed, it is released:

free(numbers);

Concepts Covered

  • Pointers
  • malloc()
  • free()
  • Arrays
  • Dynamic memory allocation
  • Error checking

Q5. Student Records Using an Array of Structures

Problem Statement

Create a program that stores information about three students using an array of structures and displays the student with the highest marks.

C Program

#include <stdio.h>

struct Student
{
    int rollNumber;
    char name[50];
    float marks;
};

int findTopper(struct Student students[], int size)
{
    int highest = 0;
    int i;

    for (i = 1; i < size; i++)
    {
        if (students[i].marks > students[highest].marks)
        {
            highest = i;
        }
    }

    return highest;
}

int main()
{
    struct Student students[3];
    int i;
    int topper;

    for (i = 0; i < 3; i++)
    {
        printf("Enter student %d details:\n", i + 1);

        printf("Roll Number: ");
        scanf("%d", &students[i].rollNumber);

        printf("Name: ");
        scanf(" %49[^\n]", students[i].name);

        printf("Marks: ");
        scanf("%f", &students[i].marks);

        printf("\n");
    }

    topper = findTopper(students, 3);

    printf("Top Student\n");
    printf("Roll Number: %d\n", students[topper].rollNumber);
    printf("Name: %s\n", students[topper].name);
    printf("Marks: %.2f", students[topper].marks);

    return 0;
}

Sample Output

Enter student 1 details:
Roll Number: 101
Name: Rahul
Marks: 78

Enter student 2 details:
Roll Number: 102
Name: Priya
Marks: 92

Enter student 3 details:
Roll Number: 103
Name: Amit
Marks: 85

Top Student
Roll Number: 102
Name: Priya
Marks: 92.00

Explanation

The program stores multiple students:

struct Student students[3];

The function returns the array index of the student with the highest marks.

Then the program uses that index:

students[topper]

to display the student’s details.

Concepts Covered

  • Structures
  • Array of structures
  • Functions
  • Arrays
  • Strings
  • Searching
  • Loops

Q6. Recursive Factorial with Input Validation

Problem Statement

Write a C program that uses recursion to calculate the factorial of a non-negative integer.

C Program

#include <stdio.h>

unsigned long long factorial(int n)
{
    if (n == 0 || n == 1)
    {
        return 1;
    }

    return n * factorial(n - 1);
}

int main()
{
    int number;

    printf("Enter a non-negative number: ");
    scanf("%d", &number);

    if (number < 0)
    {
        printf("Error: Factorial is not defined for negative numbers.");
    }
    else if (number > 20)
    {
        printf("Number is too large for this example.");
    }
    else
    {
        printf("Factorial = %llu", factorial(number));
    }

    return 0;
}

Sample Output

Enter a non-negative number: 5
Factorial = 120

Explanation

The function calls itself:

factorial(n - 1)

For example:

factorial(5)
    ↓
5 × factorial(4)
    ↓
5 × 4 × factorial(3)
    ↓
5 × 4 × 3 × factorial(2)
    ↓
5 × 4 × 3 × 2 × factorial(1)

When n becomes 1, the recursion stops.

Concepts Covered

  • Recursion
  • Functions
  • Conditional statements
  • Input validation
  • Return values

Q7. Copy a File Using File Handling

Problem Statement

Write a C program that copies the contents of one text file into another file.

C Program

#include <stdio.h>

int main()
{
    FILE *source;
    FILE *destination;
    int ch;

    source = fopen("source.txt", "r");

    if (source == NULL)
    {
        perror("Error opening source file");
        return 1;
    }

    destination = fopen("copy.txt", "w");

    if (destination == NULL)
    {
        perror("Error creating destination file");
        fclose(source);
        return 1;
    }

    while ((ch = fgetc(source)) != EOF)
    {
        fputc(ch, destination);
    }

    fclose(source);
    fclose(destination);

    printf("File copied successfully.");

    return 0;
}

Sample Output

File copied successfully.

Explanation

The source file is opened in read mode:

fopen("source.txt", "r");

The destination file is opened in write mode:

fopen("copy.txt", "w");

Then:

fgetc()

reads one character at a time.

Each character is written using:

fputc()

Finally, both files are closed.

Concepts Covered

  • File handling
  • fopen()
  • fgetc()
  • fputc()
  • fclose()
  • while
  • Error handling

Q8. Swap Two Numbers Using Pointers

Problem Statement

Write a C program that uses pointers and a function to swap two numbers.

C Program

#include <stdio.h>

void swap(int *a, int *b)
{
    int temp;

    temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    int x, y;

    printf("Enter two numbers: ");
    scanf("%d %d", &x, &y);

    printf("Before swapping: x = %d, y = %d\n", x, y);

    swap(&x, &y);

    printf("After swapping: x = %d, y = %d", x, y);

    return 0;
}

Sample Output

Enter two numbers: 10 20
Before swapping: x = 10, y = 20
After swapping: x = 20, y = 10

Explanation

The addresses of x and y are passed:

swap(&x, &y);

Inside the function:

*a

refers to the original x, while:

*b

refers to the original y.

Therefore, the function can modify the original variables.

Concepts Covered

  • Pointers
  • Addresses
  • Dereferencing
  • Functions
  • Call by address

Q9. Employee Record with Dynamic Memory

Problem Statement

Create an employee record using dynamic memory allocation. Accept the employee’s name and salary, then display the information.

C Program

#include <stdio.h>
#include <stdlib.h>

struct Employee
{
    char name[50];
    float salary;
};

int main()
{
    struct Employee *employee;

    employee = malloc(sizeof(struct Employee));

    if (employee == NULL)
    {
        printf("Memory allocation failed.");
        return 1;
    }

    printf("Enter employee name: ");
    scanf(" %49[^\n]", employee->name);

    printf("Enter salary: ");
    scanf("%f", &employee->salary);

    printf("\nEmployee Details\n");
    printf("Name: %s\n", employee->name);
    printf("Salary: %.2f", employee->salary);

    free(employee);

    return 0;
}

Sample Output

Enter employee name: Rahul Sharma
Enter salary: 45000

Employee Details
Name: Rahul Sharma
Salary: 45000.00

Explanation

Memory for one structure is allocated dynamically:

employee = malloc(sizeof(struct Employee));

Because employee is a pointer to a structure, members are accessed using:

employee->name

and:

employee->salary

Finally, the allocated memory is released:

free(employee);

Concepts Covered

  • Structures
  • Structure pointers
  • Dynamic memory
  • malloc()
  • free()
  • Strings

Q10. Mini Contact Management Program

Problem Statement

Create a small contact management program that stores contact names and phone numbers using structures. Allow the user to search for a contact by name.

C Program

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

struct Contact
{
    char name[50];
    char phone[20];
};

int searchContact(struct Contact contacts[], int size, char searchName[])
{
    int i;

    for (i = 0; i < size; i++)
    {
        if (strcmp(contacts[i].name, searchName) == 0)
        {
            return i;
        }
    }

    return -1;
}

int main()
{
    struct Contact contacts[3];
    char searchName[50];
    int position;
    int i;

    for (i = 0; i < 3; i++)
    {
        printf("Enter contact %d name: ", i + 1);
        scanf(" %49[^\n]", contacts[i].name);

        printf("Enter phone number: ");
        scanf(" %19s", contacts[i].phone);
    }

    printf("\nEnter name to search: ");
    scanf(" %49[^\n]", searchName);

    position = searchContact(contacts, 3, searchName);

    if (position != -1)
    {
        printf("\nContact Found\n");
        printf("Name: %s\n", contacts[position].name);
        printf("Phone: %s", contacts[position].phone);
    }
    else
    {
        printf("Contact not found.");
    }

    return 0;
}

Sample Output

Enter contact 1 name: Rahul
Enter phone number: 9876543210
Enter contact 2 name: Priya
Enter phone number: 9876501234
Enter contact 3 name: Amit
Enter phone number: 9876512345

Enter name to search: Priya

Contact Found
Name: Priya
Phone: 9876501234

Explanation

This program combines several concepts.

Each contact contains:

Name
Phone number

The information is stored in an array of structures:

struct Contact contacts[3];

The strcmp() function compares two strings:

strcmp(contacts[i].name, searchName)

If the result is 0, both strings are equal.

The search function returns the position of the matching contact.

Concepts Covered

  • Structures
  • Array of structures
  • Strings
  • strcmp()
  • Functions
  • Searching
  • Loops
  • Conditional statements

Key Takeaways

  • Advanced C programming is mainly about combining previously learned concepts.
  • Functions make large programs easier to organize.
  • Pointers allow functions to work with original data.
  • Arrays are useful for handling collections of values.
  • Structures are useful for representing records.
  • Arrays of structures can store multiple records.
  • Dynamic memory allows memory to be allocated during program execution.
  • Allocated memory should be released with free().
  • Recursion allows a function to solve a problem by calling itself.
  • File handling allows programs to work with persistent data.
  • Error checking is especially important when working with files and dynamic memory.
  • String functions such as strlen() and strcmp() are useful when processing text.
  • Breaking a large problem into smaller functions makes advanced programs easier to develop and debug.

FAQs

1. What should I practice after learning basic C concepts?

Start combining concepts. Practice programs involving arrays with functions, structures with arrays, pointers with functions, dynamic memory, strings, recursion, and file handling.

2. Are advanced C programs difficult for beginners?

They can look difficult because several concepts appear together. The easiest approach is to break the program into smaller tasks and solve each task separately.

3. Why are pointers important in advanced C programming?

Pointers allow programs to work directly with memory addresses and are commonly used with arrays, functions, structures, and dynamic memory allocation.

4. When should I use dynamic memory allocation?

Use dynamic memory when the amount of memory required needs to be decided during program execution or when dynamically managed data structures are needed.

5. Why should I use functions in large C programs?

Functions divide a large program into smaller, manageable tasks. This makes code easier to read, test, reuse, and debug.

6. What is an array of structures in C?

An array of structures stores multiple records of the same structure type. For example, struct Student students[50] can store information for 50 students.

7. How can I improve my C problem-solving skills?

Practice regularly and gradually increase the number of concepts used in each program. Try solving the problem yourself first, then compare your solution with a working implementation and test different inputs.

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top