C Interview Questions

These interview questions specifically focus on understanding how C is applied in various domains and industries, highlighting its versatility and relevance in software development. These interview questions explore C’s diverse applications in various industries, showcasing its versatility and relevance in software development. They cover a range of topics to assess candidates’ understanding of fundamental C programming concepts.

C-Quiz

C Quiz-1
C Quiz-2
C Quiz-3
C Quiz-4
C Quiz-5
C Quiz-6

Basic

What is size of character, integer, integer pointer, character pointer?

  • Character – 1 Byte
  • Integer – 2 byte or 4 byte
  • Integer Pointer (The size of a pointer is platform-dependent)
    • 64 bit computer 8 byte
    • 32 bit computer 4 byte
  • Character Pointer
    • Character pointer is platform dependent, in a 32 bits system it’s 4 bytes.



#define cat(x,y) x##y concatenates x to y. But cat(cat(1,2),3) does not expand but gives preprocessor warning. Why?

cat(cat(1,2),3) will be replaced to 1##2##3, ## could only concatenate two arguments. The problem is that cat(cat(1,2),3) isn’t expanded in a normal way which you expect that cat(1,2) would give 12 and cat(12, 3) would give 123.



What is the output of printf(“\nab\bcd\ref”); ?

  • Output is efd
  • \n  means new line
  • \b  means backspace
  • \r means delete to the beginning of the line, so it will delete ‘acd’



is the output correct?? a+++b  -> (a++)+b



++ip increments what?

it pre increments the ip variable.



Operations involving unsigned and signed

Unsigned will be converted to signed



What is the result of below Program?

#include<stdio.h>
int main()
{
    int k=0;
    k=1,2;
    printf("%d\n",k);
    return 0;
}

Answere: 1

Explanation: Assigment will be always Right to Left, So first k=2 will be assign and next k=1 will be assign



What do you mean by const keyword ?



Which way of writing infinite loops is more efficient than others?

  • there are 3ways.
    • while(1) ;
    • for(;;);
    • goto
  • I think goto  is the most efficient



How do you write a function which takes 2 arguments โ€“ a byte and a field in the byte and returns the value of the field in that byte?

We can move the number using shift operator (>>)



Which parameters decide the size of data type for a processor ?

  • Answers will add Soon

Multiply by 15 using bitwise operator (without addition and multiplication)?

#include <stdio.h>

int main()
{
    int a;
    printf("Enter the number : ");
    scanf("%d",&a);
    char b = 15;
    int c = 0;
    while(b--)
    {
        c = c + a ;
    }
    printf("AEW: Multiplication of 15 * %d = %d", a,c);

    return 0;
}


Storage Class

What are static variables?



How to use a variable in a source file that is defined in another source file?

Using extern keyword



Array

Why cannot arrays be passed by values to functions?

The array name represents the first element in the array.



Pointer

What is NULL pointer and what is its use?

NULL pointer assignment : char q=0;  (or) char *q=(char)0;  (or) char *p=NULL;

  • Example
    • What is (void*)0 ? //Representation of NULL pointer
  • NULL Macro is defined in locale.h , stddef.h , stdio.h , stdlib.h , string.h , time.h , and wchar.h

What is void pointer and what is its use?

  • When we do not know what type of the memory address the pointer variable is going to hold, then we declare a void pointer for such.
  • If a function is defined like: int func (void *a);
  • It can take any type of pointer

What is forward reference w.r.t. pointers in c?

  • Forward reference means a reference is used before its declaration.
    There are only two cases:
    • structure and
    • goto statement

Array of pointer to functions?

An array of pointers to functions is a construct in C that allows storing pointers to different functions within an array. Each element of the array is a pointer to a function, enabling flexibility in function invocation and organization.


Structure

How can you define a structure with bit field members?

  • Answere will add soon.

Can structures be passed to the functions by value?

  • Yes, structures can be passed by value.



Find the structure’s base address using one of the member’s addresses?

#include 

struct AEW
{ int Arun;
  int Eworld;
};


