C Interview Questions for Experienced

C Interview Questions for Experienced with Answer

This article is mainly focused on the most repeatedly asked and the latest updated C interview questions that are appearing in most of the current C interviews.

If you are looking for C interview questions for an experienced developer or C interview questions for experienced with answer, then you are at the right place. Here I have tried to create a collection of good C Interview questions for experienced developers. I have spent many hours creating these C programming interview questions.

So let see the  C questions, I hope you will enjoy these tricky C interview questions. And finally, all the best for your C interview.

 

Q) What is the difference between global and static global variables?

Ans:

In C language, the external static variable has the internal linkage and the internal static variable has no linkage. It is the reason they have a different scope but both will alive throughout the program.

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

 

Q) 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.

Ans:

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

 

Q) What are the uses of the keyword static?

Ans:

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.

1.  A static variable only initializes once, so a variable declared static within the body of a function maintains its prior value between function invocations.

2.  A global variable with static keyword has 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.

3. By default in C language, the 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.

 

Q) Size of the integer depends on what?

Ans:

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 the size of integer depends on the type of the compiler which has written by the 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 to use the C99 integer data types ( uin8_t, uin16_t, uin32_t ..) in place of standard int.

 

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

Ans:

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 the 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 the 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 shows the undefined behavior but for the unsigned type, it would be Data x 2pos.

 

Q) What is the difference between a macro and a function?

Ans:

macro VS function

 

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

Ans:

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

#include <stdio.h>

int main(void)
{
    int aiData[5] = {100,200,300,400,500};
    
    int *piData = aiData;
    
    ++*piData;
    
    printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData);
    
    return 0;
}

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.

#include <stdio.h>

int main(void)
{
    int aiData[5] = {100,200,30,40,50};

    int *piData = aiData;

    *++piData;

    printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData);

    return 0;
}

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.

 

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

Ans:

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

#include <stdio.h>

int main(void)
{
    int aiData[5] = {100,200,30,40,50};
    
    int *ptr = aiData;
    
    *ptr++;
    
    printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *ptr);
    
    return 0;
}

Output: 100, 200, 200

Explanation:

In the above example, two operators are involved and both have different precedence. The precedence of post ++ is higher than the *, so first post ++ will be executed and above expression, *p++ will be equivalent to *(p++). In another word you can say that it is post-increment of address and output is 100, 200, 200.

#include <stdio.h>

int main(void)
{
    int aiData[5] = {100,200,300,400,500};

    int *ptr = aiData;

    ++*ptr;

    printf("aiData[0] = %d, aiData[1] = %d, *ptr = %d", aiData[0], aiData[1], *ptr);

    return 0;
}

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.

 

Q) What is the difference between const and macro?

Ans:

  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 a 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 the case of call by reference, it prevents modifying the passed object value.

Q) What is a volatile variable in C?

Ans:

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 cache a variable into a register. Reading the value from memory is the only way to check the unpredictable change of the value.

 

Q) Can we have a volatile pointer?

Ans:

Yes, we can create a volatile pointer in C language.

int * volatile piData; // piData is a volatile pointer to an integer.

 

Q) Can a variable be both constant and volatile in C?

Ans:

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 the case of GPIO, its value will 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 a volatile keyword.

Syntax of declaration,
int volatile * const PortRegister;
How to read the above declaration,
int volatile * const PortRegister;
 |     |     |   |    |
 |     |     |   |    +------> PortRegister is a
 |     |     |   +-----------> constant
 |     |     +---------------> pointer to a
 |     +---------------------> volatile
 +---------------------------> integer

 

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

Ans:

Setting N-th Bit

Setting an N-th bit means that if the N-th bit is 0, then set it to 1 and if it is 1 then leave it unchanged. In C, bitwise OR operator (|) use to set a bit of integral data type. As we know that | (Bitwise OR operator) evaluates a new integral value in which each bit position is 1 only when operand’s (integer type) has a 1 in that position.

In simple words, you can say that “Bitwise OR ” of two bits is always one if any one of them is one.

That means,

0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1

 

Algorithm to set the bits:
Number | = (1UL << nth Position);

Clearing a Bit

Clearing a bit means that if N-th bit is 1, then clear it to 0 and if it is 0 then leave it unchanged. 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.

That means,
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1

 

Algorithm to clear the bit:

To clear the nth bit, first, you need to invert the string of bits then AND it with the number.

Number  &=  ~(1UL << nth Position);

 

Checking a Bit

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

An algorithm to check the bit
Bit = Number & (1UL << nth)

 

If you want to learn more about the c language, here 10 Free days  C video course for you.

 

Toggling a Bit

Toggling a bit means that if the N-th bit is 1, then change it to 0 and if it is 0 then change it to 1. 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.

That means,
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
An algorithm to toggle the bits
Number  ^=  (1UL << nth Position);

Recommended Post