Top 40+ C Programming Interview Questions and Answers
Dec 04, 2024 9 Min Read 121 Views
(Last Updated)
C programming, often hailed as the “mother of all languages,” remains a cornerstone in the world of software development. Whether you’re coding embedded systems, designing operating systems, or delving into low-level programming, mastering C is non-negotiable. With its efficiency, simplicity, and unparalleled control over hardware, C is a must-know language for every aspiring and experienced developer.
So, to help you prepare for your next technical interview, I’ve compiled 40+ of the most essential C programming interview questions and answers that range from beginner to advanced levels. This guide is your one-stop resource to ace your interview and stand out as a C programming expert.
Table of contents
- Top C Programming Interview Questions and Answers (Section-Wise)
- Beginner Level Questions
- Intermediate Level Questions
- Advanced Level Questions
- Takeaways…
Top C Programming Interview Questions and Answers (Section-Wise)
I have divided all these important C Programming interview questions and answers into various sections for your ease of learning, I recommend covering the beginner level questions as a must and then going through all the sections one by one so that you can gain a well-rounded knowledge of how these interviews are undertaken and how much and what you should prepare.
Beginner Level Questions
1) What is C programming and why is it called a middle-level language?
C is a general-purpose, procedural programming language developed by Dennis Ritchie in the 1970s. It is called a “middle-level” language because it combines the features of both low-level and high-level programming languages.
C allows manipulation of hardware and memory directly (low-level), but it also provides high-level abstractions such as functions and structures. This makes it suitable for system programming (like operating systems) and application programming, offering both flexibility and control over the hardware.
2) What are the basic data types in C? Provide examples of each.
The basic data types in C are:
- int: Used to store integers. Example: int a = 5;
- char: Used to store single characters. Example: char b = ‘A’;
- float: Used to store floating-point numbers. Example: float c = 3.14;
- double: Used for double-precision floating-point numbers. Example: double d = 3.141592;
- void: Represents no value or no type. Example: void func() {}
Each type has a specific size and range depending on the system architecture.
3) Write a program to print “Hello, World!” without using ; .
Answer: Use an if or switch statement:
#include <stdio.h>
int main() {
if (printf("Hello, World!")) {}
return 0;
}
4) What is the difference between #include <stdio.h> and #include “file.h”?
- #include <stdio.h>: This directive is used to include standard library header files. The compiler looks for stdio.h in the system’s predefined library directories.
- #include “file.h”: This directive is used to include user-defined header files. The compiler first looks for file.h in the current directory and, if not found, checks the system directories.
In short, < > is used for standard headers, and ” ” is used for custom headers.
5) What is the purpose of a main() function in C?
The main() function is the entry point of any C program. It is where execution begins. Every C program must have a main() function, which returns an integer value (typically 0 to indicate successful execution). The arguments int argc, char *argv[] can be passed to main() to handle command-line inputs.
6) Explain the difference between printf() and scanf().
- printf(): A function used to output formatted text to the standard output (usually the console). It allows formatting through format specifiers like %d for integers, %f for floating-point numbers, etc.
- Example: printf(“The value is: %d”, x);
- scanf(): A function used to read input from the standard input (keyboard). It takes input from the user and stores it in specified variables.
- Example: scanf(“%d”, &x);
In short, printf() is used for output, and scanf() is used for input.
7) What are keywords in C? List five examples and their uses.
Keywords in C are reserved words that have special meanings and cannot be used as identifiers (variable names, function names, etc.). Examples include:
- int: Defines an integer data type.
- return: Terminates a function and optionally returns a value.
- if: Used for conditional statements.
- while: Defines a loop that executes as long as a condition is true.
- struct: Defines a structure to group different data types.
These keywords are part of the syntax of the language and enable structured programming.
8) What is the purpose of the return statement in C functions?
The return statement is used to exit a function and optionally pass a value back to the calling function. In non-void functions, it specifies the function’s return value. In void functions, return is used without a value to exit the function prematurely.
- Example: return 0; in int main() indicates successful execution.
9) Explain the use of comments in C. How many types of comments are there?
Comments are used to add explanatory notes to the code. They are ignored by the compiler and help make the code more readable for developers. There are two types of comments in C:
- Single-line comments: Denoted by //. They comment out a single line.
- Example: // This is a comment
- Multi-line comments: Denoted by /* */. They can span multiple lines.
- Example: /* This is a multi-line comment */
10) What is a variable in C? How do you declare and initialize it?
A variable in C is a named storage location in memory that holds a value of a specified data type. To declare a variable, you specify its type followed by its name, and optionally, its initial value.
- Declaration: int x; declares an integer variable x.
- Initialization: int x = 5; initializes the variable x with a value of 5.
11) What is the difference between a compiler and an interpreter? Why is C a compiled language?
- Compiler: A program that translates the entire source code of a program into machine code (or intermediate code) before execution. The output is an executable file.
- Interpreter: A program that reads and executes the source code line by line.
C is a compiled language because it uses a compiler to translate the C source code into machine code before execution, resulting in faster execution. The compiled code is platform-dependent.
12) Write a program to reverse a string in C.
Answer:
#include <stdio.h>
#include <string.h>
void reverse(char str[]) {
int n = strlen(str);
for (int i = 0; i < n / 2; i++) {
char temp = str[i];
str[i] = str[n - i - 1];
str[n - i - 1] = temp;
}
}
int main() {
char str[] = "Interview";
reverse(str);
printf("Reversed string: %s\n", str);
return 0;
}
13) How do you swap two integers without using a temporary variable?
Answer:
int a = 5, b = 10;
a = a + b; // a = 15
b = a - b; // b = 5
a = a - b; // a = 10
14) Write a program to check if a number is a palindrome.
Answer:
#include <stdio.h>
int isPalindrome(int n) {
int original = n, reversed = 0;
while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}
return original == reversed;
}
int main() {
int num = 121;
if (isPalindrome(num))
printf("%d is a palindrome\n", num);
else
printf("%d is not a palindrome\n", num);
return 0;
}
Master C programming with GUVI’s C Programming Course, designed for both aspiring programmers and those preparing for C programming interviews. This course offers hands-on practice, real-world problem-solving examples, and detailed guidance on essential concepts like loops, arrays, and functions.
With lifetime access, interactive learning modules, and industry-relevant projects, it’s perfect for building a solid foundation in C and excelling in technical interviews.
Intermediate Level Questions
15) What are pointers in C, and how are they used? Provide a real-world example.
Answer:
Pointers in C are variables that store the memory address of another variable. They allow direct memory access and manipulation, which is essential for dynamic memory management, implementing linked lists, and passing large structures to functions efficiently.
Example:
int num = 10;
int *ptr = # // Pointer 'ptr' holds the address of 'num'
printf("%d", *ptr); // Dereferencing ptr gives the value of 'num', which is 10
Pointers are widely used in memory management, such as allocating and freeing dynamic memory using malloc() and free().
16) Explain the difference between call by value and call by reference with examples.
Answer:
- Call by Value: The function receives a copy of the argument. Any changes to the parameter inside the function do not affect the original variable.
- Call by Reference: The function receives the address of the argument. Changes to the parameter inside the function will modify the original variable.
Example (Call by Value):
void foo(int x) {
x = 20;
}
int main() {
int a = 10;
foo(a); // 'a' remains 10 after function call
}
Example (Call by Reference):
void foo(int *x) {
*x = 20;
}
int main() {
int a = 10;
foo(&a); // 'a' becomes 20 after function call
}
17) What is recursion? How does it differ from iteration in C?
Answer:
Recursion is when a function calls itself to solve smaller instances of a problem. It’s often used in problems like factorial calculation, tree traversals, and searching algorithms. Each recursive call typically reduces the problem size, and a base case is required to stop the recursion.
Iteration involves repeating a set of instructions using loops (for, while, do-while). It doesn’t involve function calls.
Example (Recursion for Factorial):
int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n - 1);
}
Example (Iteration for Factorial):
int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
Difference:
Recursion is elegant but can lead to high memory usage due to call stack, whereas iteration typically uses less memory and is often more efficient.
18) What is a struct in C, and how does it differ from an array?
Answer:
A struct is a user-defined data type that allows grouping variables of different types together. It is used to represent a record. An array, on the other hand, is a collection of elements of the same data type.
Example (Struct):
struct Person {
char name[50];
int age;
};
Difference:
- Struct can store different types of data, while an array can only store one type of data.
- Arrays are fixed in size, while structs can contain elements of different sizes and types.
19) Explain the concept of dynamic memory allocation in C. How are malloc() and free() used?
Answer:
Dynamic memory allocation in C allows programs to request memory at runtime using functions like malloc(), calloc(), and realloc(), and release it with free(). This helps manage memory efficiently, especially when the exact amount of memory needed is not known in advance.
- malloc(size): Allocates a block of memory of size bytes and returns a pointer to it. It does not initialize the memory.
- free(ptr): Deallocates the memory previously allocated by malloc().
Example:
int *arr = (int *)malloc(5 * sizeof(int)); // Allocating memory for an array of 5 integers
if (arr == NULL) { /* Handle memory allocation failure */ }
free(arr); // Free the allocated memory
20) What is a preprocessor in C? List common preprocessor directives and their uses.
Answer:
The preprocessor in C is a program that processes the source code before it is compiled. It handles directives like #define, #include, #if, and #ifdef.
Common preprocessor directives:
- #define: Used to define constants and macros.
- #include: Includes header files in the program.
- #if, #ifdef, #endif: Conditional compilation for including/excluding code.
- #undef: Undefines a macro.
- #pragma: Provides special instructions to the compiler.
Example:
#define PI 3.14
#include <stdio.h>
21) What is the difference between an array and a pointer? When should you use one over the other?
Answer:
- An array is a fixed-size collection of elements of the same data type.
- A pointer is a variable that stores the address of another variable, allowing dynamic memory allocation.
Difference:
- Arrays have a fixed size at compile-time, while pointers can be resized and manipulated at runtime.
- Arrays are easier to use when the size is known in advance, while pointers are better for dynamic memory allocation.
When to Use:
- Use an array when the size is fixed and known.
- Use a pointer for dynamic memory allocation and when working with data structures like linked lists.
22) What is the significance of the const keyword in C? Provide examples of its usage.
Answer:
The const keyword in C is used to define variables whose values cannot be changed after initialization. It ensures that a value remains constant throughout the program, providing better safety and readability.
Example:
const int MAX_VALUE = 100; // MAX_VALUE cannot be modified
It can also be used with pointers:
const int *ptr = &MAX_VALUE; // ptr cannot modify the value of MAX_VALUE
23) What is a storage class in C? Briefly describe all types with examples.
Answer:
A storage class in C defines the scope, lifetime, and visibility of a variable. There are four types:
- auto: Default for local variables, scope limited to the block.
- register: Suggests that the variable be stored in a register for faster access (not guaranteed).
- static: Retains the value of a variable between function calls, limited to the file.
- extern: Used to declare variables defined in another file.
Example:
static int count = 0; // retains its value between function calls
24) How does the sizeof operator work in C? What are its applications?
Answer:
The sizeof operator in C returns the size (in bytes) of a data type or variable. It is evaluated at compile-time and can be used to determine the memory required for variables, arrays, structures, and more.
Example:
int num = 5;
printf("Size of int: %lu", sizeof(int)); // Outputs the size of int
Applications:
- Determining the memory needed for data structures.
- Allocating memory dynamically with malloc() based on the type.
25) Write a function to count the number of set bits in an integer.
Answer:
int countSetBits(int n) {
int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
26) Write a program to check if a number is prime.
Answer:
int isPrime(int n) {
if (n <= 1) return 0;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return 0;
}
return 1;
}
27) What is a segmentation fault, and how can it occur in C? Provide an example.
Answer:
A segmentation fault occurs when a program tries to access memory it doesn’t own. Example:
int *ptr = NULL;
*ptr = 10; // Dereferencing a NULL pointer causes a segmentation fault.
28) Write a program to reverse a linked list.
Answer:
struct Node {
int data;
struct Node* next;
};
struct Node* reverse(struct Node* head) {
struct Node *prev = NULL, *current = head, *next = NULL;
while (current) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
Advanced Level Questions
29) What is undefined behavior in C? Provide examples of how it can occur.
Answer:
Undefined behavior refers to program behavior that is unpredictable and may vary across compilers, platforms, or even compiler settings. It occurs when the C standard does not specify how certain operations should behave. Examples include:
- Dereferencing a null pointer: *ptr = 10; when ptr is null.
- Using uninitialized variables: int x; printf(“%d”, x);
- Overflowing array bounds: arr[10] = 5; for an array with size 10.
- Modifying a variable more than once between sequence points: x = x++ + 1;
30) What is the purpose of the volatile keyword in C? How does it prevent compiler optimizations?
Answer:
The volatile keyword tells the compiler that a variable’s value can change at any time, outside of the program’s control (e.g., hardware registers or interrupt service routines). It prevents the compiler from applying optimizations, such as caching the value of the variable in a register. Without volatile, the compiler might assume that the variable’s value doesn’t change, leading to incorrect program behavior.
Example:
volatile int flag = 0;
The compiler will ensure that every access to flag reads from memory and not from a cached register.
31) Explain how memory is divided in a C program (stack, heap, text, data segments).
Answer:
A C program’s memory is divided into several segments:
- Text Segment: Contains the executable code of the program.
- Data Segment: Stores global and static variables that are initialized by the programmer.
- BSS (Block Started by Symbol) Segment: Stores uninitialized global and static variables.
- Heap: Used for dynamic memory allocation (malloc(), calloc()) and is managed manually (using free()).
- Stack: Holds local variables, function calls, and control data such as return addresses. It grows and shrinks as functions are called and return.
32) What is the difference between deep copy and shallow copy in C?
Answer:
Shallow Copy: Creates a new reference to the same memory address as the original variable. Any changes to the copied object affect the original object. For example, copying a pointer to a structure only copies the address.
struct Person *p1 = malloc(sizeof(struct Person));
struct Person *p2 = p1; // Shallow copy
Deep Copy: Allocates new memory for the copied object and copies the values of the original object into the new memory. Modifications to the copy do not affect the original object.
struct Person *p1 = malloc(sizeof(struct Person));
struct Person *p2 = malloc(sizeof(struct Person));
*p2 = *p1; // Deep copy
33) What are function pointers? How are they declared and used in real-world applications?
Answer:
A function pointer is a pointer that points to a function rather than data. It allows functions to be passed as arguments or invoked dynamically at runtime.
Declaration:
int (*func_ptr)(int, int);
Usage:
Passing functions as arguments:
void execute(int (*func)(int, int)) {
int result = func(5, 10);
}
Callback functions in event-driven programming, like in GUI applications or libraries like qsort():
qsort(arr, n, sizeof(int), compare);
34) What are inline functions in C? How do they improve performance?
Answer:
Inline functions are functions that the compiler replaces with their actual code during compilation. Instead of performing a function call, the code is “inlined” at the call site. This can improve performance by avoiding the overhead of function calls (stack operations, jumps), particularly for small, frequently-called functions.
Example:
inline int add(int a, int b) {
return a + b;
}
However, excessive inlining may increase code size, so the compiler decides when to inline a function.
35) What is the difference between exit() and _exit() in C? When should each be used?
Answer:
exit(): Terminates the program and calls all cleanup functions registered with atexit(), closes open file descriptors, and flushes the output buffers.
exit(0); // Exits the program normally
_exit(): Terminates the program immediately without performing any cleanup (no flushing of buffers or closing of file descriptors).
_exit(0); // Exit immediately
Use exit() for normal program termination, and _exit() for situations where you don’t want any I/O or cleanup operations, such as in child processes after fork().
36) Explain the concept of reentrant functions. Why are they critical for multi-threaded programs?
Answer:
A reentrant function is one that can be safely called again before its previous executions are finished. It doesn’t rely on static or global variables, and if it does, it uses synchronization mechanisms to prevent race conditions. Reentrant functions are critical for multi-threaded applications because they allow threads to invoke the same function simultaneously without causing data corruption or unexpected behavior.
Example: A reentrant function avoids using shared global variables that could be modified by different threads simultaneously.
37) What are macros in C? How do they differ from functions? Provide examples.
Answer:
A macro is a preprocessor directive that defines a piece of code (typically a constant value or a small function) that is substituted by the preprocessor before compilation.
Difference between macros and functions:
- Macros are expanded inline during preprocessing, avoiding function call overhead. However, they don’t have type safety.
- Functions are compiled as regular functions, with type checking, but involve overhead from function calls.
Example of a macro:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
Macros are fast but can lead to debugging challenges (e.g., operator precedence issues), whereas functions are safer and more maintainable.
38) What is the role of memory alignment in C? Why is it important for performance?
Answer:
Memory alignment refers to arranging data in memory based on the architecture’s requirements, such as aligning variables to addresses that are multiples of their size. Misalignment can lead to inefficient memory access and performance penalties due to extra memory cycles needed to read or write misaligned data.
For example, on a 32-bit system, a 4-byte integer should ideally be stored at an address that is a multiple of 4. Misalignment can cause slower memory access or even cause the program to crash on some architectures.
Example:
struct {
char a; // 1 byte
int b; // 4 bytes
};
The compiler may add padding between a and b to ensure b is aligned to a 4-byte boundary.
39) Write a program to implement a stack using arrays.
Answer:
#define MAX 100
int stack[MAX], top = -1;
void push(int x) {
if (top == MAX - 1) {
printf("Stack Overflow\n");
return;
}
stack[++top] = x;
}
int pop() {
if (top == -1) {
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
40) What is the difference between stack and heap memory allocation?
Answer:
Stack: Fast, automatic memory, but limited in size.
Heap: Dynamically allocated memory with manual control but slower and prone to fragmentation.
41) Write a program to implement binary search.
Answer:
int binarySearch(int arr[], int n, int key) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) return mid;
else if (arr[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
42) Write a program to detect a loop in a linked list.
Answer:
int detectLoop(struct Node* head) {
struct Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return 1;
}
return 0;
}
43) Write a program to generate all permutations of a string.
Answer:
void permute(char *str, int l, int r) {
if (l == r) printf("%s\n", str);
else {
for (int i = l; i <= r; i++) {
swap(&str[l], &str[i]);
permute(str, l + 1, r);
swap(&str[l], &str[i]); // Backtrack
}
}
}
Takeaways…
Cracking a C programming interview requires more than just theoretical knowledge—it demands problem-solving skills, hands-on coding expertise, and a deep understanding of how the language works under the hood.
The C Programming Interview Questions and Answers I’ve covered will not only prepare you for common interview scenarios but also sharpen your technical acumen. Remember, practice is key. Keep exploring, coding, and debugging to refine your mastery over C.
I hope these questions have aided in your preparation, if you have any doubts about them or the article, do reach out to me in the comments section below.
Did you enjoy this article?