100 c interview questions, your interviewer might ask

c interview questions

I have received a lot of emails from my subscriber to create the collection of some important basic c interview questions that are generally asked by an interviewer. So here I have tried to create a collection of some important c interview questions that might be asked by your interviewer.

What is the difference between declaration and definition of a variable?

Answer:

Declaration of a variable in c

A variable declaration only provides sureness to the compiler at the compile time that variable exists with the given type and name, so that compiler proceeds for further compilation without needing all detail of this variable. In C language, when we declare a variable, then we only give the information to the compiler, but there is no memory reserve for it. It is only a reference, through which we only assure to the compiler that this variable may be defined within the function or outside of the function.

Note: We can declare a variable multiple time but defined only once.
eg,
extern int data;
extern int foo(int, int);
int fun(int, char); // extern can be omitted for function declarations

Definition of a variable in c

The definition is action to allocate storage to the variable. In another word, we can say that variable definition is the way to say the compiler where and how much to create the storage for the variable generally definition and declaration occur at the same time but not almost.

eg,
int data;
int foo(int, int) { }

Note: When you define a variable then there is no need to declare it but vice versa is not applicable.


What is the variable in C?

Answer:

A variable defines a location name where we can put the value and we can use this value whenever required in the program. In another word, we can say that variable is a name (or identifier) which indicate some physical address in the memory, where data will be stored in form of the bits of string.

In C language, every variable has a specific data types (pre-defined or user-defined) that determine the size and memory layout of the variable.

Note: Each variable bind with two important properties, scope, and extent.


Using the variable p write down some declaration

  1. An integer variable.
  2. An array of five integers.
  3. A pointer to an integer.
  4. An array of ten pointers to integers.
  5. A pointer to a pointer to an integer.
  6. A pointer to an array of three integers.
  7. A pointer to a function that takes a pointer to a character as an argument and returns an integer.
  8. An array of five pointers to functions that take an integer argument and return an integer.

Answer:

  1. int p; // An integer
  2. int p[5]; // An array of 5 integers
  3. int *p; // A pointer to an integer
  4. int *p[10]; // An array of 10 pointers to integers
  5. int **p; // A pointer to a pointer to an integer
  6. int (*p)[3]; // A pointer to an array of 3 integers
  7. int (*p)(char *); // A pointer to a function a that takes an integer
  8. int (*p[5])(int); // An array of 5 pointers to functions that take an integer argument and return an integer

Some Questions related to declaration for you

  1. int* (*fpData)(int , char, int (*paIndex)[3]);
  2. int* (*fpData)(int , int (*paIndex)[3] , int (* fpMsg) (const char *));
  3. int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));
  4. int* (*fpData[2])(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));
  5. int* (*(*fpData)(const char *))(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));

 

If you love online courses, I recommend you to see this video course, 10 days trial is free.

C tutorial

What are the data types in C?

Answer:

There are two types of data type, user-defined and predefined. A predefined data type is int, char, float, double etc and user-defined is created by the users using the tags struct, union or enum. Basically, data types describe the size and memory layout of the variable.

In C language, different data types have the different ranges. The range varies from compiler to compiler. In below table, I have listed some data types with there ranges and format specifier as per the 32-bit GCC compiler.


What are storage classes in C language?

Answer:

The storage classes decide the extent (lifetime) and scope (visibility) of a variable or function within the program. Every variable gets some location in the memory where variable’s value is stored in form of bits. Storage class defines the storage location of the variable like CPU register or memory (like the stack, BSS, DS).

There are four different storage class in C.

  • auto
  • static
  • extern
  • register

What are the uses of the keyword static?

Answer:

In C language, the static keyword has a lot of importance. If we have used the static keyword with a variable or function, then only internal or none linkage is worked. I have described some simple use of a static keyword.

  • A static variable only initializes once, so a variable declared static within the body of a function maintains its prior value between function invocations.
  • A global variable with static keyword has an internal linkage, so it only accesses within the translation unit (.c). It is not accessible by another translation unit. The static keyword protects your variable to access from another translation unit.
  • By default in C language, linkage of the function is external that it means it is accessible by the same or another translation unit. With the help of the static keyword, we can make the scope of the function local, it only accesses by the translation unit within it is declared.

What is the difference between global and static global variables?

Answer:

In simple word, they have different linkage.

A static global variable            ===>>>  internal linkage.
A non-static global variable  ===>>>  external linkage.

So global variable can be accessed outside of the file but the static global variable only accesses within the file in which it is declared.


Differentiate between an internal static and external static variable?

Answer:

In C language, the external static variable has the internal linkage and internal static variable has no linkage. So the life of both variable throughout the program but scope will be different.