int main()
{

  struct AEW base;
  printf("%u\n",&base);
  printf("%u",&base+1);
  return 0;
}



Difference between Structure and Union?

This is very important question for all embedded engineers


Memory

malloc(sizeof(0)) will return

  • valid pointer

Others

Exchange or swap the all bits in the following manner without using 2nd variable?

  • Swap 15th to 0th location
  • Swap 14th to 1th Location
  • Swap 13th to 2nd Location
  • ……………………..
  • ……………………..
  • Swap 10th to 5th Location
  • ……………………….
  • ……………………….
  • Swap 8th to 7th Location
15th Bit0th bit
1010101010101010
  • Answers will add Soon

What is the use of #progma  keyword

  • This is a preprocessor directive that can be used to turn on or off certain features.
  • It is of two types #pragma startup  , #pragma exit  and #pragma warn  .
    • #pragma startup allows us to specify functions called upon program startup.
    • #pragma exit  allows us to specify functions called upon program exit.

How are macros different from inline functions?

Macros :

  • Its used for when the set of instruction/function/task repeatedly run again&  again. Macros is defined by #define macro_name
  • Example : Add the two numbers using macros #define add(a,b) (a+b) , Here the add is the macro name perform the two number addition functionality.
  • The major disadvantage of macros is that they are not really functions and the usual error checking and stepping through of the code does not occur.

Inline :

  • Whenever inline functions are invoked, they expand, avoiding the control going to the place where the function is defined. They also bypass all activities, such as saving the return address when a jump is performed. Saves time in case of short codes.
  • Example : inline float add(float a,float b) { return a+b; }
  • Inline is just a request to the compiler and it is upto to the compiler whether to substitute the code at the place of invocation or perform a jump based on its performance algorithms.

Advantages and disadvantages of using macro and inline functions?

  • Macro does not have type checking. The compiler replaces the entire function with an inline function.

What happens when recursion functions are declared inline?

  • It depends some compiler will expand it up to a limit, others will simply not expand it.

What is the work of compiler?

Compiler – Source code to Binary code

What is job of preprocessor, compiler, assembler and linker ?

  • Answers will add Soon

What is the difference between static linking and dynamic linking ?

  • Answers will add Soon

Memory

What is the segmentation fault error in C?

Segmentation fault is a runtime error. This will occur due to some causes when the program is running time.

  • Cause-1: Trying to access a memory area which is read-only.
  • Cause-2: Using the dereferenced pointer : A pointer may does not have a valid address/memory location to point. It may also happen when you try to free a memory (using a pointer), which is already freed.

What is โ€˜stack overflowโ€™ error in C?

In C, a “stack overflow” error occurs when the call stack, a region of memory used for function call and local variable storage, exceeds its predefined size. This typically happens due to excessive recursion or allocating too much memory for local variables within functions. When the stack size limit is reached, the program will terminate abnormally, usually resulting in a segmentation fault or a crash.

What is the output of the following code

#include <stdio.h>
#include <stdlib.h>

static int i = 20;

void sum(int j)
{
	printf("%d\n",j++);
}
void newsum(int k)
{
	printf("%d\n",++i);
}

void print()
{
	printf("%d\n", i++);
}

int main()
{
	int i = 10;
	printf("%d\n",i++);	
	sum(++i);				
	printf("%d\n",i--);	 
	newsum(i++);			
	printf("%d\n",--i);	
	print();		 
	return 0;
}

Output


Understanding the variables

  • Global static int i = 20; โ€” this i is different from the i inside main().
  • main() has a local int i = 10, which shadows the global i.
  • Functions sum() and newsum() use parameters j and k (copies of arguments).
  • newsum() modifies the global i.
  • print() uses the global i.

Step-by-step execution

1.

int i = 10;
printf("%d\n", i++);
  • Prints 10
  • Local i becomes 11.

2.

