Master C Programming Interviews in 2026. From Embedded Systems to High-Frequency Trading, C remains the king of performance. This guide covers the Top 50+ essential interview questions asked by tech giants like Google and Qualcomm to help you crack the toughest technical rounds.
1. What is the difference between a deep copy and a shallow copy in C?
| Feature | Shallow Copy | Deep Copy |
|---|
| Definition | Copies only the pointer, not the actual data it points to | Copies both the pointer and the actual data (creates a new memory block) |
| Memory Usage | Lower (shares the same memory address) | Higher (allocates separate memory) |
| Data Independence | No – Changes in one reflect in the other | Yes – Changes are isolated |
| Use Case | When objects are not managing dynamic memory | When objects manage resources like heap memory. |
Shallow Copy code:
Deep Copy in C:
2. What is the difference between malloc() and calloc() in the C programming language?
The primary difference lies in initialization. malloc() allocates a single block of memory with garbage values, while calloc() allocates multiple blocks and initializes them to zero.
Here are a few differences between malloc() and calloc()
| Feature | malloc() (Memory Allocation) | calloc() (Contiguous Allocation) |
|---|
| Initialization | Contains garbage values initially. | Automatically initializes all bits to zero. |
| Arguments | Takes 1 argument: size in bytes. | Takes 2 arguments: number of blocks and size of each block. |
| Speed | Faster, as it skips the initialization step. | Slower, due to the overhead of setting memory to zero. |
| Syntax | ptr = malloc(size); | ptr = calloc(n, size); |
Code Example:
3. What is the use of static variables in C?
Static variables are initialized only once and retain their previous values, which were assigned or initialized in the previous scope.
Table of Contents:
Core Syntax and Data Types
4. List the data types supported in the C Language.
The data types supported in the C Programming Language are:
- Int: int is used to store integers.
For example:
int var = 10;
- Float: A float is used to store floating/decimal numbers.
For example:
float weight = 10.5;
- Char: char is used to store characters.
For example:
char Grade = ‘A’;
- Double: double is used to store double-precision floating-point numbers.
For example:
double pi = 3.14159265359;
- Void: void is used for functions that don’t return any value.
For example:
void function_name() {
return;
}
5. Difference between “=” and “==” operator in C programming.
The core difference is their function: = is for Assignment, while == is for Comparison.
| Feature | Assignment Operator (=) | Equality Operator (==) |
|---|
| Type | Binary Operator (Assigns value). | Relational Operator (Compares values). |
| Function | Copies the value from the right side to the left side variable. | Checks if the left side is equal to the right side. |
| Return Value | Returns the assigned value. | Returns 1 (True) or 0 (False). |
| Example | x = 10; (Sets x to 10). | if (x == 10) (Checks if x is 10). |
6. What are Reserved Keywords in C?
Reserved keywords are the special keywords that can not be used as a variable name.
For example: int, return, for, void, if, else, switch, etc.
7. What do you mean by the scope of the variable?
The scope of a variable means the section of the code in which the variable is accessible or valid.
8. What are the different storage class specifiers in the C Language?
There are 4 storage class specifiers in the C Language, i.e., auto, register, static, and extern.
- Auto is used as the Default storage class for local variables.
- The register is used to store variables in the CPU register for faster access.
- Static is used to retain the value of the variables between function calls.
- Extern is used to declare a global variable or function in another file.
9. What are an r-value and an l-value?
An object that has a specified memory location and is written on the left side of the assignment is known as an L-value.
int var = 5; //var is a l-value
An object that doesn’t have a specified memory location and is written on the right side of the assignment is known as an R-value.
int var = var1 + 5; //var1+5 is a r-value
10. Explain the difference between Type Casting and Type Conversion in C with examples?
Typecasting is done to convert one data type into another data type. It is an explicit conversion as it is done by the user.
float a = 6.5;
int b = (int)a; // b is now 6
Type Conversion is also done to convert a data type into another data type, but it is an implicit conversion as it is done by the compiler itself.
int x = 5;
float y = x; // Implicitly converts int to float
11. Can we compile a program without a main() function in C? [Tricky]
Yes, a program can be compiled without a main() function, but it can’t be executed.
In C programming, the main() function is the entry point of any executable program. While the compiler’s job is just to translate the code into machine language (object code), it doesn’t care whether main() is present or not, it will still compile the code as long as there are no syntax errors.
However, when it comes to execution, the operating system looks for the main() function to start the program. If main() is missing, the linker will throw an error because it doesn’t know where to begin execution.
12. How to create an Infinite loop in C?
1. Infinite loop using a while Loop: Set the condition 1 (or any non-zero value), which is always true, so the loop runs indefinitely.
while (1) {
// Code block
}
2. Infinite loop Using a for Loop: Does not specify any initialization, condition, or increment in the loop. Without a condition, it is always considered true, which will result in an infinite loop.
for (;;) {
// Code block
}
3. Using a do-while Loop: Similar to a while loop, set the loop condition value to 1, which is always true, so the loop continues indefinitely.
do {
// Code block
} while (1);
13. What is the difference between const and #define? When should you use which? [Asked in Bosch]
The main difference is what handles it: #define is handled by the Preprocessor, whereas const is handled by the Compiler.
| Feature | #define (Macro) | const (Constant Variable) |
|---|
| Stage | Preprocessor (Before Compilation). | Compiler (During Compilation). |
| Memory | Does not occupy memory (Text replacement). | Occupies memory (Stored in Read-Only Data). |
| Type Checking | No. It is just a text copy-paste. | Yes. The compiler checks for type mismatch. |
| Debugging | Harder (Symbol is lost). | Easier (Symbol exists in symbol table). |
When to use which?
- Use const (Preferred): If at all possible, for Type Safety and Scope considerations.
- Use #define: Only use this when something cannot be done with variables, such as:
- Header Guards (#ifndef).
- Code snippets (Macros like MAX(a, b)).
14. What is the difference between i++ and ++i in a complex expression?
The difference lies in the Order of Evaluation:
- i++ (Post-Increment): This operator uses the current value of the expression and then increments the variable.
- ++i (Pre-Increment): First, it increments the variable and then uses the incremented variable for the expression.
Code Example:
Pointers and Memory Management
15. What is the difference between a null pointer and a void pointer?
The difference is in their nature:
- NULL Pointer: It has a value of (0). It is used to indicate that the pointer is not pointing to any memory location.
- Void Pointer: This data type is used to represent a type (void*). It is called a “generic pointer” that can hold addresses of any type (int, float, char), but has no type associated with itself.
| Feature | NULL Pointer (int *p = NULL) | Void Pointer (void *p) |
|---|
| Concept | A Value indicating “Nothing”. | A Data Type indicating “Generic”. |
| Dereferencing | Runtime Error: Causes a Segmentation Fault (Crash). | Compiler Error: You cannot dereference without casting it first. |
| Arithmetic | Allowed (if it has a type, e.g., int*). | Not Allowed (compiler doesn’t know the size of the object). |
| Use Case | Error checking and initializing pointers. | malloc(), qsort(), and generic function arguments. |
16. What is the difference between const char* p and char const* p?
There is NO difference. Both declarations mean exactly the same thing: “A pointer to a constant character.”
In C, always read the declaration from Right to Left:
- const char * p: “p is a pointer to a char that is constant.”
- char const * p: “p is a pointer to a const char.”
The Real Difference (Interview Trap):
The confusion usually arises when comparing these to char * const p.
| Declaration | Meaning | Can change p? (Address) | Can change *p? (Value) |
|---|
| const char * p | Pointer to Constant Data | Yes (p++ is OK) | No (*p = ‘A’ is Error) |
| char const * p | Pointer to Constant Data | Yes (p++ is OK) | No (*p = ‘A’ is Error) |
| char * const p | Constant Pointer to Data | No (p++ is Error) | Yes (*p = ‘A’ is OK) |
Code Example:
17. What is a memory leak in C?
When the allocated memory is not freed, a memory leak occurs. To avoid a memory leak, we can use the free() function to release the memory.
18. What is the difference between call by value and call by reference in C?
The main difference is the manner of memory manipulation:
- Call by Value: It passes a copy of the variable. Changes are not reflected in the original variable.
- Call by Reference: This method passes the address (pointer) of the variable. Changes to the variable within the function affect the original variable.
| Feature | Call by Value | Call by Reference |
|---|
| What is passed? | A duplicate copy of the data. | The memory address of the data. |
| Effect on Original | Safe. The original variable remains unchanged. | Modified. Changes reflect in the original variable. |
| Memory Usage | High. Creates a copy (bad for large structs). | Low. Only passes a small pointer size (4/8 bytes). |
| Syntax | function(x); | function(&x); |
19. What are the differences between the sizeof operator and the strlen function?
The main difference is when they run:
- sizeof: A Compile-Time Operator. It returns the total size of the variable in bytes, including the null-terminating character \0 for arrays.
- strlen: It is a runtime function that iterates through the string to count the number of characters until it reaches the \0 character (excluding the null terminator).
| Feature | sizeof Operator | strlen Function |
|---|
| Type | Unary Operator (Keywords). | Library Function (<string.h>). |
| Execution Time | Compile Time (Calculated before run). | Run Time (Calculated while running). |
| Null Terminator | Includes \0 (Total allocated memory). | Excludes \0 (Actual data length). |
| Works On | Arrays, Types (int, struct), Pointers. | Only Null-Terminated Strings. |
20. When does the compiler not implicitly generate the address of the first element of an array?
The compiler does not implicitly generate the address of the first element of an array whenever an array name appears:
- As an operand of the sizeof operator
- As an operand of the & operator.
- As a string literal, initialize a character array.
21. What is a Dangling Pointer? How is it different from a Memory Leak? [Asked in Samsung]
A dangling pointer is a pointer that has already been deleted. It means that it’s pointing to memory space that’s already been deleted.
- The Risk: If dereferenced, it will cause Undefined Behavior (crashes and/or data corruption).
- The Fix: Always set the pointer to NULL immediately after freeing it.
| Feature | Dangling Pointer | Memory Leak |
|---|
| Definition | A pointer pointing to freed memory. | Memory that is allocated but never freed. |
| Analogy | You have a key to a house that was demolished. | You lost the key to a locked house (space is wasted). |
| Cause | Accessing memory after calling free(). | Forgetting to call free() after malloc(). |
| Consequence | Immediate Crash (Segmentation Fault). | Slow Death (System runs out of RAM over time). |
| Solution | Set ptr = NULL after freeing. | Use tools like Valgrind to find leaks. |
22. Explain realloc(). What happens to the old memory block if allocation fails?
realloc() is used to resize a previously allocated memory block. It checks if sufficient contiguous space exists for resizing the current block.
- Success: It returns a pointer to the new (resized) block. Data from the old block is copied.
- Failure: It returns NULL. Most importantly, the original block remains valid and unchanged.
The Common Mistake (Memory Leak): When you assign the result of realloc() to the original pointer, you will overwrite your original pointer with NULL if realloc() fails. The original memory will be lost (memory leak).
The Safe Way (Use a Temporary Pointer):
23. What is a Double Pointer (**ptr), and give a practical use case for it? [Advanced].
A Double Pointer (Pointer to a Pointer) is a variable that holds the memory address of another pointer.
- Single Pointer (*p): This stores the memory address of a variable (Value).
- Double Pointer (**p): It contains the reference to a pointer, i.e., Reference to Reference.
The Practical Use Case (Why use it?): The most common use case is when you want to modify the memory address stored in a pointer. For example, you want to allocate memory in a function.
Data Structures and Algorithms
24. What is a structure?
A structure is a user-defined data type that combines or merges multiple data types together.
25. What is a UNION?
A Union is similar to a structure, but in a structure, the variables don’t share memory, whereas in a union, the multiple variables with different data types use shared memory.
26. What are the different techniques for making a hash function?
Techniques for making a hash function.
This is the simplest method for computing an address from a key. In this method, we take only a part of the key as the address.
In this method, the key is squared, and some digits from the middle of this square are taken as the address.
In this technique, the key is divided into differents part where the length of each part is the same as that of the required address, except possibly the last part.
- Division Method (Modulo-Division)
In the Modulo-Division method, the key is divided by the table size, and the remainder is taken as the address of the hash table.
Let the table size be n, then
H (k) =k mod n
27. What is XOR linked list? [Data Structures]
XOR-linked list is a Memory Efficient Doubly Linked List. An ordinary Doubly Linked List
requires space for two address fields to store the addresses of previous and next nodes. A memory-efficient version of a Doubly Linked List can be created using only one space for the address field in every node. This memory-efficient Doubly Linked List is called the XOR Linked List or Memory Efficient, as the list uses the bitwise XOR operation to save space for one address.
In the XOR-linked list, instead of storing actual memory addresses, each node stores the XOR of the addresses of the previous and next nodes.
XOR List Representation:
Let us call the address variable in XOR representation npx (XOR of next and previous)
Node A:
npx = 0 XOR add(B) // bitwise XOR of zero and address of B
Node B:
npx = add(A) XOR add(C) // bitwise XOR of address of A and address of C
Node C:
npx = add(B) XOR add(D) // bitwise XOR of address of B and address of D
Node D:
npx = add(C) XOR 0 // bitwise XOR of address of C and 0
28. What is ‘trie’ in data structure?
A trie is an efficient information retrieval data structure. Using a trie, search complexities can be brought to an optimal limit (key length). If we store keys in a binary search tree, a well-balanced BST will need time proportional to M * log N, where M is the maximum string length, and N is the number of keys in the tree.
- Using a trie, we can search the key in O(M) time. However, the penalty is on the storage requirements.
- Each node of a trie consists of multiple branches. Each branch represents a possible character of keys.
- We need to mark the last node of every key as a leaf node.
- A trie node field value will be used to distinguish the node as a leaf node (there are other uses of the value field).
- A simple structure to represent the nodes of the English alphabet can be as follows:
29. What do you understand by a splay tree?
A splay tree is a self-balancing Binary Search Tree (BST). The main idea of a splay tree is to bring the recently accessed item to the root of the tree. This makes the recently searched item accessible in O (1) time if accessed again. The idea is to use locality of reference (In a typical application, 80% of the accesses are to 20% of the items).
Imagine a situation where we have millions or billions of keys and only a few of them are accessed frequently, which is very likely in many practical applications.
All splay tree operations run in O(log n) time on average, where n is the number of entries in the tree. Any single operation can take Theta(n) time in the worst case.
30. What is a Treap?
A treap is a Balanced Binary Search Tree, but not guaranteed to have height as O(Log n). The idea is to use Randomization and the binary heap property to maintain balance with high probability. The expected time complexity of search, insert, and delete is O(Log n).
Each node of Treap maintains two values.
- Key: It follows standard BST ordering (left is smaller and right is greater)
- Priority: Randomly assigned value that follows the Max-Heap property.
31. How to implement the LRU caching scheme? What data structures should be used? [Asked in Google]
We are given the total possible page numbers that can be referred to. We are also given cache (or memory) size (the Number of page frames that the cache can hold at a time). The LRU caching scheme is to remove the least recently used frame when the cache is full, and a new page is referenced that is not in the cache.
We use two data structures to implement an LRU Cache.
- Queue: A queue that is implemented using a doubly linked list. The maximum size of the queue will be equal to the total number of frames available (cache size). The most recently used pages will be near the front end, and the least recently used pages will be near the rear end.
- A Hash: with page number as key and address of the corresponding queue node as value. When a page is referenced, the required page may be in memory. If it is in the memory, we need to detach the node from the list and bring it to the front of the queue. If the required page is not in memory, we bring it into memory. In simple words, we add a new node to the front of the queue and update the corresponding node address in the hash. If the queue is full, i.e., all the frames are full, we remove a node from the rear of the queue and add the new node to the front of the queue.
32. Suppose there are two linked lists: L1 and L2 (of the same length) that intersect at a particular node N1… What are the possibilities of finding N1?
A linear solution is possible. Have two pointers, say P1 pointing to the first node of L1 and P2 to that of L2. Traverse through both the lists. If P1 reaches L1’s last node, point it to the first node of L2 and continue traversing.
Do the same thing for P2 when it reaches L2’s last node. (By doing this, we are balancing the difference in the length between the linked lists. The shorter one will get over soon, and by redirecting to the longer list’s head, it will traverse the extra nodes also. Finally, they will meet at the Intersection node.
33. Given two keys K1 & K2, write an algorithm to print all the elements between them with K1<=K2 in a BST.
- A linear solution is possible without using any extra space.
- Perform an inorder traversal.
- Once you find K1, print it and continue traversal now.
- Print all other traversed elements until you reach K2.
Let us understand this with a pseudo-code:
Explanation:
- Left Subtree Condition:
- If the current node’s value is greater than K1, then the left subtree might contain values within range. So we explore it.
- Printing Current Node:
- If the current node is within [K1, K2], we print it.
- Right Subtree Condition:
- If the current node’s value is less than K2, then the right subtree might have more values within the range. So we explore it.
34. How many stacks are required to implement a Queue?
Two stacks are required to implement a Queue.
- For Enqueue: Take two stacks, S1 and S2, and perform a push on S1.
- For Dequeue: If S2 is empty, pop all the elements from S1 and push them to S2. The last element you popped from S1 is an element to be dequeued. If S2 is not empty, then pop the top element from it.
35. Write a program to detect a loop/cycle in a Linked List. (Floyd’s Algorithm). [Most Asked Logic]
The Logic (Tortoise and Hare): Use two pointers, slow_ptr and fast_ptr.
- Slow Pointer: It moves 1 step at a time.
- Fast Pointer: Advances 2 steps at a time.
- The Catch: If a loop exists, the Fast Pointer will ultimately enter the loop and “lap” the Slow Pointer (i.e., they will meet at the same node). If the Fast Pointer reaches NULL, it means that no loop exists.
Code Implementation:
System, OS, and Bitwise Operations
36. Explain the difference between #include “…” and #include <…> header files?
The difference is in the Search Path, which is where the preprocessor first looks for the file.
- #include <file.h>: Only searches the standard system directories, typically /usr/include.
- #include “file.h”: Searches in the current directory first. If not found, it then searches the standard system directories.
| Feature | #include <filename> | #include “filename” |
|---|
| Search Order | System Path Only. | Current Directory $\rightarrow$ System Path. |
| Primary Use | Standard Libraries (built-in). | User-Defined Headers (your code). |
| Examples | <stdio.h>, <stdlib.h> | “my_header.h”, “utils.h” |
| Efficiency | Slightly faster for system files. | Essential for local project files. |
37. What is the difference between getc(), getchar(), getch(), and getche() in C?
All these functions read a character, and their difference is in the Source, Buffering (wait for Enter), and Echoing.
| Function | Header File | Standard? | Waits for ‘Enter’? (Buffered) | Echoes to Screen? |
|---|
| getchar() | <stdio.h> | Yes | Yes (Must press Enter). | Yes (Visible). |
| getc(fp) | <stdio.h> | Yes | Yes (If reading from stdin). | Yes (If reading from stdin). |
| getch() | <conio.h> | No (Windows/DOS). | No (Instant capture). | No (Hidden input). |
| getche() | <conio.h> | No (Windows/DOS). | No (Instant capture). | Yes (Visible). |
38. What are the issues that hamper the efficiency in sorting a file?
The issues are:
- The length of time required by the programmer to code a particular sorting program.
- The amount of machine time necessary for running the particular program.
- The amount of space necessary for the particular program.
39. What is the use of the volatile keyword?
The modifier ‘volatile’ tells the compiler that a variable’s value may be changed in ways not explicitly specified by the program. For example, a global variable’s address may be passed to the operating system’s clock routine and used to hold the system time.
In this situation, the contents of the variable are altered without any explicit assignment statements in the program.
This is important because most C compilers automatically optimize certain expressions by assuming that a variable’s content is unchanging if it does not occur on the left side of an assignment statement. Thus, it may not be reexamined each time it is referenced. Also, some compilers change the order of evaluation of an expression during the compilation process. The volatile modifier prevents these changes.
40. What is a condition variable? How does it help in thread synchronization?
A condition variable is useful for the communication and coordination of threads. It helps one thread wait while a second one notifies it when something occurs.
For example, think of an order with a delivery app:
The delivery boy (thread) sits idle until there is an incoming order (condition). The moment a customer places an order, the app informs the delivery boy to commence the delivery.
In computer science, condition variables, along with mutexes, are used in such situations so that threads pause and only wake when required.
Advantages:
- Reducing overhead checks increases CPU time efficiency.
- Improves overall fluidity of control in multi-threaded applications.
41. Is using exit() the same as using return?
No, the exit() function is used to exit your program, and return() controls the operating system.
The return statement is used to return from a function and return control to the calling function. If you make a return from the main() function, you are essentially returning control(operating system) to the calling function. In this case, the return statement and exit() function are similar.
42. What is the difference between goto, longjmp(), and setjmp()?
The fundamental difference is the Scope of the Jump:
goto: Performs a Local Jump. It can only jump to a label within the same function.
longjmp() / setjmp(): Perform a Non-Local Jump. They can jump between different functions (e.g., jumping from a deeply nested function back to main()).
| Feature | goto Statement | setjmp() & longjmp() |
| Type of Jump | Local Jump (Intra-function). | Non-Local Jump (Inter-function). |
| Scope | Restricted to the same function scope. | Can jump across different functions (Stack Unwinding). |
| Mechanism | Jumps to a specific Label (label:). | Restores the CPU state (Stack Pointer, PC) saved in jmp_buf. |
| Use Case | Breaking out of nested loops. | Implementing Exception Handling (Try-Catch) in C. |
| Drawbacks | Creates “Spaghetti Code” (hard to read). | Memory Leaks: Does not free memory allocated on the heap between the set and the jump. |
43. What is the difference between a mutex and a spinlock?
The difference lies in what the thread does while waiting:
- Mutex (Mutual Exclusion): If the lock is taken by another process, the waiting process will go to Sleep (Context Switch). The OS will wake it up when the lock is available.
- Spinlock: If the lock is held by another person, the waiting thread will spin in a loop (“Busy Wait”) to check if the lock is free.
| Feature | Mutex (Sleep Lock) | Spinlock (Busy Wait) |
|---|
| Low. The CPU can do other work while waiting. | Sleeps (Yields CPU to other threads). | Spins (Consumes CPU cycles in a while loop). |
| Context Switch | Yes. (Expensive operation). | No. (Cheaper if wait time is short). |
| CPU Usage | Low. CPU can do other work while waiting. | High. CPU is “busy” doing nothing useful (polling). |
| Use Case | Long critical sections (User Space). | Short critical sections (Kernel/Interrupt Handlers). |
44. How do you set, Clear, and toggle a single bit in a register? [Asked in Qualcomm/Intel]
We use Bitwise Operators combined with Bit Masking (shifting 1 to the nth position).
| Operation | Operator | Logic | Formula (Macro) |
|---|
| Set Bit | ` | ` (OR) | Force bit to 1. |
| Clear Bit | & (AND), ~ (NOT) | Force bit to 0. | reg &= ~(1 << n); |
| Toggle Bit | ^ (XOR) | Flip (0->1, 1->0). | reg ^= (1 << n); |
| Check Bit | & (AND) | Read the value. | (reg >> n) & 1; |
If a header file is included multiple times (for example, if file A includes file B and file C also includes file B), then a Redefinition Error will occur. We avoid this using Include Guards.
There are two main ways to do this:
- Standard Include Guards (#ifndef): The traditional, portable way.
- #pragma once: A non-standard but widely supported modern directive.
| Feature | Standard Include Guards (#ifndef) | #pragma once |
|---|
| Portability | 100% Standard. Works on every C compiler. | Non-Standard. Supported by most (GCC, Clang, MSVC), but not all. |
| Performance | Slower. The preprocessor must open and parse the file every time. | Faster. The compiler remembers the file path and skips it instantly. |
| Collision Risk | High. If two files have the same macro name (HEADER_H), one will be ignored. | Zero. It relies on the file’s physical path/identity. |
| Code Style | More verbose (3 lines of code). | Cleaner (1 line of code). |
Strings, Macros, and Preprocessors
46. Explain the working of printf() and scanf() functions in C Programming language?
printf() is used to print the value or display the output on the screen.
printf("Hello, Intellipaat !");
scanf() is used to take input from the user.
int intellipaat_marks;
scanf("%d", &intellipaat_marks);
47. What is the difference between macros and functions?
The major variation is that of handling time:
- Macros: This is done before compiling by the Preprocessor. The code is literally copy-pasted into the source file (Text Replacement).
- Functions: Handled by the Compiler and Linker. They have a specificmemory address and involve a jump in execution (Context Switch).
| Feature | Macro (#define) | Function |
|---|
| Processed By | Preprocessor (Text substitution). | Compiler (Binary execution). |
| Performance | Faster (No call overhead). | Slower (Context switch/Stack overhead). |
| Code Size | Larger (Code is duplicated at every call). | Smaller (Code exists once in memory). |
| Type Checking | No (Unsafe). | Yes (Safe). |
| Debugging | Difficult (Source code changes). | Easy (Step-through works). |
48. How to convert a string to a number in C?
To convert a string into a number, the atoi() function (ASCII to integer) is used. It is defined in the stdlib.h header.
49. How to convert a number to a string in C?
50. How does C23 improve memory safety or standard library features?
The latest version of the C programming language, C23, implements new features that improve safety and user-friendliness.
Key Improvements:
- Buffer protective features: New functions like strcpys and memcpys handle preexisting buffer problems while avoiding buffer overflows.
- Better null pointer support: C23 introduces nullptr, which reduces mistakes and makes code clearer when working with pointers.
- Improved standard library: Enhancements add helpful functions and additional security checks to streamline development as well as improve the speed and safety of development. For example, suppose you are performing a copy operation into a string. Older versions of C did not have proper validation checks for the size of the destination memory space for the new data, e.g., strcpy(). This could result in crashes due to overflowing the destination buffer. C23 introduces strcpy_s(), which checks the size and hence prevents these types of errors.
51. Why is it not preferred to use gets()?
gets() is used to read a complete line of input until a new line is encountered, which can lead to overflow and characters overwritten at adjacent memory locations, as the size of the input doesn’t matter in the case of gets().
char buffer[10];
gets(buffer); // Unsafe: No limit on input size, buffer overflow can occur
52. What is an lvalue?
An lvalue is an expression to which a value can be assigned. The lvalue expression is located on the left side of an assignment statement, whereas an rvalue is located on the right side of an assignment statement.
Each assignment statement must have an lvalue and an rvalue. The lvalue expression must refer to a storable variable in memory. It cannot be a constant.
Scenario-Based Coding and Debugging
53. Write a program to print “Hello-World” without using a semicolon.
54. How to generate random numbers in C?
Random numbers are generated using the rand() function. Below is the code to generate a random number
Below is the code to generate random numbers in a range:
55. Write a C program to swap two numbers without using a third variable.
56. Write a C program to check whether a number is prime or not.
Here is a program to check if a number is prime or not
Understand the Perfect Number Program in C through this blog.
57. Write a C program to add two numbers without using the addition operator.
58. You are reading a binary file and getting garbage values. What did you forget?
You probably forgot to open the file in Binary Mode (“rb”).
If you open a binary file (like an image.png or executable.exe) in Text Mode (“r”), your Operating System might try to “interpret” the data.
- The Culprit: In Windows, the system automatically translates 0x0A (Line Feed) into 0x0D 0x0A (Carriage Return + Line Feed).
- The Result: This inserts extra bytes into your data stream, shifting all subsequent bytes and corrupting the binary structure (producing “garbage”).
| Feature | Text Mode (“r”) | Binary Mode (“rb”) |
|---|
| Newlines | Translates \n -> \r\n (Windows). | Raw. No translation. |
| End of File | Stops reading at 0x1A (CTRL+Z). | Reads until the actual file size end. |
| Use Case | .txt, .c, .csv files. | .jpg, .bin, .exe, struct data. |
| Portability | Essential for cross-platform text. | Essential for any non-text data. |
59. How do you debug a C program without an IDE? (GDB, Valgrind).
The professional standard is to use “Command Line Tools.” The two most important ones are “GDB (GNU Debugger)” and “Valgrind” for logic and memory errors, respectively.
Method 1: The “Quick & Dirty” Way (printf)
- Technique: Insert printf(“Checkpoint 1: x=%d\n”, x); at critical lines.
- Pros: fast, no tools required.
- Cons: requires recompiling, clutters code, hard to trace complex crashes.
Method 2: The “Professional” Way (GDB) This method lets you stop, examine variables, and single-step through your program line by line.
Step-by-Step GDB Process:
Compile with Debug Symbols: You must add the -g flag.
gcc -g myprogram.c -o myprogram
Start GDB:
gdb ./myprogram
Set a Breakpoint: Stop at the main or a specific line.
(gdb) break main
Run the Program:
(gdb) run
Step Through: Use next (n) to go to the next line.
(gdb) next
Inspect Variables: Check values.
(gdb) print variable_name
Method 3: The “Memory” Way (Valgrind) If you have a Segmentation Fault or Memory Leak, GDB might catch the crash, but Valgrind tells you why.
valgrind --leak-check=full ./myprogram
Common Interview Follow-up: “Why not just use VS Code?” Answer: “In embedded development, we often debug code running on a remote target (like an ARM board) via SSH. There is no GUI, so knowing GDB is mandatory.”
Conclusion
The Key to Mastering C programming is not just about syntax; it is about understanding how software talks to hardware. By mastering these 50+ questions, especially on pointers, memory management, and system architecture, you are demonstrating the deep technical expertise that top-tier companies demand. Bookmark this page, practice the code snippets, and walk into your next interview ready to solve any problem they throw at you.
Want to Learn C & Data Structure? Click Here
Unlock success in your next programming interview with our comprehensive question collection, designed to boost your confidence and expertise!
Frequently Asked Questions
Q1. What job roles can I get with C programming skills?
C Programming mainly offers opportunities for specialized positions like Embedded System Engineer, Firmware Developer, and System Software Engineer. These are the pillars of industries like IoT, Automotive (EV), and Operating Systems, where direct control over hardware is necessary.
Q2. What are the top companies that hire C Developers in 2026?
The largest recruiting companies are chipmakers like Qualcomm, NVIDIA, and Intel, along with automotive companies like Tesla and Bosch, who are using this technology in autonomous vehicles. Technology giants like Google and Microsoft are also recruiting C experts to develop OS kernels and optimize cloud infrastructure.
Q3. What is the average salary of a C Developer?
Because of the unique skill set involved (memory management, architecture, etc.), C programmers can start at a higher salary compared to web programmers. For instance, the salary for a fresh graduate can vary between ₹6L-12L (around $85k-$110k) for a junior developer, and a system architect can make significantly more than ₹30L+
Q4. What is the interview process like to become a C Developer?
Most processes begin with an online coding test (DSA), followed by 2-3 tough technical rounds, which focus mainly on Pointers, Memory Management (malloc & free), and System Design. Be prepared to answer in-depth questions about Operating System concepts like concurrency, mutex, interrupt handling, etc.
Q5. Is C programming relevant today in 2026?
Absolutely, C remains the unreplaceable language for performance-critical systems where speed and unimpeded access are non-negotiables. It drives the kernels of Windows and Linux, the firmware of every smart device (IoT), and the safety systems of Electric Vehicles everywhere.