C Programming Interview Questions
C Programming Interview Questions
The individual elements of a program are called Tokens. There are following 6 types of
tokens are available in C:
• Identifiers
• Keywords
• Constants
• Operators
• Special Characters
• Strings
4. What is the use of printf() and scanf() functions? Also explain format
specifiers?
Some datatype format specifiers for both printing and scanning purposes are as
follows:
• %d: It's a datatype format specifier for printing and scanning an integer value.
• %s: It's a datatype format specifier for printing and scanning a string.
• %c: It's a datatype format specifier for displaying and scanning a character value.
• %f: The datatype format specifier %f is used to display and scan a float value.
Explanation: The string mentioned "abxdef" is an array, and the expression is equal to
"abxdef"[5]. Why is the inside-out expression equivalent? Because a[b] is equivalent to
*(a + b) which is equivalent to *(b + a) which is equivalent to b[a].
Built-function is also known as library functions that are provided by the system to
make the life of a developer easy by assisting them to do certain commonly used
predefined tasks. For example, if you need to print output or your program into the
terminal, we use printf() in C.
7. What is a Preprocessor?
In C, #line is used as a preprocessor to re-set the line number in the code, which takes
a parameter as line number. Here is an example for the same.
#include <stdio.h>
/*line 1*/
/*line 2*/
int main(){
/*line 3*/
/*line 4*/
printf("Hello world\n"); /*line
5*/
//print current line /*line
6*/
printf("Line: %d\n",__LINE__); /*line 7*/
//reset the line number by 36 /*line 8*/
#line 36 /*reseting*/
//print current line /*line
36*/
printf("Line: %d\n",__LINE__); /*line 37*/
printf("Bye bye!!!\n");
/*line 39*/
/*line 40*/
return 0;
/*line 41*/
}
/*line 42*/
9. How can a string be converted to a number?
The function takes the string as an input that needs to be converted to an integer.
Return Value:
The function takes a pointer to an array of char elements that need to be converted,
and a format string needs to be written in a buffer as a string
When a function in C calls a copy of itself, this is known as recursion. To put it another
way, when a function calls itself, this technique is called Recursion. Also, this function is
known as recursive function.
void do_recursion()
{
... .. ...
do_recursion();
... .. ...]
}
int main()
{
... .. ...
do_recursion();
... .. ...
}
After you compile the C source, the symbol names need to be intact in the object
code. If we introduce function overloading in our source, we should also provide
name mangling as a preventive measure to avoid function name clashes. Also, as C is
not a strictly typed language many things(ex: data types) are convertible to each other
in C. Therefore, the complexity of overload resolution can introduce confusion in a
language such as C.
When you compile a C source, symbol names will remain intact. If you introduce
function overloading, you should provide a name mangling technique to prevent
name clashes. Consequently, like C++, you'll have machine-generated symbol names
in the compiled binary.
Additionally, C does not feature strict typing. Many things are implicitly convertible to
each other in C. The complexity of overload resolution rules could introduce confusion
in such kind of language
13. What is the difference between global int and static int declaration?
The difference between this is in scope. A truly global variable has a global scope and
is visible everywhere in your program.
#include <stdio.h>
int my_global_var = 0;
int
main(void)
{
printf("%d\n", my_global_var);
return 0;
}
#include <stdio.h>
int
myfunc(int val)
{
static int my_static_var = 0;
my_static_var += val;
return my_static_var;
}
int
main(void)
{
int myval;
myval = myfunc(1);
printf("first call %d\n", myval);
myval = myfunc(10);
return 0;
}
A pointer is a variable that stores or points to another variable's address. The value of
a variable is stored in a normal variable, whereas the address of a variable is stored in
a pointer variable.
Since const char and char const are the same, it's the same.
n++ being a unary operation, it just needs one variable. Whereas, n = n + 1 is a binary
operation that adds overhead to take more time (also binary operation: n += 1).
However, in modern platforms, it depends on few things such as processor
architecture, C compiler, usage in your code, and other factors such as hardware
problems.
While in the modern compiler even if you write n = n + 1 it will get converted into
n++ when it goes into the optimized binary, and it will be equivalently efficient.
Syntax: (data_type)expression;
For Example:
int x;
for(x=97; x<=122; x++)
{
printf("%c", (char)x); /*Explicit casting from int to char*/
}
If a variable is used frequently, it should be declared with the register storage specifier,
and the compiler may allocate a CPU register for its storage to speed up variable
lookup.
All statements written in a program are executed from top to bottom one by one.
Control statements are used to execute/transfer the control from one part of the
program to another depending on the condition.
• If-else statement.
o normal if-else statement.
o Else-if statement
o nested if-else statement.
• Switch statement.
calloc() and malloc() are memory dynamic memory allocating functions. The main
difference is that malloc() only takes one argument, which is the number of bytes, but
calloc() takes two arguments, which are the number of blocks and the size of each
block.
A struct is a group of complex data structures stored in a block of memory where each
member on the block gets a separate memory location to make them accessible at
once
Whereas in the union, all the member variables are stored at the same location on the
memory as a result to which while assigning a value to a member variable will change
the value of all other members.
union foo {
int a; // we can't use both a and b simultaneously
char b;
} foo;
struct bar y;
y.a = 3; // OK to use
y.b = 'c'; // OK to use
union foo x;
x.a = 3; // OK
x.b = 'c'; // NOl this affects the value of x.a!
In Pass by reference, the callee receives the address and makes a copy of the address
of an argument into the formal parameter. Callee function uses the address to access
the actual argument (to do some manipulation). If the callee function changes the
value addressed at the passed address it will be visible to the caller function as well.
Pass By Reference
When we assign a variable it takes space of our RAM (either heap or RAM)dependent
on the size of data type, however, if a programmer uses a memory available on the
heap and forgets to a delta it, at some point all the memory available on the ram will
be occupied with no memory left this can lead to a memory leak.
int main()
{
char * ptr = malloc(sizeof(int));
/* Do some work */
/*Not freeing the allocated memory*/
return 0;
}
To avoid memory leaks, you can trace all your memory allocations and think forward,
where you want to destroy (in a good sense) that memory and place delete there.
Another way is to use C++ smart pointer in C linking it to GNU compilers.
C is a language known for its low-level control over the memory allocation of variables
in DMA there are two major standard library malloc() and free. The malloc() function
takes a single input parameter which tells the size of the memory requested It returns
a pointer to the allocated memory. If the allocation fails, it returns NULL. The
prototype for the standard library function is like this:
void *malloc(size_t size);
The free() function takes the pointer returned by malloc() and de-allocates the
memory. No indication of success or failure is returned. The function prototype is like
this:
• malloc()
• calloc()
• free()
• realloc()
typedef provides an alias name to the existing complex type definition. With typedef,
you can simply create an alias for any type. Whether it is a simple integer to complex
function pointer or structure declaration, typedef will shorten your code.
The standard input library gets() reads user input till it encounters a new line character.
However, it does not check on the size of the variable being provided by the user is
under the maximum size of the data type which makes the system vulnerable to buffer
overflow and the input being written into memory where it isn’t supposed to.
We, therefore, use gets() to achieve the same with a restricted range of input
Bonus: It remained an official part of the language up to the 1999 ISO C standard, but
it was officially removed by the 2011 standard. Most C implementations still support it,
but at least GCC issues a warning for any code that uses it.
32. What is the difference between #include "..." and #include <...>?
In practice, the difference is in the location where the preprocessor searches for the
included file.
For #include <filename> the C preprocessor looks for the filename in the predefined
list of system directories first and then to the directories told by the user(we can use -I
option to add directories to the mentioned predefined list).
For #include "filename" the preprocessor searches first in the same directory as the file
containing the directive, and then follows the search path used for the #include
<filename> form. This method is normally used to include programmer-defined
header files.
33. What are dangling pointers? How are dangling pointers different
from memory leaks?
The dangling pointer points to a memory that has already been freed. The storage is
no longer allocated. Trying to access it might cause a Segmentation fault. A common
way to end up with a dangling pointer:
#include<stdio.h>
#include<string.h>
char *func()
{
char str[10];
strcpy(str,"Hello!");
return(str);
}
You are returning an address that was a local variable, which would have gone out of
scope by the time control was returned to the calling function. (Undefined behavior)
*c = malloc(5izeof(int));
free(c);
*c = 3; //writing to freed location!
In the figure shown above writing to a memory that has been freed is an example of
the dangling pointer, which makes the program crash.
A memory leak is something where the memory allocated is not freed which causes
the program to use an undefined amount of memory from the ram making it
unavailable for every other running program(or daemon) which causes the programs
to crash. There are various tools like O profile testing which is useful to detect memory
leaks on your programs.
void function(){
char *leak = malloc (10); //leak assigned but not freed
}
• Near Pointer: In general, the near pointer can be considered because it is used to hold
the address, which has a maximum size of just 16 bits. We can't store an address with a
size larger than 16 bits using the near pointer. All other smaller addresses that are
within the 16-bit limit, on the other hand, can be stored. Because we can only access
64kb of data at a time, you might assume the 16 bits are insufficient. As a result, it is
regarded as one of the near-pointer's biggest drawbacks, which is why it is no longer
commonly used.
• Far Pointer: A far pointer is considered a pointer of size 32 bits. It can, however, use
the current segment to access information stored outside the computer's memory.
Although, in order to use this type of pointer, we usually need to allocate the sector
register to store the data address in the current segment.
36. Which structure is used to link the program and the operating
system?
The file structure is used to link the operating system and a program. The header file
"stdio.h" (standard input/output header file) defines the file. It contains information
about the file being used like its current size and its memory location. It contains a
character pointer that points to the character which is currently being opened. When
you open a file, it establishes a link between the program and the operating system
about which file is to be accessed.
37. Suppose a global variable and local variable have the same name. Is
it possible to access a global variable from a block where local variables
are defined?
No. This isn’t possible in C. It’s always the most local variable that gets preference.
The following program will help you to remove duplicates from an array.
#include <stdio.h>
int main() {
int n, a[100], b[100], calc = 0, i, j,count;
printf("Enter no. of elements in array: ");
scanf("%d", &n);
printf("Enter %d integers: ", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
E.g.
#include<studio.h>
#define abc main
int abc ()
{
printf("Hello World ");
return 0;
}
41. Write a program to get the higher and lower nibble of a byte
without using shift operator?
#include<stdio.h>
struct full_byte
{
char first : 4;
char second : 4;
};
union A
{
char x;
struct full_byte by;
};
main()
{
char c = 100;
union A a;
a.x = c;
printf("the two nibbles are: %d and %d\n", a.by.first, a.by.second);
}
To override a defined macro we can use #ifdef and #undef preprocessors as follows:
• #ifdef A
• #undef A
• #endif
• #define A 10
If macro A is defined, it will be undefined using undef and then defined again using
define.
46. Can you tell me how to check whether a linked list is circular?
Circular linked list is a variation of a linked list where the last node is pointing to the
first node's information part. Therefore the last node does not point to null.
A very simple way to determine whether the linked list is circular or not
-Store the value of first node in temp variable and make it traverse all
nodes.
-temp-firstgode
-tempenext node pointed by temp(temp->next)
-run until temp is at null or firstNode
if (temp at null)
not circular and returns false
if (temp points first node)
return true as its circular.
}
-To insert new nodes and link each one of them to the previous node by
storing the address of the new node to the previous one.
-Then make them point to NULL.
}
-First insert nodes for circular linked list and check its nature by calling
isCircular function.
-Since it is true through if statement it prints "yes..
-Second insert a normal linked list and check its nature by calling
isCircular function. As its not circular it prints "no",
47. What is the use of a semicolon (;) at the end of every program
statement?
It is majorly related to how the compiler reads( or parses) the entire code and breaks it
into a set of instructions(or statements), to which semicolon in C acts as a boundary
between two sets of instructions.
To call a function before the main(), pragma startup directive should be used. E.g.-
In fun
In main
This pragma directive, on the other hand, is compiler-dependent. This is not supported
by gcc. As a result, it will ignore the startup directive and produce no error. But the
output, in that case, will be -
In main
Macros Functions
Macros are useful when a small piece of code is Functions are helpful when a large piece of
used multiple times in a program. code is repeated a number of times.
The difference between the Source Code and Object Code is that Source Code is a
collection of computer instructions written using a human-readable programming
language while Object Code is a sequence of statements in machine language, and is
the output after the compiler or an assembler converts the Source Code.
The last point about Object Code is the way the changes are reflected. When the
Source Code is modified, each time the Source Code needs to be compiled to reflect
the changes in the Object Code.
51. What are header files and what are its uses in C programming?
Header Files in C
In C header files must have the extension as .h, which contains function definitions,
data type definitions, macro, etc. The header is useful to import the above definitions
to the source code using the #include directive. For example, if your source code
needs to take input from the user do some manipulation and print the output on the
terminal, it should have stdio.h file included as #include <stdio.h>, with which we can
take input using scanf() do some manipulation and print using printf().
void PrintHello()
{
printf("Hello\n");
return; // the function does "return", but no value is
returned
}
Here we’ve declared a function, and all functions have a return type. In this case, we’ve
said the return type is “void”, and that means, “no data at all” is returned.
The other use for the void keyword is a void pointer. A void pointer points to the
memory location where the data type is undefined at the time of variable definition.
Even you can define a function of return type void* or void pointer meaning “at
compile time we don’t know what it will return” Let’s see an example of that.
Dynamic data structures play a key role in programming languages like C, C++, and
Java because they provide the programmer with the flexibility to adjust the memory
consumption of software programs.
For the sum of two numbers, we use the addition (+) operator. In these tricky C
programs, we will write a C program to add two numbers without using the addition
operator.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x, y;
printf("Enter two number: ");
scanf("%d %d",&x,&y);
// method 1
printf("%d\n", x-(-y));
// method 2
printf("%d\n", -(-x-y));
// method 3
printf("%d\n", abs(-x-y));
// method 4
printf("%d", x-(~y)-1);
return 0;
}
The bitwise complement operator is used in this program. The bitwise complement of
number ~y=-(y+1). So, expression will become x+(-(y+1))+1=x-y-1+1=x-y
The left shift operator shifts all bits towards the left by a certain number of specified
bits. The expression x<<1 always returns x*2. Note that the shift operator doesn’t work
on floating-point values.
For multiple of x by 4, use x<<2. Similarly x<<3 multiply x by 8. For multiple of the
number x by 2^n, use x<<n.
57. Check whether the number is EVEN or ODD, without using any
arithmetic or relational operators
#include<stdio.h>
int main()
{
int x;
printf("Enter a number: ");
scanf("%d", &x);
(x&1)?printf("Odd"):printf("Even");
return 0;
}
The bitwise and(&) operator can be used to quickly check the number is odd or even.
While you travel the linked list, change the current node's next pointer to point to its
previous element. reference to the previous nodes should be stored into a temp
variable as shown so that we don’t lose track of the swapped node. You also need
another pointer to store the next node before changing the reference. Also when we
are done return the new head of the reversed list.
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the
input string is valid.
Example 1:
Input: s = "()"
Output: true
Example 2:
Input: s = "()[]{}"
Output: true
Example 3:
Input: s = "(]"
Output: false
Below is the source code for C Program to Check for Balanced Parentheses using Stack
which is successfully compiled and run on Windows System to produce desired output
as shown below :
Fibonacci sequence is characterized by the fact that every number after the first two is
the sum of the two preceding ones. For example, consider below sequence
Where in F{n} = F{n-1} + F{n-2} with base values F(0) = 0 and <code>F(1) = 1
Below is naive implementation for finding the nth member of the Fibonacci sequence
int main()
{
int n = 8;
return 0;
}
61. Write a program to find the node at which the intersection of two
singly linked lists begins.
Let's take an example of the following two linked lists which intersect at node c1.
Solution -
• Get count of the nodes in the first list, let count be c1.
• Get count of the nodes in the second list, let count be c2.
• Get the difference of counts d = abs(c1 – c2)
• Now traverse the bigger list from the first node till d nodes so that from here onwards
both the lists have an equal no of nodes
• Then we can traverse both the lists in parallel till we come across a common node.
(Note that getting a common node is done by comparing the address of the nodes)
Merge two sorted linked lists and return them as a sorted list. The list should be made
by splicing together the nodes of the first two lists.
Merging Two Sorted Linked List
NodePtr merge_sorted(NodePtr head1, NodePtr head2) {
if (head1 != nullptr) {
mergedTail->next = head1;
} else if (head2 != nullptr) {
mergedTail->next = head2;
}
return mergedHead;
}
Runtime Complexity Linear, O(m + n) where m and n are lengths of both linked lists.
Maintain a head and a tail pointer on the merged linked list. Then choose the head of
the merged linked list by comparing the first node of both linked lists. For all
subsequent nodes in both lists, you choose the smaller current node and link it to the
tail of the merged list, moving the current pointer of that list one step forward.
You keep doing this while there are some remaining elements in both lists. If there are
still some elements in only one of the lists, you link this remaining list to the tail of the
merged list.
Initially, the merged linked list is NULL. Compare the value of the first two nodes and
make the node with the smaller value the head node of the merged linked list. In this
example, it is 4 from head1.
Since it’s the first and only node in the merged list, it will also be the tail. Then move
head1 one step forward.
Conclusion
C is the foundational language from which practically all other languages are built. C is
the programming language's base. For writing system applications, it is a very popular
and frequently used language. Even if new languages have surpassed it in popularity, it
remains one of the most popular programming languages. The C questions listed here
will aid you in interviews as well as improve your learning. I hope you found these to
be helpful!