sum(++i);
  • ++i โ†’ local i goes from 11 โ†’ 12
  • Inside sum(int j):
    • j++ prints 12 (post-increment, but increment has no effect outside).
  • Local i in main remains 12 after the call.

3.

printf("%d\n", i--);
  • Prints 12
  • Local i becomes 11.

4.

newsum(i++);
  • i++ โ†’ passes 11 to newsum()
  • In newsum(int k):
    • Operates on global i (20 initially)
    • ++i โ†’ 20 โ†’ 21
    • Prints 21
  • Local i in main becomes 12 after the call.

5.

printf("%d\n", --i);
  • Local i = 12 โ†’ pre-decrement โ†’ 11
  • Prints 11

6.

print();
  • Uses global i (currently 21 from earlier step)
  • i++ โ†’ prints 21, then global i becomes 22.

Final Output

10
12
12
21
11
21

define MUL(x,y) ((x)*(y))

x=7+1
y=8+1

If you use your macro

#define MUL(x,y)  ((x)*(y))

with

x = 7+1
y = 8+1

and call

MUL(x, y)

If you do:

MUL(7+1, 8+1)

the compiler sees:

((7+1)*(8+1))

So it calculates:

(8 * 9) = 72

This is correct because of the extra parentheses in your macro definition.


If you had defined it without parentheses:

#define MUL(x,y)  x*y
MUL(7+1, 8+1)  // becomes 7+1*8+1

Operator precedence makes it:

7 + (1 * 8) + 1 = 16

Thatโ€™s why the parentheses in your definition ((x)*(y)) are important โ€” they preserve the intended math.


Set ->N is number, ith bit.

Set   : 	N |= (1<<i);
Clear : N &= (~(1<<i));
Toggle: N ^= (1<<i);

write the api for set, toggle, clear the particlar bit

Header file โ€“ bit_ops.h

#ifndef BIT_OPS_H
#define BIT_OPS_H

#include <stdint.h>

// Set the ith bit
static inline void set_bit(uint32_t *num, uint8_t i) {
    *num |= (1U << i);
}

// Clear the ith bit
static inline void clear_bit(uint32_t *num, uint8_t i) {
    *num &= ~(1U << i);
}

// Toggle the ith bit
static inline void toggle_bit(uint32_t *num, uint8_t i) {
    *num ^= (1U << i);
}

// Check if ith bit is set (returns 1 if set, 0 if clear)
static inline uint8_t is_bit_set(uint32_t num, uint8_t i) {
    return (num & (1U << i)) ? 1 : 0;
}

#endif // BIT_OPS_H

Example usage โ€“ main.c

#include <stdio.h>
#include "bit_ops.h"

int main() {
    uint32_t num = 0b00001000; // 8
    printf("Initial: %u (0x%X)\n", num, num);

    set_bit(&num, 1);
    printf("After set bit 1: %u (0x%X)\n", num, num);

    clear_bit(&num, 3);
    printf("After clear bit 3: %u (0x%X)\n", num, num);

    toggle_bit(&num, 2);
    printf("After toggle bit 2: %u (0x%X)\n", num, num);

    printf("Is bit 2 set? %s\n", is_bit_set(num, 2) ? "Yes" : "No");

    return 0;
}

Sample Output

Initial: 8 (0x8)
After set bit 1: 10 (0xA)
After clear bit 3: 2 (0x2)
After toggle bit 2: 6 (0x6)
Is bit 2 set? Yes

Toggle the all the bits in byte.

If you want to toggle (invert) all bits in a byte, you can use the bitwise NOT (~) operator.

Hereโ€™s a simple example:

#include <stdio.h>
#include <stdint.h>

uint8_t toggleAllBits(uint8_t byte)
{
    return ~byte;
}

int main()
{
    uint8_t data = 0b10101010; // Example: 0xAA
    uint8_t result = toggleAllBits(data);

    printf("Original: 0x%02X\n", data);
    printf("Toggled : 0x%02X\n", result);

    return 0;
}

Explanation:

  • ~byte flips every bit in the byte.
    • 0 becomes 1
    • 1 becomes 0
  • For an uint8_t, this inverts exactly 8 bits.