A external static variable  ===>>>  internal linkage.
A internal static variable   ===>>>  none .


What are the different types of linkage?

Answer:

The C language has three types of linkage, external linkage, internal linkage and none linkage.


Can static variables be declared in a header file?

Answer:

Yes, we can declare the static variables in a header file.


Size of the integer depends on what?

Answer:

The C standard is explained that the minimum size of the integer should be 16 bits. Some programing language is explained that the size of the integer is implementation dependent but portable programs shouldn’t depend on it.

Primarily size of integer depends on the type of the compiler which has written by compiler writer for the underlying processor. You can see compilers merrily changing the size of integer according to convenience and underlying architectures.So it is my recommendation use the C99 integer data types ( uin8_t, uin16_t, uin32_t ..) in place of standard int.


Are integers signed or unsigned?

Answer:

In standard C language, integer data type is by default signed. So if you create an integer variable, it can store both positive and negative value.

For more details on signed and unsigned integer, check out:
A closer look at signed and unsigned integers in C


What is a difference between unsigned int and signed int in C?

Answer:

The signed and unsigned integer type has the same storage (according to the standard at least 16 bits) and alignment but still, there is a lot of difference them, in bellows lines, I am describing some difference between the signed and unsigned integer.

  • A signed integer can store the positive and negative value both but beside it unsigned integer can only store the positive value.
  • The range of nonnegative values of a signed integer type is a sub-range of the corresponding unsigned integer type.
    For example,
    Assuming size of the integer is 2 bytes.
    signed int -32768 to +32767
    unsigned int 0 to 65535
  • When computing the unsigned integer, it never gets overflow because if the computation result is greater than the largest value of the unsigned integer type, it is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
    For example,
    Computational Result % (Largest value of the unsigned integer+1)
  • The overflow of signed integer type is undefined.
  • If Data is signed type negative value, the right shifting operation of Data is implementation dependent but for the unsigned type, it would be Data/ 2pos.
  • If Data is signed type negative value, the left shifting operation of Data show the undefined behavior but for the unsigned type, it would be Data x 2pos.




What is the difference between a macro and a function?

Answer:

macro VS function


What is the difference between typedef & Macros?

Answer:

typedef:

The C language provides a very important keyword typedef for defining a new name for existing types. The typedef is the compiler directive mainly use with user-defined data types (structure, union or enum) to reduce their complexity and increase the code readability and portability.

Syntax,
typedef type NewTypeName;

Let’s take an example,
typedef unsigned int UnsignedInt;

Now UnsignedInt is a new type and using it, we can create a variable of unsigned int.

UnsignedInt Mydata;
In above example, Mydata is variable of unsigned int.

Note: A typedef creates synonyms or a new name for existing types it does not create new types.

Macro:

A macro is a pre-processor directive and it replaces the value before compiling the code.One of the major problem with the macro that there is no type checking. Generally, the macro is used to create the alias, in C language macro is also used as a file guard.

Syntax,

#define Value 10

Now Value becomes 10, in your program, you can use the Value in place of the 10.


Training.LinuxFoundation.org

What do you mean by enumeration in C?

Answer:

In C language enum is user-defined data type and it consists a set of named constant integer. Using the enum keyword, we can declare an enumeration type by using the enumeration tag (optional) and a list of named integer.

An enumeration increases the readability of the code and easy to debug in comparison of symbolic constant (macro).

The most important thing about the enum is that it follows the scope rule and compiler automatic assign the value to its member constant.

Note: A variable of enumeration type stores one of the values of the enumeration list defined by that type.

Syntax of enum,
enum Enumeration_Tag { Enumeration_List };

The Enumeration_Tag specifies the enumeration type name.

The Enumeration_List is a comma-separated list of named constant.

Example,
enum FLASH_ERROR { DEFRAGMENT_ERROR, BUS_ERROR};.


What does the keyword const mean?

Answer:

A const is only a qualifier, it changes the behavior of a variable and makes it read-only type. When we want to make an object read-only type, then we have to declare it as const.

Syntax
const DataType Identifier = Value;
e.g.
const int iData = 0;

const

At the time of declaration, const qualifier only gives the direction to the compiler that the value of declaring object could not be changed. In simple word, const means not modifiable (cannot assign any value to the object at the runtime).


When should we use const in a C program?

Answer:

There are following places where we need to use the const keyword in the programs.

  • In call by reference function argument, if you don’t want to change the actual value which has passed in function.
    Eg.
    int PrintData ( const char *pcMessage);
  • In some places, const is better then macro because const handle by the compiler and have a type checking.
    Eg.
    const int ciData = 100;
  • In the case of I/O and memory mapped register const is used with the volatile qualifier for efficient access.
    Eg.
    const volatile uint32_t *DEVICE_STATUS = (uint32_t *) 0x80102040;
  • When you don’t want to change the value of an initialized variable.

