Documente Academic
Documente Profesional
Documente Cultură
Experienced
Top 60 complex and advanced C Interview Questions and Answers for
Experienced programmers covering all aspects of C programming with detailed
explanations.
#include<stdio.h>
main()
{
int c;
printf("Hello%n world ",&c);
printf("%d", c);
}
#include <stdio.h>
main()
{
int a = 6;
int b = 10;
a ^= b;
b ^= a;
a ^= b;
printf("a: %d, b: %d\n", a, b);
}
7) Consider the two structures Struct A and Struct B given below. What
will be size of these structures?
struct A
{
unsigned char c1 : 3;
unsigned char c2 : 4;
unsigned char c3 : 1;
}a;
struct A
{
unsigned char c1 : 3;
unsigned char : 0;
unsigned char c2 : 4;
unsigned char c3 : 1;
}a;
The size of the structures will be 1 and 2. In case of first structure, the members
will be assigned a byte as follows -
7 6 5 4 3 2 1 0
c3 c2 c2 c2 c2 c1 c1 c1
8 7 6 5 4 3 2 1 0
c3 c2 c2 c2 c2 c1 c1 c1
The :0 field (0 width bit field) forces the next bit width member assignment to
start from the next nibble. By doing so, the c3 variable will be assigned a bit in
the next byte, resulting the size of the structure to 2.
8) How to call a function before main()?
To call a function pragma startup directive should be used. Pragma startup can
be used like this -
But this pragma directive is compiler dependent. Gcc does not support this. So,
it will ignore the startup directive and will produce no error. But the output in
that case will be -
In main
#pragma pack(1)
typedef struct A
{
char c;
int I;
}B;
In both cases the size of the structure will be 5. But remember, the pragma pack
and the other method mentioned, both are compiler dependent.
Method 2:
sscanf(str, “%d”, &i);
switch(i)
{
default:
printf("%d", i);
case 1:
printf("1\n");
case 2:
printf("2\n");
case 3:
printf("3\n");
}
}
Output of this program will be 3. The position of the default is before case 1.
So, even if there is no break after case 3, the execution will just exit switch case
and it will not go to default case.
13) How to prevent same header file getting included multiple times?
We can use ifndef and define preprocessors. Say the header file is hdrfile.h, then
we can write the header file like -
#ifndef _HDRFILE_H_
#define _HDRFILE_H_
#endif
The ifndef will check whether macro HDRFILE_H_ is defined or not. If it is not
defined, it will define the macro. From next time onward the statements inside
ifndef will not be included.
Enum values can be automatically generated by compiler if we let it. But all the
define values are to be mentioned specifically.
Macro is preprocessor, so unlike enum which is a compile time entity, source
code has no idea about these macros. So, the enum is better if we use a
debugger to debug the code.
If we use enum values in a switch and the default case is missing, some
compiler will give a warning.
Enum always makes identifiers of type int. But the macro let us choose between
different integral types.
Macro does not specifically maintain scope restriction unlike enum. For
example -
#include <stdio.h>
main()
{
{
#define A 10
printf("first A: %d\n", A);
}
{
printf("second A: %d\n", A);
}
}
first A: 10
second A: 10
The program will crash. The pointer p points to string “Pointers”. But the string
in constant and C will not allow to change its values. Forcibly doing so, like we
did it, will cause crash of the program.
16) What is the difference between const char* p and char const* p?
In const char* p, the character pointed by pointer variable p is constant. This
value can not be changed but we can initialize p with other memory location. It
means the character pointed by p is constant but not p. In char const* p, the
pointer p is constant not the character referenced by it. So we can't assign p with
other location but we can change the value of the character pointed by p.
void (*ptr)(int);
Here, ptr is a function pointer that can point to function with no return type and
one integer argument. After declaration, we can point to function Hello like this
-
void (*ptr)(int) = NULL;
ptr = Hello;
#include<stdio.h>
void Hello();
typedef void (*FP)();
FP fun(int);
main()
{
FP (*ptr)(int) = NULL;
FP p;
ptr = fun;
p = (*fun)(30);
(*p)();
}
void Hello()
{
printf("Hello\n");
}
FP fun(int a)
{
FP p = Hello;
printf("Number is : %d\n", a);
return p;
}
In this program, we have a function Hello with no return type and no argument.
The function fun takes an integer argument and returns a function pointer that
can point to Hello(). First we have typdef the function pointer which can point
to a function with no return type and argument with identifier FP. That way it
will be easier to define the required function pointer. If we avoid typedef the
required function pointer (ptr) will look like this -
void (*(*ptr)())(int)
22) 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);
}
23) How can you determine the size of an allocated portion of memory?
Ans: We can’t. During malloc or calloc system maintains a list for the pointer
allocated and sizeof memory which is used during free(). This is not accessible
to user.
Answer will be 49. The macro will be expanded like (++i) * (++i). But the ++
operator has higher precedence. So, the output will be 49.
Here if macro A is defined it will be undefined using undef and again defined
using define.
First: 5
Second: 0
Third: 1
main()
{
int i = 0;
DO_SOMETHING(i);
printf("\n%d", i + printf("1"));
}
Here a has type array[5] of int, and &a has type pointer to array[5] of int. So, ptr
will yield a pointer to the array[5] of int that comes after a. Subtracting 1 from
ptr will point to the last element of a which is 5. Remember, here &a and &a[0]
both will point to starting address of the array or the address of the first element.
But (&a + 1) points block of memory of size 5 times the sizeof int that comes
after the memory block of a, while (&a[0] + 1) return the address of the second
element.
30) Print the output of this C program on operator precedence?
#include <stdio.h>
int main(void)
{
int a, b, c, d;
a = 3;
b = 5;
c = a, b;
d = (a, b);
printf("c=%d ", c);
printf("d=%d\n", d);
return 0;
}
Output - 3 5
This program will give a compiler error: Cannot modify a constant value. Here
p is a pointer to a "constant integer". But in the printf function, we tried to
change the value of the "constant integer" which is not allowed in C and thus
the compilation error.
32) Print the output of this data comparison C program?
#include<stdio.h>
main()
{
float me = 1.1;
double you = 1.1;
if(me==you)
printf("I love U");
else
printf("I hate U");
}
Output is "I hate U"
For floating point numbers (float, double, long double) the values cannot be
predicted exactly. Depending on the number of bytes, the precession with of the
value represented varies. Float takes 4 bytes and long double takes 10 bytes. So
float stores 0.9 with less precision than long double. So comparing them will
result false and thus the “I hate U' string is printed. It is better to avoid
comparing different type of floating point numbers.
33) Guess the output of the backspace and carriage return C program?
#include<stdio.h>
main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}
Output is "hai"
The “\b” in C represents backspace and \r carriage return. The “\b” will erase
the last character printed in the output. So, the first printf feed a newline
character and then prints ab. The second printf first erases b from ab and then
prints si. Until now the output is asi. The third printf encounters the “\r” and
move the cursor back to the beginning of the line and then prints ha overwriting
the as of the asi. So, the final output will be hai.
34) Print the output of this recursive function C Program?
void add(int a, int b)
{
int c;
c = a + b;
add (1,1);
}
The function will lead to stack overflow. Here, there is no terminating condition
and that is why it leads to infinite recursion which results in STACK
OVERFLOW. When a function is called,
Here without proper termination condition, the recursion will continue and the
memory is allocated for all the recursion instances. After certain time the
memory allocated for the programs stack will be full and it will cause stack
overflow.
In this program the format specifier is a bit different from normal %s. After the
“%” operator the 10 forces to print minimum 10 characters to be printed in
output. The “.*” followed by that takes an integer argument and represents the
number of characters to be printed from the string followed. So, the argument i
with value 7 forces to print first 7 characters of the variable s. The remaining 3
characters are filled by preceding blank spaces.
36) Guess the condition in place of X which lead to print “Hello world” as
output?
if(X)
{
printf(“Hello”);
}
else
{
printf(“ world”);
}
The output will be same as sizeof(int). In case 64 bit machine it will be 4. The
sizeof operator will change the 'A' to its ASCII value and to the sizeof operator
that ASCII value is nothing but an integer.
Output of this program is 45545. The arguments in any function call are pushed
into the stack from left to right order. During evaluation those arguments are
popped out from the stack. So, ultimately. the evaluation is from right to left.
So, the last argument will result 5, the next one will result 4 and also the
variable i at that point will hold 4. The next one is again 5 and after that it is
again 5 as it is post decrement. The first one will return 4 and turn the value of i
to 5.
Program will produce the output - 64. The macro call square(4) will substituted
by 4*4 and the expression becomes i = 64/4*4 . Since / and * has equal priority
the expression will be evaluated based on the associativity which is left to right.
So, 64/4*4 will be equal to (64/4)*4 i.e. 16*4 = 64.
main()
{
struct A a = {4};
printf("%d %s %f\n", a.i, a.str, a.f);
}
Output - 0 0. The static storage class will initialize all the elements of the array
to 0. The 2nd element i.e. element with index 1 will be populated with 0 as the
increment is post increment. So, the output will be 0 0.
Output of this program is "Size of c is 1". Sizeof is an operator not function. So,
sizeof <variable_name> is a valid statement. But sizeof int is not. It will give
you compilation error. Better to use sizeof(<variable_name/data_type>) i.e.
enclosed in parenthesis.
Output is 12. The macro A will take two argument and paste them after word
cou. So when we called A(n,t), the macro will be replaced with count and print
the value 12. Here ## in macro pastes arguments and after replacement it ends
up with variable name not value.
44) How to use scanf to get a complete line(i.e upto '\n') from input?
Use scanf(“%[^\n]”, str). [^\n] is a regular expression that means until '\n' is
encountered.
Output will be 8. The size should be (4 + 1) or 5 but the compiler adds padding
and make its size multiple of 4.
main()
{
printf("%d", sizeof(fun()));
}
Output is 1. Even if this is function pointer, the sizeof will get the return type
and returns the size of that data type. Here, the return type is char, so the output
is 1.
Output will be "10 20". The %.0d forces compiler to print non negative values.
As c is 0, it will not be printed.
Condition will be fclose(stdout). It will close the stdout file handle and no
output will be printed.
main()
{
struct A a = { 15, 63};
printf("%d %d\n", a.i1, a.i2);
}
Output of this program is "7 15". The : 3 or :4 in the structure definition means
that i1 will be of unsigned int type, but it will be 3 bit long and i2 will be 4 bit
long. So, when we assign the value 15 to i1, it will only store the first 3 bits
which will result value 7. Same goes for i2. The value of i2 will be 15.
main()
{
printf("%s\n",C(A(1,2)));
printf("%s\n",B(A(1,2)));
}
55) What is the difference between void foo(void) and void foo()?
Ans: In C, void foo() means a function foo taking an unspecified number of
arguments of unspecified type and void foo(void) means a function foo taking
no arguments. So, in case of void foo(), if we call this function like foo(1,2,3),
the compiler will not raise any error. But the compiler will raise an error in case
of void foo(void).
When a function is called in C, the caller pushes all of the arguments, in reverse
order, into the stack before calling the callee. Using foo() means that the
compiler won't care to check the arguments passed to foo. In case of foo(void),
before calling the function compiler will specifically check the number of
arguments and will raise an error saying the mismatch between number of
arguments.
sizeof(++i) is: 4
i : 10
The sizeof operator is evaluated during compile time and also the expression
inside sizeof is not evaluated. The sizeof just takes the type of the expression.
Here sizeof(++i) is same as sizeof(int).
57) Print the output of this C program using Octel and Decimal?
#include <stdio.h>
main()
{
int a[] = {0001,0010,0100,1000};
int i;
Output
a[0] : 1
a[1] : 8
a[2] : 64
a[3] : 1000
The array elements are 0001,0010,0100,1000. As first three element has
preceding 0, the compiler will treat them as octal numbers. So, 0001 in octal is 1
in decimal; 0010 in octal is same as 8 in decimal and 0100 in octal is equivalent
to 64 in decimal. But the last element has no preceding 0, so the last element
will have value 1000.
Output is 4. The '!' operator takes an argument and return 1 if the value is 0 and
0 otherwise. So, !2.3 is 0. To sizeof 0 is an integer and so the output is 4.
59) Print the output of C program given below using strlen and sizeof
operator?
#include<string.h>
#include <stdio.h>
main()
{
printf("%d %d", sizeof("string"), strlen("string"));
}
Output is "7 6". The sizeof return the number of characters including the null
character, but strlen returns number of characters without null character.
61) Guess the output of this C program having a pointer in the main
function?
#include<stdio.h>
void func(int *a)
{
int x = 1;
a = &x;
}
main()
{
int i = 2;
int *p = &i;
func(p);
printf("%d", *p);
}
Output is 2. The pointer a in function func is a local copy of pointer p. So, even
if we assign another location to a, it will not be reflected on the p in main
function. The p will point to location of i and will print 2 as result.
It has since spread to many other operating systems, and is one of the
most widely used programming languages. C is prized for its
efficiency, and is the most popular programming language for writing
system software, though it is also used for writing applications.
C. Some compilers check the format string and will generate an error
without the proper number and type of arguments for things like
printf(...) and scanf(...).
Size of the final executable can be reduced using dynamic linking for
libraries.
Create two pointers, and set both to the start of the list. Update each
as follows:
while (pointer1) {
pointer1 = pointer1->next;
pointer2 = pointer2->next;
if (pointer2) pointer2=pointer2->next;
if (pointer1 == pointer2) {
print ("circular");
}}
#include
main() {
typedef union {
int a;
char b[10];
float c;
}
Union;
Union x,y = {100};
x.a = 50;
strcpy(x.b,"hello");
x.c = 21.50;
printf("Union x : %d %s %f n",x.a,x.b,x.c);
printf("Union y : %d %s %f n",y.a,y.b,y.c);
}
Macros are a necessary evils of life. The purists don’t like them, but
without it no real work gets done.
Variables with block scope, and with static specifier have static scope.
Global variables (i.e, file scope) with or without the static specifier
also have static scope.
A major difference is: string will have static storage duration, whereas
as a character array will not, unless it is explicity specified by using
the static keyword. Actually, a string is a character array with
following properties:
* Two strings of same value[1] may share same memory area. For
example, in the following declarations:
[1] The value of a string is the sequence of the values of the contained
characters, in order.
13. What is the difference between const char* p and char const*
p?
In char const* p, the ptr ‘p’ is constant not the character referenced by
it, so u cant make ‘p’ to reference to any other location but u can
change the value of the char pointed by ‘p’.
To hash means to grind up, and that’s essentially what hashing is all
about. The heart of a hashing algorithm is a hash function that takes
your nice, neat data and grinds it into some random-looking integer.
The idea behind hashing is that some data either has no inherent
ordering (such as images) or is expensive to compare (such as
images). If the data has no inherent ordering, you can’t perform
comparison searches.
If the data is expensive to compare, the number of comparisons used
even by a binary search might be too many. So instead of looking at
the data themselves, you’ll condense
(hash) the data to an integer (its hash value) and keep all the data with
the same hash value in the same place. This task is carried out by
using the hash value as an index into an array.
To search for an item, you simply hash it and look at all the data
whose hash values match that of the data you’re looking for. This
technique greatly lessens the number of items you have to look at. If
the parameters are set up with care and enough storage is available for
the hash table, the number of comparisons needed to find an item can
be made arbitrarily close to one.
There are two ways to resolve this problem. In open addressing, the
collision is resolved by the choosing of another position in the hash
table for the element inserted later. When the hash table is searched, if
the entry is not found at its hashed position in the table, the search
continues checking until either the element is found or an empty
position in the table is found.
You can’t, really. free() can , but there’s no way for your program to
know the trick free() uses. Even if you disassemble the library and
discover the trick, there’s no guarantee the trick won’t change with
the next release of the compiler.
Yes. The const modifier means that this code cannot change the value
of the variable, but that does not mean that the value cannot be
changed by means outside this code.
19. When does the compiler not implicitly generate the address of
the first element of an array?
Then the compiler does not implicitly generate the address of the
address of the first element of an array.
Streams can be classified into two types: text streams and binary
streams. Text streams are interpreted, with a maximum length of 255
characters. With text streams, carriage return/line feed combinations
are translated to the newline n character and vice versa. Binary
streams are uninterrupted and are treated one byte at a time with no
translation of characters. Typically, a text stream would be used for
reading and writing standard text files, printing output to the screen or
printer, or receiving input from the keyboard.
A binary text stream would typically be used for reading and writing
binary files such as graphics or word processing documents, reading
mouse input, or reading and writing to the modem.
22. What is static memory allocation and dynamic memory
allocation?
Sometimes you can get away with using a small memory model in
most of a given program. There might be just a few things that don’t
fit in your small data and code segments.
When that happens, you can use explicit far pointers and function
declarations to get at the rest of memory. A far function can be
outside the 64KB segment most functions are shoehorned into for a
small-code model. (Often, libraries are declared explicitly far, so
they’ll work no matter what code model the program uses.) A far
pointer can refer to information outside the 64KB data segment.
Typically, such pointers are used with farmalloc() and such, to
manage a heap separate from where all the rest of the data lives. If
you use a small-data, large-code model, you should explicitly make
your function pointers far.
- Pointers are used to manipulate data using the address. Pointers use
* operator to access the data pointed to by them
No. The exit() function is used to exit your program and return control
to the operating system. The return statement is used to return from a
function and return control to the calling function. If you issue a
return from the main() function, you are essentially returning control
to the calling function, which is the operating system. In this case, the
return statement and exit() function are similar.
27. What is a method?
Declaring a variable means describing its type to the compiler but not
allocating any space for it. Defining a variable means declaring it and
also allocating space to hold the variable. You can also initialize a
variable at the time it is defined.
The “value” of an array is the same as the address of (or a pointer to)
the first element; so, frequently, a C string and a pointer to char are
used to mean the same thing.
1)The storage for an external variable exists even when the variable is
not needed
2)The side effect may produce surprising output
3)Modification of the program is difficult
4)Generality of a program is affected
In C and C++, any time you need a void pointer, you can use another
pointer type. For example, if you have a char*, you can pass it to a
function that expects a void*. You don’t even need to cast it. In C (but
not in C++), you can use a void* any time you need any kind of
pointer, without casting. (In C++, you need to cast it).
A void pointer is used for working with raw memory or for passing a
pointer to an unspecified type. Some C code operates on raw memory.
When C was first invented, character pointers (char *) were used for
that. Then people started getting confused about when a character
pointer was a string, when it was a character array, and when it
was raw memory.
A switch statement is generally best to use when you have more than
two conditional expressions based on a single variable of numeric
type.
Examples:
1) The operators >> and << may be used for I/O operations because in
the header, they are overloaded.
When your program calls setjmp(), the current state of your program
is saved in a structure of type jmp_buf. Later, your program can call
the longjmp() function to restore the program’s state as it was when
you called setjmp().Unlike the goto statement, the longjmp() and
setjmp() functions do not need to be implemented in the same
function.