Example output:

Original: 0xAA
Toggled : 0x55

Toggle the only 3 Bits in the byte

If you only want to toggle specific 3 bits (for example, bits 0, 1, and 2) in a byte,
you can use XOR (^) with a bitmask that has those bits set to 1.


Example: Toggle bits 0, 1, and 2

#include <stdio.h>
#include <stdint.h>

uint8_t toggleThreeBits(uint8_t byte)
{
    uint8_t mask = (1 << 0) | (1 << 1) | (1 << 2); // Bits 0,1,2 -> mask = 0x07
    return byte ^ mask;
}

int main()
{
    uint8_t data = 0b10101010; // Example: 0xAA
    uint8_t result = toggleThreeBits(data);

    printf("Original: 0x%02X\n", data);
    printf("Toggled : 0x%02X\n", result);

    return 0;
}

How it works:

  • mask = (1 << 0) | (1 << 1) | (1 << 2)
    โ†’ binary 00000111 โ†’ hex 0x07
  • byte ^ mask
    โ†’ XOR flips only the bits that are 1 in the mask.

Example run:

Original: 0xAA   // 10101010
Toggled : 0xAD   // 10101101

Circular Shift API

#include <stdio.h>
#include <stdbool.h>

unsigned int shift(unsigned int a, bool dir, unsigned char bit)
{
    unsigned char total_bits = sizeof(a) * 8; // 32 for unsigned int on most systems
    bit %= total_bits; // avoid overflow shift

    if (bit == 0)
        return a;

    if (dir) // Right rotate
    {
        return (a >> bit) | (a << (total_bits - bit));
    }
    else // Left rotate
    {
        return (a << bit) | (a >> (total_bits - bit));
    }
}

int main()
{
    unsigned int b = 0x1234;

    printf("Original : 0x%08X\n", b);
    printf("Left 3   : 0x%08X\n", shift(b, 0, 3)); // Left rotate by 3 bits
    printf("Right 3  : 0x%08X\n", shift(b, 1, 3)); // Right rotate by 3 bits

    return 0;
}

Example output:

Original : 0x00001234
Left 3   : 0x000091A0
Right 3  : 0x80000246

Key improvements:

  • No pointer confusion โ€” passing a by value makes usage simple.
  • Uses correct total bit width (sizeof(a) * 8).
  • Bit mask protection (bit %= total_bits).
  • No undefined behavior โ€” avoids negative or excessive shifts.

Pointer Understanding

The code in below will crash (or cause undefined behavior) because trying to modify a string literal, which is stored in read-only memory in most modern C implementations.

Hereโ€™s whatโ€™s happening step-by-step:


Code Analysis

char *str = "Hello";   // "Hello" is stored in read-only memory (string literal)
str++;                 // Now str points to 'e' (second character)
*str = g;              // ❌ Modifying read-only memory โ†’ undefined behavior
printf("string is: %s\r\n", str);

Why It Fails

  • In C, char *str = "Hello"; stores "Hello" in a read-only section of memory.
  • Incrementing str makes it point to the 'e'.
  • Attempting *str = g; tries to overwrite 'e' with the value of variable g โ€” this causes segmentation fault or memory corruption.

Correct Way (Modifiable String)

If we want to change characters, must store the string in a char array:

#include <stdio.h>

int main() {
    char str[] = "Hello";  // Stored in modifiable array
    str++;                 // ❌ This won't compile (can't increment array name)
    // Instead use a pointer
    char *p = str;
    p++;                   // Now p points to 'e'
    *p = 'g';               // Modify 'e' โ†’ 'g'
    printf("string is: %s\r\n", p); // Prints "gllo"
    return 0;
}

Inc operator

int a = 20;
printf("%d,%d,%d", ++a, a++, ++a);

Answere: 23,21,21

Please turn AdBlock off, and continue learning

Notice for AdBlock users

Please turn AdBlock off

Table of Contents

Index