What is the meaning of below declarations?

  1. const int a;
  2. int const a;
  3. const int *a;
  4. int * const a;
  5. int const * a const;

Answer:

  1. The “a” is a constant integer.
  2. Similar to first, “a” is a constant integer.
  3. Here “a” is a pointer to a const integer, the value of the integer is not modifiable, but the pointer is not modifiable.
  4. Here “a” is a const pointer to an integer, the value of the pointed integer is modifiable, but the pointer is not modifiable.
  5. Here “a” is a const pointer to a const integer that means the value of pointed integer and pointer both are not modifiable.

Differentiate between a constant pointer and pointer to a constant?

Answer:

Constant pointer:

A constant pointer is a pointer whose value (pointed address) is not modifiable. If you will try to modify the pointer value, you will get the compiler error.

A constant pointer is declared as follows :
Data_Type * const Pointer_Name;

Let’s see the below example code when you will compile the below code get the compiler error.

Pointer to a constant:

In this scenario the value of pointed address is constant that means we can not change the value of the address that is pointed by the pointer.

A constant pointer is declared as follows :
Data_Type  const*  Pointer_Name;

Let’s take a small code to illustrate a pointer to a constant:





What are the post increment and decrement operators?

Answer:

When we use post-increment (++) operator on an operand then the result is the value of the operand and after getting the result, the value of the operand is incremented by 1. The working of the post-decrement (–) operator is similar to the post-increment operator but the difference is that the value of the operand is decremented by 1.

Note: incrementation and decrementation by 1 are the types specified.


Which one is better: Pre-increment or Post increment?

Answer:

Nowadays compiler is enough smart, they optimize the code as per the requirements. The post and pre increment both have own importance we need to use them as per the requirements.

If you are reading a flash memory byte by bytes through the character pointer then here you have to use the post-increment, either you will skip the first byte of the data. Because we already know that in case of pre-increment pointing address will be increment first and after that, you will read the value.

Let’s take an example of the better understanding,
In below example code, I am creating a character array and using the character pointer I want to read the value of the array. But what will happen if I used pre-increment operator? The answer to this question is that ‘A’ will be skipped and B will be printed.

But in place of pre-increment if we use post-increment then the problem is getting solved and you will get A as the output.

Besides that, when we need a loop or just only need to increment the operand then pre-increment is far better than post-increment because in case of post increment compiler may have created a copy of old data which takes extra time. This is not 100% true because nowadays compiler is so smart and they are optimizing the code in a way that makes no difference between pre and post-increment. So it is my advice, if post-increment is not necessary then you have to use the pre-increment.

Note: Generally post-increment is used with array subscript and pointers to read the data, otherwise if not necessary then use pre in place of post-increment.Some compiler also mentioned that to avoid to use post-increment in looping condition.
iLoop = 0.





Are the expressions *ptr ++ and ++*ptr same ?

Answer:

Both expressions are different. Let’s see a sample code to understand the difference between both expressions.

Output: 101 , 200 , 101

Explanation:
In the above example, two operators are involved and both have the same precedence with a right to left associativity. So the above expression ++*p is equivalent to ++ (*p). In another word, we can say it is pre-increment of value and output is 101, 200, 101.

Output: 100, 200, 200

Explanation:
In the above example, two operators are involved and both have the same precedence with the right to left associativity. So the above expression *++p is equivalent to *(++p). In another word you can say it is pre-increment of address and output is 100, 200,200.


What is the difference between const and macro?

Answer:

  1. The const keyword is handled by the compiler, in another hand, a macro is handled by the preprocessor directive.
  2. const is a qualifier that is modified the behavior of the identifier but macro is preprocessor directive.
  3. There is type checking is occurred with const keyword but does not occur with #define.
  4. const is scoped by C block, #define applies to a file.
  5. const can be passed as a parameter (as a pointer) to the function.In case of call by reference, it prevents to modify the passed object value.

What is a volatile variable in C?

Answer:

The volatile keyword is a type qualifier that prevents the objects from the compiler optimization.According to C standard, an object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects.You can also say that the value of the volatile-qualified object can be changed at any time without any action being taken by the code.

If an object is qualified by the volatile qualifier, the compiler reloads the value from memory each time it is accessed by the program that means it prevents from to cache a variable into a register.Reading the value from the memory is the only way to check the unpredictable change of the value.


Can we have a volatile pointer?

Answer:

Yes, we can create a volatile pointer in C language.
int * volatile piData; // piData is a volatile pointer to an integer.


The Proper place to use the volatile keyword?

