All C Interview Questions

What are storage classes in C?

ClassMeaning
autoDefault for local variables
staticKeeps its value between function calls
externUses a variable defined in another file or place
registerHint to keep the variable in a CPU register

See the full explanation in Scope and Storage Classes.

What is the use of the static keyword in C?

A static local variable is created once and keeps its value between function calls. A static global variable or function is visible only in its own file.

#include <stdio.h>

void count(void) {
    static int n = 0;
    n++;
    printf("%d ", n);
}

int main(void) {
    count(); count(); count();
    printf("\n");
    return 0;
}

Output:

Output of the above program is

1 2 3

A normal local variable would print 1 every time.

What is an enum in C?

#include <stdio.h>

enum Day { MON, TUE, WED };

int main(void) {
    enum Day d = TUE;
    printf("%d\n", d);
    return 0;
}

Output:

Output of the above program is

1

Names make the code easy to read. You can also set values, like enum Level { LOW = 1, HIGH = 10 };. See C enum.

How to reverse a string in C?

#include <stdio.h>
#include <string.h>

int main(void) {
    char s[] = "Hello";
    int i = 0, j = strlen(s) - 1;

    while (i < j) {
        char t = s[i];
        s[i] = s[j];
        s[j] = t;
        i++;
        j--;
    }
    printf("%s\n", s);
    return 0;
}

Output:

Output of the above program is

olleH

More ways are in Reverse a String in C.

How to swap two numbers in C?

#include <stdio.h>

int main(void) {
    int a = 10, b = 20, t;

    t = a;  a = b;  b = t;           // with a third variable
    printf("%d %d\n", a, b);

    a = a + b;  b = a - b;  a = a - b;   // without a third variable
    printf("%d %d\n", a, b);
    return 0;
}

Output:

Output of the above program is

20 10
10 20

In a function, send the addresses (swap(&a, &b)) and use pointers. See Call by Value and Reference.

How to check if a number is prime in C?

#include <stdio.h>

int isPrime(int n) {
    if (n < 2) return 0;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return 0;
    }
    return 1;
}

int main(void) {
    printf("%d\n", isPrime(29));
    printf("%d\n", isPrime(30));
    return 0;
}

Output:

Output of the above program is

1
0

It is enough to check divisors up to the square root of the number, so the loop is fast.

How to find the factorial of a number in C?

#include <stdio.h>

int main(void) {
    int n = 5;
    unsigned long long fact = 1;

    for (int i = 2; i <= n; i++) {
        fact *= i;
    }
    printf("%d! = %llu\n", n, fact);
    return 0;
}

Output:

Output of the above program is

5! = 120

Factorial grows very fast. Even unsigned long long overflows after 20!. The recursive way is in C Recursion.

What is the difference between malloc() and calloc() in C?

malloc()calloc()
malloc(size) takes one argument (total bytes)calloc(n, size) takes two arguments
Memory has garbage valuesMemory is set to zero
Slightly fasterSlightly slower because of the zeroing
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *a = calloc(3, sizeof(int));

    printf("%d %d %d\n", a[0], a[1], a[2]);
    free(a);
    return 0;
}

Output:

Output of the above program is

0 0 0

Both return NULL if the memory is not available, and both must be released with free(). See Dynamic Memory Allocation.

What is a memory leak in C and how to avoid it?

A memory leak happens when the program allocates memory with malloc(), calloc() or realloc() but never frees it. The program keeps using more and more memory, and a long running program can finally crash.

void leak(void) {
    int *p = malloc(100 * sizeof(int));
    // no free(p) here, and the pointer p is lost when the function ends
}

How to avoid it:

  • Call free() for every malloc().
  • Free the memory on all paths, also on the error paths.
  • Set the pointer to NULL after freeing.
  • Use tools like Valgrind or the AddressSanitizer (-fsanitize=address) to find leaks.

What is a dangling pointer in C?

A dangling pointer is a pointer which still holds an address, but the memory at that address is no longer valid. Using it is undefined behavior.

Common causes:

  • The memory was released with free(), but the pointer was still used.
  • A function returns the address of its local variable.
  • The pointer points to a block which has ended.
int *bad(void) {
    int x = 10;
    return &x;        // x is destroyed when the function ends
}

int *p = malloc(sizeof(int));
free(p);
p = NULL;             // good habit: no dangling pointer now

The fix is to set the pointer to NULL after free(), and never return the address of a local variable. See Pointers and Functions.

What is the difference between an array and a pointer in C?