Answer:

Here I am pointing some important places where we need to use the volatile keyword.

  • Accessing the memory-mapped peripherals register or hardware status register.

  • Sharing the global variables or buffers between the multiple threads.
  • Accessing the global variables in an interrupt routine or signal handler.


What is the difference between the const and volatile qualifier in C?

Answer:

The const keyword is compiler-enforced and says that program could not change the value of the object that means it makes the object nonmodifiable type.
e.g,
const int a = 0;
if you will try to modify the value of “a”, you will get the compiler error because “a” is qualified with const keyword that prevents to change the value of the integer variable.

In another side volatile prevent from any compiler optimization and says that the value of the object can be changed by something that is beyond the control of the program and so that compiler will not make any assumption about the object.
e.g,
volatile int a;

When the compiler sees the above declaration then it avoids to make any assumption regarding the “a” and in every iteration read the value from the address which is assigned to the variable.


Can a variable be both constant and volatile in C?

Answer:

Yes, we can use both constant and volatile together. One of the great use of volatile and const keyword together is at the time of accessing the GPIO registers. In case of GPIO, its value can be changed by the ‘external factors’ (if a switch or any output device is attached with GPIO), if it is configured as an input. In that situation, volatile plays an important role and ensures that the compiler always read the value from the GPIO address and avoid to make any assumption.

After using the volatile keyword, you will get the proper value whenever you are accessing the ports but still here is one more problem because the pointer is not const type so it might be your program change the pointing address of the pointer. So we have to create a constant pointer with volatile keyword.

Syntax of declaration,

int volatile * const PortRegister;

How to read the above declaration,

Consider a simple below example:

 

#define PORTX 0x00020000 // Address of the GPIO

uint32_t volatile * const pcPortReg = (uint32_t *) PORTX;

The pcPortReg is a constant pointer to a volatile unsigned integer, using *pcPortReg we can access the memory-mapped register.

*pcPortReg = value; // Write value to the port
value = *pcPortReg; // Read value from the port


How to set, clear, toggle and checking a single bit in C?

Answer:

Setting a Bits
Bitwise OR operator (|) use to set a bit of integral data type. “OR” of two bits is always one if any one of them is one.

Number | = (1<< nth Position)

Clearing a Bits
Bitwise AND operator (&) use to clear a bit of integral data type. “AND” of two bits is always zero if any one of them is zero.To clear the nth bit, first, you need to invert the string of bits then AND it with the number.

Number &= ~ (1<< nth Position)

Checking a Bits
To check the nth bit, shift the ‘1’ nth position toward the left and then “AND” it with the number.

Bit = Number & (1 << nth)

Toggling a Bits
Bitwise XOR (^) operator use to toggle the bit of an integral data type. To toggle the nth bit shift the ‘1’ nth position toward the left and “XOR” it.

Number ^= (1<< nth Position)


Detect if two Integers have opposite Signs (Bit Manipulation)

Answer:

Let the given integers are “a” and “b”. The EX-OR of sign bit (MSB) of “a” and “b” will be 1 if the sign bit of “a” is different from the sign bit of “b”. In other words, we can say, EX-OR of “a” and “b” will be negative if “a” and “b” have the opposite signs.

Note: bool exists in the current C – C99.


Write an Efficient C Program to Reverse Bits of a Number?

Answer:

There are a lot of ways to reverse the bits of a number, here I am describing three general methods to reverse the bits.

Method 1:

In this method, we will check the set bits of num and run the loop through all the bits of an integer.If we find the ith bits of num is set then just put 1 at the ((INT_BITS – 1) – ith ) position of tmp, where INT_BITS is the number of bits of an integer.

Method 2:

It is a simple algorithm to reverse bits of the 32-bit integer. This algorithm uses the eight constant value for the reversing the bits and takes five simple steps.

In below section, I am describing the functioning of each step.

Steps 1:
num = (((num & 0xaaaaaaaa) >> 1) | ((num & 0x55555555) << 1));

This expression used to swap the bits.
Let an example, suppose num is 0100, after the above expression it will be 1000.

Steps 2:
num = (((num & 0xcccccccc) >> 2) | ((num & 0x33333333) << 2));

Above expression uses to swap the 2 bits of a nibble. Suppose num is 10 00, after the above expression, it will be 00 01.

Steps 3:
num = (((num & 0xf0f0f0f0) >> 4) | ((num & 0x0f0f0f0f) << 4));

An expression used to swaps the nibbles. like if num is 0011 0010 then after the above expression it will be 0010 0011.

Steps 4:
num = (((num & 0xff00ff00) >> 8) | ((num & 0x00ff00ff) << 8));

This statement uses to swap the bytes of an integer. Let num is 00001000 00001100, after the above expression, it will be 00001100 00001000.

Steps 5:
((num >> 16) | (num << 16));

The above expression uses to swap the half-word of an integer. Means that if the num is 0000000011001110 1000100100000110 after the above result number will be 1000100100000110 0000000011001110.

Third Method:

This is the simplest method to reverse the bits of an integer. In which we create a table of the hex value from 0 to 255. In this method, we are performing the AND operation of data with 0xFF to calculate the index of the array.

In this algorithm, we need to calculate the index of the array (look-up table) four times to get the appropriate value from the look-up table. After getting the corresponding value, we will perform the bit shifting operation to get the reverse value.


How to print a decimal number in binary format in C?

Answer:


What is the output of the below program?

Answer:

8


What is the output of the below program?

Answer:

15


What is the output of the below program?

Answer:

2


Write a program swap two numbers without using the third variable?

Answer:

Let’s assume a, b two numbers, there are a lot of methods two swap two number without using the third variable.

Method 1( (Using Arithmetic Operators):

Method 2 (Using Bitwise XOR Operator):


Write a program to check an integer is a power of 2?

Answer:

Here, I am writing a small algorithm to check the power of 2. If a number is a power of 2, function return 1.


What is the output of the below code?

Answer:

undefined behavior.


What is the output of the below code?

Answer:

implementation-defined.


Write a program to count set bits in an integer?

Answer:


When should we use pointers in a C program?

Answer:

  • To pass large structure liked server request or response packet.
  • To implement the linked list and binary trees.
  • To play with GPIO or hardware register.
  • To get the address or update value from the function (call by reference)
  • To create the dynamic array.
  • To create call back function using the function pointer.

Note: Besides it, lots of places where the need to use the pointer.


What is void or generic pointers in C?

Answer:

A void pointer is a generic pointer. It has no associated data type that’s why it can store the address of any type of object and type-casted to any types.

According to C standard, the pointer to void shall have the same representation and alignment requirements as a pointer to a character type.A void pointer declaration is similar to the normal pointer, but the difference is that instead of data types we use the void keyword.

Syntax:
void * Pointer_Name;


What is the advantage of a void pointer in C?

Answer:

There are following advantages of a void pointer in c.

  • Using the void pointer we can create a generic function that can take arguments of any data type. The memcpy and memmove library function are the best examples of the generic function, using these function we can copy the data from the source to destination.
    e.g.
    void * memcpy ( void * dst, const void * src, size_t num );
  • We have already know that void pointer can be converted to another data type that is the reason malloc, calloc or realloc library function return void *. Due to the void * these functions are used to allocate memory to any data type.
  • Using the void * we can create a generic linked list.For more information see this link: How to create generic Link List.

What are dangling pointers?

Answer:

Generally, daggling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers. It creates the problem because the pointer is still pointing the memory that is not available. When the user tries to dereference the daggling pointers than it shows the undefined behavior and can be the cause of the segmentation fault.

For example,

In simple word, we can say that dangling pointer is a pointer that not pointing a valid object of the appropriate type and it can be the cause of the undefined behavior.


What is the wild pointer?

Answer:

A pointer that is not initialized properly prior to its first use is known as the wild pointer. Uninitialized pointers behavior is totally undefined because it may point some arbitrary location that can be the cause of the program crash, that’s is the reason it is called a wild pointer.

In the other word, we can say every pointer in programming languages that are not initialized either by the compiler or programmer begins as a wild pointer.

Note: Generally, compilers warn about the wild pointer.

Syntax,
int *piData; //piData is wild pointer


What is a NULL pointer?

Answer:

According to C standard, an integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer.

wild pointerSyntax,
int *piData = NULL; // piData is a null pointer


What is a Function Pointer?

Answer:

A function pointer is similar to the other pointers but the only difference is that it points to a function instead of the variable.

In the other word, we can say, a function pointer is a type of pointer that store the address of a function and these pointed function can be invoked by function pointer in a program whenever required.

 


How to declare a pointer to a function in c?

Answer:

The syntax for declaring function pointer is very straightforward. It seems like difficult in beginning but once you are familiar with function pointer then it becomes easy.

The declaration of a pointer to a function is similar to the declaration of a function. That means function pointer also requires a return type, declaration name, and argument list. One thing that you need to remember here is, whenever you declare the function pointer in the program then declaration name is preceded by the * (Asterisk) symbol and enclosed in parenthesis.

For example,

void ( *fpData )( int );

For the better understanding, let’s take an example to describe the declaration of a function pointer in c.
e.g,
void ( *pfDisplayMessage) (const char *);

In above expression, pfDisplayMessage is a pointer to a function taking one argument, const char *, and returns void.

When we declare a pointer to function in c then there is a lot of importance of the bracket. If in the above example, I remove the bracket, then the meaning of the above expression will be change and it becomes void *pfDisplayMessage (const char *). It is a declaration of a function which takes the const character pointer as arguments and returns void pointer.


Where can the function pointers be used?

Answer:

There are a lot of places, where the function pointers can be used. Generally, function pointers are used in the implementation of the callback function, finite state machine and to provide the feature of polymorphism in C language …etc.


What is the difference between array and pointer in c?

Answer:

Here is one important difference between array and pointer is that address of the element in an array is always fixed we cannot modify the address at execution time but in the case of pointer we can change the address of the pointer as per the requirement.

Consider the below example:
In below example when trying to increment the address of the array then we will get the compiler error.

Note: When an array is passed to a function then it decays its pointer to the first element.


What is static memory allocation and dynamic memory allocation?

Answer:

According to C standard, there are four storage duration, static, thread (C11), automatic, and allocated. The storage duration determines the lifetime of the object.

The static memory allocation:

Static Allocation means, an object has external or internal linkage or declared with static storage-class. It’s initialized only once, prior to program startup and its lifetime is throughout the execution of the program. A global and static variable is an example of static memory allocation.

The dynamic memory allocation:

In C language, there are a lot of library functions (malloc, calloc, or realloc,..) which are used to allocate memory dynamically. One of the problems with dynamically allocated memory is that it is not destroyed by the compiler itself that means it is the responsibility of the user to deallocate the allocated memory.

When we allocate the memory using the memory management function, they return a pointer to the allocated memory block and the returned pointer is pointing to the beginning address of the memory block. If there is no space available, these functions return a null pointer.


What is the memory leak in C?

Answer:

A memory leak is a common and dangerous problem. It is a type of resource leak. In C language, a memory leak occurs when you allocate a block of memory using the memory management function and forget to release it.

Note: once you allocate a memory than allocated memory does not allocate to another program or process until it gets free.


What is the difference between malloc and calloc?

Answer:

The malloc and calloc are memory management functions. They are used to allocate memory dynamically. Basically, there is no actual difference between calloc and malloc except that the memory that is allocated by calloc is initialized with 0.

In C language,calloc function initialize the all allocated space bits with zero but malloc does not initialize the allocated memory. These both function also has a difference regarding their number of arguments, malloc take one argument but calloc takes two.





What is the purpose of realloc( )?

Answer:

The realloc function is used to resize the allocated block of memory. It takes two arguments first one is a pointer to previously allocated memory and the second one is the newly requested size.

The calloc function first deallocates the old object and allocates again with newly specified size. If the new size is lesser to the old size, the contents of the newly allocated memory will be same as prior but if any bytes in the newly created object goes beyond the old size, the values of the exceeded size will be indeterminate.

Syntax:
void *realloc(void *ptr, size_t size);

Output:
pcBuffer = aticle
pcBuffer = aticleworld

Note: It should be used for dynamically allocated memory but if a pointer is a null pointer, realloc behaves like the malloc function.


What is the return value of malloc (0)?

Answer:

If the size of the requested space is zero, the behavior will be implementation-defined. The return value of the malloc could be a null pointer or it shows the behavior of that size is some nonzero value.It is suggested by the standard to not use the pointer to access an object that is returned by the malloc while size is zero.


What is dynamic memory fragmentation?

Answer:

The memory management function is guaranteed that if memory is allocated, then it would be suitably aligned to any object which has the fundamental alignment. The fundamental alignment is less than or equal to the largest alignment that’s supported by the implementation without an alignment specification.

One of the major problems with dynamic memory allocation is fragmentation, basically, fragmentation occurred when the user does not use the memory efficiently. There are two types of fragmentation, external fragmentation, and internal fragmentation.

The external fragmentation is due to the small free blocks of memory (small memory hole) that is available on the free list but program not able to use it. There are different types of free list allocation algorithms that used the free memory block efficiently.

To understand the external fragmentation, consider a scenario where a program has 3 contiguous blocks of memory and the user frees the middle block of memory. In that scenario, you will not get a memory, if the required block of memory is larger than a single block of memory (but smaller or equal to the aggregate of the block of memory).

External Fragmentation

The internal fragmentation is the wasted of memory that is allocated for rounding up the allocated memory and in bookkeeping (infrastructure), the bookkeeping is used to keep the information of the allocated memory.

Whenever we called the malloc function then it reserves some extra bytes (depend on implementation and system) for bookkeeping. This extra byte is reserved for each call of malloc and become a cause of the internal fragmentation.

Internal fragmentation

For example,
See the below code, the programmer may think that system will be allocated 8 *100 (800) bytes of memory but due to bookkeeping (if 8 bytes) system will be allocated 8*100 extra bytes. This is an internal fragmentation, where 50% of the heap waste.


How is the free work in C?

Answer:

When we call the memory management functions (malloc, calloc or realloc) then these functions keep extra bytes for bookkeeping.

Whenever we call the free function and pass the pointer that is pointing to allocated memory, the free function gets the bookkeeping information and release the allocated memory. Anyhow if you or your program change the value of the pointer that is pointing to the allocated address, the calling of free function give the undefined result.

For example,


How can you determine the size of an allocated portion of memory?

Answer:

In C language, we can calculate the size of the static array using the sizeof operator but there is no operator to calculate the size of the dynamically allocated memory.

Mainly there are two ways to get the size of allocated memory in every section of the code.

  • Create a global variable to store the size of the allocated memory.
  • Carry the length of allocated memory.

For example,

Suppose you need to create an integer array whose size is n. So to carry the array length of the array, you need to allocate the memory for n+1.

int *piArray = malloc ( sizeof(int) * (n+1) );

If memory is allocated successfully, assign n (size of the array) its 0 places.

piArray[0] = n;
or
* piArray = n;

Now it’s time to create a copy of original pointer but to left one location from the beginning.

int * pTmpArray = piArray +1;

Note: if you are new, see this article arithmetic operation on the pointer.

Now, whenever in a program you ever required the size of the array then you can get from copy pointer.

ArraySize = pTmpArray[-1];

After using the allocated memory don’t forget to deallocate the allocated memory.

free (piArray);


What is the difference between memcpy and memmove?

Answer:

Both copies function are used to copy n characters from the source object to destination object but they have some difference that is mentioned below.

  • The memcpy copy function shows undefined behavior if the memory regions pointed to by the source and destination pointers overlap. The memmove function has the defined behavior in case of overlapping. So whenever in doubt, it is safer to use memmove in place of memcpy.

OutPut:
Function: memmove with overlap
Orignal : I am going from Delhi to Gorakhpur
Source: going from Delhi to Gorakhpur
Destination: from Delhi to Gorakhpur
Result: I am going going from Delhi to Gorakhpur
Length: 40 characters

Function: memcpy with overlap
Orignal : I am going from Gorakhpur to Delhi
Source: going from Gorakhpur to Delhi
Destination: from Gorakhpur to Delhi
Result: I am going going fring frakg frako frako
Length: 40 characters

  • The memmove function is slower in comparison to memcpy because in memmove extra temporary array is used to copy n characters from the source and after that, it uses to copy the stored characters to the destination memory.
  • The memcpy is useful in forwarding copy but memmove is useful in case of overlapping scenario.

Reverse a string in c without using library function

Answer:

A string is a collection of characters and it always terminates with a null character that means every string contains a null character at the end of the string.

Example:
char *pszData = “aticle”;
In above example, pszData is the pointer to the string. All characters of the string are stored in a contiguous memory and consist a null character in the last of the string.

See the below table:

character ‘a’‘t’‘i’‘c’‘l’‘e’‘\0’
Address 0x000x010x020x030x040x050x06

Here we will reverse a string using two methods, iterative and recursive.

Reversing a string using the Iterative method

Method 1:

Algorithm:

  • Calculate the length (Len) of string.
  • Initialize the indexes of the array.
    Start = 0, End = Len-1
  • In a loop, swap the value of pszData[Start] with pszData[End].
  • Change the indexes’ of the array as follows.
    Start = start +1; End = end – 1

Method 2:

Recursive way to reverse a string

Algorithm:

  • Calculate the length (Len) of string.
  • Initialize the indexes of the array.
    Start = 0, End = Len-1
  • swap the value of pszData[Start] with pszData[End].
  • Change the indexes’ of an array as below and Recursively call reverse function for the rest array.
    Start = start +1; End = end – 1


What is the endianness?

Answer:

The endianness is the order of bytes to store data in memory and it also describes the order of byte transmission over a digital link. In memory data store in which order it depends on the endianness of the system, if the system is big-endian then the MSB byte store first (means at lower address) and if the system is little-endian then LSB byte store first (means at lower address).

Some examples of the little-endian and big-endian system.


What is big-endian and little-endian?

Answer:

Suppose, 32 bits Data is 0x11223344.

little-endian

Big-endian

The most significant byte of data stored at the lowest memory address.

Little endian to Big endian

Little-endian

The least significant byte of data stored at the lowest memory address.

little-endian

Note: Some processor has the ability to switch one endianness to other endianness using the software means it can perform like both big endian or little endian at a time. This processor is known as the Bi-endian, here are some architecture (ARM version 3 and above, Alpha, SPARC) who provide the switchable endianness feature.


Write a c program to check the endianness of the system.

Answer:

Method 1:

Method 2:


How to convert little endian to big endian vice versa in C?

Answer:

Method 1:

Endianness Conversion

Method 2:

We can also make the macro to swap the data from one endianness to another.


Write a c Program to Check Whether a Number is Prime or Not?

Answer:

A prime number is a positive natural number, whose value greater than 1 and has only two factors 1 and the number itself.

For more details on a prime number, check out:
How to find all prime numbers up to n.

Algorithm to check prime number using division method

START

Step 1 → Take the number n

Step 2 → Divide the number n with (2, n-1) or (2, n/2) or (2, sqrt(n)).

Step 3 → if the number n is divisible by any number between (2, n-1) or (2, n/2) or (2, sqrt(n)) then it is not prime

Step 4 → If it is not divisible by any number between (2, n-1) or (2, n/2) or (2, sqrt(n)) then it is a prime number

STOP


How to find the size of an array in C without using the sizeof operator?

Answer:

Method 1:

Method 2:


How to find the size of the structure in c without using sizeof operator?

Answer:

Method 1:

When incrementing the pointer then pointer increase a block of memory (block of memory depends on pointer data type). So here we will use this technique to calculate the sizeof structure.

  • First, create the structure.
  • Create a pointer to structure and assign the NULL pointer.
  • Increment the pointer to 1.

Method 2:

We can also calculate the size of the structure using the pointer subtraction. In the previous article “all about the pointer“, we have read that using the pointer subtraction we can calculate the number of bytes between the two pointers.

  • First, create the structure.
  • create an array of structure, Here aiData[2].
  • Create pointers to the structure and assign the address of the first and second element of the array.
  • Subtract the pointers to get the size of the structure.

structure in c


What is meant by structure padding?

Answer:

In the case of structure or union, the compiler inserts some extra bytes between the members of structure or union for the alignment, these extra unused bytes are called padding bytes and this technique is called padding.

Padding has increased the performance of the processor at the penalty of memory.In structure or union data members aligned as per the size of the highest bytes member to prevent from the penalty of performance.

Note: Alignment of data types mandated by the processor architecture, not by language.


How to pass a 2d array as a parameter in C?

Answer:

In C language, there are a lot of ways to pass the 2d array as a parameter. In below section, I am describing few ways to pass the 2d array as a parameter to the function.

Passing 2d array to function in c using pointers

 

The first element of the multi-dimensional array is another array, so here, when we will pass a 2D array then it would be split into a pointer to the array.

For example,

If int aiData[3][3], is a 2D array of integers, it would be split into a pointer to the array of 3 integers (int (*)[3]).

Passing 2d array to function with row and column

In which prototype of the function should be same as the passing array. In another word, we can say that if int aiData[3][3] is a 2D array, the function prototype should be similar to the 2D array.

Passing 2d array to function, using the pointer to 2D array

If int aiData[3][3] is a 2D array of integers, then &aiData would be pointer the 2d array that has 3 row and 3 column.

 

Get your complete list of C interview questions in eBook format with live instructor support and more. 

             Download Now | $9




11 comments

  1. ultimate questions….thank Q soo much .

    but a small question>>> |||| find below

    write a program to ciunt set bits..??

    plsz explain this logic…. 🙂 🙂

    unsigned int NumberSetBits(unsigned int n)
    {
    unsigned int CountSetBits= 0;
    while (n)
    {
    CountSetBits += n & 1; // im not understan how this logic works to catuch the set bits.
    n >>= 1;
    }
    return CountSetBits;
    }

    1. In the below code,

      while (n)
      {
      CountSetBits += n & 1;
      n >>= 1;
      }

      Suppose n =2, that means in binary (0000000000000010) if the size of n is 2 byte.

      initialy CountSetBits = 0;

      Now,

      In first iteration:

      while (0000000000000010)
      {
      CountSetBits += 0000000000000010 & 1;

      0000000000000010 >>= 1; //shift 1 position right
      }

      After the first iteration the value of CountSetBits will be 0 because CountSetBits += 0000000000000010 & 1;

      become CountSetBits += 0;

      In second iteration:

      while (0000000000000001)
      {
      CountSetBits += 0000000000000001 & 1;

      0000000000000001 >>= 1; //shift 1 position right
      }

      After the second iteration the value of CountSetBits will be 1 because CountSetBits += 0000000000000001 & 1;

      become CountSetBits += 1;

      After the second iteration,

      while (0000000000000000) //false never executed
      {

      }

      So finally the value of CountSetBits is 1.

      I hope now you have understood.

Leave a Reply