ArrayPointer
Fixed block of memory with its own sizeA variable which stores an address
sizeof(arr) gives the total bytessizeof(p) gives the pointer size
Name cannot be changed to point elsewhereCan point to any place
Memory is allocated automaticallyMemory is given by the programmer, or it points to an existing one
#include <stdio.h>

int main(void) {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;

    printf("%zu %zu\n", sizeof(arr), sizeof(p));
    printf("%d %d\n", arr[2], p[2]);
    return 0;
}

Output:

Output of the above program is

20 8
3 3

The array name acts like a pointer in most expressions (it “decays”), and that is why they look alike. See Pointers and Arrays.

What is a void pointer in C?

A void * is a generic pointer. It can store the address of any type, but you cannot dereference it directly. You must cast it to the right type first.

#include <stdio.h>

int main(void) {
    int n = 42;
    float f = 3.5f;
    void *p;

    p = &n;
    printf("%d\n", *(int *)p);
    p = &f;
    printf("%.1f\n", *(float *)p);
    return 0;
}

Output:

Output of the above program is

42
3.5

malloc() returns a void *, and functions like qsort() and memcpy() use it to work with any type.

What is a function pointer in C?

#include <stdio.h>

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int calc(int (*op)(int, int), int x, int y) {
    return op(x, y);
}

int main(void) {
    printf("%d\n", calc(add, 10, 4));
    printf("%d\n", calc(sub, 10, 4));
    return 0;
}

Output:

Output of the above program is

14
6

The function calc() does not know which operation it will run. This idea is used for callbacks, menus and the compare function of qsort(). See Pointers and Functions.

What is the difference between const and #define in C?

const#define
Has a data typeNo data type, only text
Handled by the compilerHandled by the preprocessor
Follows scope rulesValid from the line it is written
Has a memory addressNo address

Example: const int MAX = 10; and #define MAX 10. Prefer const (or enum) for plain values, because it is safer. See C Constants.

What is the difference between #include with angle brackets and with double quotes in C?

  • #include <stdio.h> searches the standard system include folders. Use it for standard and library headers.
  • #include "myheader.h" searches the folder of the current file first, and then the system folders. Use it for your own headers.

The exact search order depends on the compiler. See Preprocessor and Macros.

What is a segmentation fault in C?

A segmentation fault (segfault) happens when a program reads or writes memory that it should not touch. The operating system stops the program.

Common causes:

  • Dereferencing a NULL or uninitialized pointer.
  • Accessing an array outside its limits.
  • Using memory after free().
  • Very deep recursion (stack overflow).
  • Writing to a string literal, like char *s = "abc"; s[0] = 'x';.

To find it, compile with -g and run with a debugger like GDB, or use -fsanitize=address to see the exact line.

What is the volatile keyword in C?

volatile tells the compiler that the value of a variable can change at any time, from outside the normal program flow. So the compiler must read it from memory each time, and cannot keep it in a register.

volatile int flag = 0;      // may be changed by an interrupt or another thread

while (flag == 0) {
    // wait
}

Without volatile the compiler may see that the loop never changes flag and turn it into an infinite loop. It is used for hardware registers, interrupt handlers and signal flags. It does not make the code thread safe.

What is structure padding in C?

The compiler adds empty bytes (padding) between structure members so that each member starts at an address that suits its type. So the size of a structure can be more than the sum of its members.

#include <stdio.h>

struct A { char a; int b; char c; };
struct B { int b; char a; char c; };

int main(void) {
    printf("%zu\n", sizeof(struct A));
    printf("%zu\n", sizeof(struct B));
    return 0;
}

Output:

Output of the above program is

12
8

Both have the same members, but the order in struct B wastes less space. A good habit is to put the bigger members first.

What is the difference between memcpy() and strcpy() in C?

strcpy()memcpy()
Only for stringsFor any data (int arrays, structures)
Stops at the null characterCopies exactly n bytes
Does not need a sizeNeeds the number of bytes
#include <stdio.h>
#include <string.h>

int main(void) {
    int a[3] = {1, 2, 3};
    int b[3];

    memcpy(b, a, sizeof(a));
    printf("%d %d %d\n", b[0], b[1], b[2]);
    return 0;
}

Output:

Output of the above program is

1 2 3

For overlapping memory use memmove(), because memcpy() does not handle it.

What is the difference between stack and heap memory in C?

StackHeap
Local variables and function callsMemory from malloc(), calloc(), realloc()
Managed automaticallyManaged by the programmer with free()
Very fastSlower
Limited size (stack overflow)Much bigger
Memory ends when the function endsLives until freed

See Dynamic Memory Allocation and Recursion.