Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools
C Language

Top 50 C Language Interview Questions

Curated questions covering pointers, memory management, arrays, strings, structures, file handling, and data structures in C.

01

What is C and what are its key features?

C is a general-purpose procedural language developed by Dennis Ritchie in 1972. Key features: low-level memory access via pointers, efficient execution, portable across platforms, structured programming, rich operators, and it is the foundation for C++, Java, and many other languages.

02

What is the difference between compiled and interpreted languages?

Compiled languages (C, C++) translate source code to machine code before execution - faster runtime. Interpreted languages (Python, JavaScript) translate at runtime - slower but more flexible. C is compiled: gcc/clang converts .c files to optimized machine code.

03

What is the difference between int, long, short, and char?

  • char - 1 byte. Stores characters or small integers (-128 to 127 signed).
  • short - 2 bytes. Range: -32,768 to 32,767.
  • int - typically 4 bytes. Range: -2,147,483,648 to 2,147,483,647.
  • long - 4 or 8 bytes depending on platform. Use long long for guaranteed 8 bytes.
Example
printf("%zu\n", sizeof(int));   // 4\nprintf("%zu\n", sizeof(long));  // 4 or 8\nprintf("%zu\n", sizeof(char));  // 1
04

What is a pointer in C?

A pointer is a variable that stores the memory address of another variable. Pointers enable dynamic memory allocation, efficient array handling, and passing variables by reference.

Example
int x = 10;\nint *ptr = &x;  // ptr holds address of x\nprintf("%d\n", *ptr);  // 10 (dereference)\n*ptr = 20;  // modifies x through pointer\nprintf("%d\n", x);  // 20
05

What is the difference between * and & operators?

  • & (address-of) - returns the memory address of a variable.
  • * (dereference) - accesses the value at the memory address stored in a pointer.
  • * in declaration - declares a pointer variable.
Example
int x = 5;\nint *p = &x;      // & gets address, * declares pointer\nprintf("%d", *p); // * dereferences to get value 5
06

What is the difference between pass by value and pass by reference?

  • Pass by value - a copy is passed. Changes inside the function do not affect the original.
  • Pass by reference - the address is passed via pointer. Changes inside the function affect the original.
Example
void byValue(int x) { x = 100; }  // original unchanged\nvoid byRef(int *x) { *x = 100; }  // original changed\nint n = 5;\nbyValue(n);  // n still 5\nbyRef(&n);   // n is now 100
07

What is the difference between arrays and pointers?

  • Array name is a constant pointer to the first element. Cannot be reassigned.
  • Pointer is a variable that can point to any memory location and can be reassigned.
  • sizeof(array) returns total array size; sizeof(pointer) returns pointer size (4 or 8 bytes).
Example
int arr[5] = {1,2,3,4,5};\nint *ptr = arr;  // ptr points to arr[0]\nprintf("%d", *(ptr + 2));  // 3 (pointer arithmetic)\nprintf("%d", arr[2]);      // 3 (same result)
08

What is pointer arithmetic?

When you add 1 to a pointer, it advances by sizeof(type) bytes, not 1 byte. This allows traversing arrays efficiently.

Example
int arr[] = {10, 20, 30, 40};\nint *p = arr;\np++;  // advances by sizeof(int) = 4 bytes\nprintf("%d\n", *p);  // 20\nprintf("%d\n", *(arr + 3));  // 40
09

What is a null pointer?

A null pointer does not point to any valid memory location. Represented by NULL (0 or (void*)0). Always initialize pointers to NULL and check before dereferencing to avoid undefined behavior.

Example
int *ptr = NULL;\nif (ptr != NULL) {\n  printf("%d", *ptr);\n} else {\n  printf("Null pointer");\n}
10

What is a dangling pointer?

A dangling pointer points to memory that has been freed or gone out of scope. Dereferencing it causes undefined behavior. Always set pointers to NULL after freeing.

Example
int *ptr = (int*)malloc(sizeof(int));\n*ptr = 10;\nfree(ptr);\nptr = NULL;  // prevent dangling pointer\n\n// Also: returning address of local variable\nint* bad() { int x = 5; return &x; } // WRONG
11

What is the difference between malloc, calloc, realloc, and free?

  • malloc(size) - allocates size bytes. Memory is uninitialized (contains garbage).
  • calloc(n, size) - allocates n*size bytes. Memory is zero-initialized.
  • realloc(ptr, newSize) - resizes previously allocated memory.
  • free(ptr) - releases allocated memory. Always free to prevent memory leaks.
Example
int *a = (int*)malloc(5 * sizeof(int));   // uninitialized\nint *b = (int*)calloc(5, sizeof(int));    // zero-initialized\na = (int*)realloc(a, 10 * sizeof(int));   // resize\nfree(a); a = NULL;
12

What is a memory leak?

A memory leak occurs when dynamically allocated memory is not freed after use. The memory remains allocated but inaccessible, gradually consuming available memory. Use Valgrind to detect leaks.

Example
void leak() {\n  int *p = (int*)malloc(100 * sizeof(int));\n  // forgot free(p) - memory leak!\n}\nvoid noLeak() {\n  int *p = (int*)malloc(100 * sizeof(int));\n  free(p); p = NULL;\n}
13

What is the difference between stack and heap memory?

  • Stack - automatic memory for local variables and function calls. Fast. Limited size. Managed automatically.
  • Heap - dynamic memory allocated with malloc/calloc. Larger. Must be manually freed. Slower allocation.
14

What is a structure in C?

A structure (struct) groups variables of different types under a single name.

Example
struct Student {\n  char name[50];\n  int age;\n  float gpa;\n};\nstruct Student s1;\nstrcpy(s1.name, "Alice");\ns1.age = 20;\ns1.gpa = 3.8;\n\ntypedef struct { char name[50]; int age; } Student;
15

What is the difference between struct and union?

  • struct - each member has its own memory. Total size = sum of all member sizes (plus padding).
  • union - all members share the same memory. Total size = size of the largest member. Only one member holds a value at a time.
Example
union Data {\n  int i;    // 4 bytes\n  float f;  // 4 bytes\n  char c;   // 1 byte\n}; // sizeof = 4 (largest member)\nunion Data d;\nd.i = 10;  // only d.i is valid now
16

What is the difference between #define and const?

  • #define - preprocessor macro. No type checking. Replaced textually before compilation. No memory allocated.
  • const - typed constant. Type-checked by compiler. Has memory address. Preferred in C99+.
Example
#define MAX 100        // no type, no memory\nconst int MAX = 100;  // typed, has address\n\n// #define can cause bugs:\n#define SQUARE(x) x*x\nSQUARE(2+3)  // expands to 2+3*2+3 = 11, not 25!
17

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

  • #include - searches in system/compiler include directories. Used for standard library headers.
  • #include "file.h" - searches in the current directory first, then system directories. Used for user-defined headers.
18

What is the difference between local and global variables?

  • Local variables - declared inside a function. Stored on stack. Accessible only within that function. Destroyed when function returns.
  • Global variables - declared outside all functions. Stored in data segment. Accessible throughout the program. Persist for program lifetime.
Example
int globalVar = 10;  // global\nvoid func() {\n  int localVar = 5;  // local\n  printf("%d %d", globalVar, localVar);\n}
19

What is the static keyword in C?

  • Static local variable - retains its value between function calls. Initialized only once.
  • Static global variable/function - limits scope to the current file (internal linkage).
Example
void counter() {\n  static int count = 0;  // persists between calls\n  count++;\n  printf("%d\n", count);\n}\ncounter(); // 1\ncounter(); // 2
20

What is the extern keyword?

extern declares a variable or function defined in another file. It tells the compiler the definition exists elsewhere, allowing multi-file programs to share variables.

Example
// file1.c\nint globalVar = 10;\n\n// file2.c\nextern int globalVar;  // declaration only\nvoid func() { printf("%d", globalVar); }
21

What is a function pointer?

A function pointer stores the address of a function and can be used to call it indirectly. Used for callbacks, dispatch tables, and implementing polymorphism in C.

Example
int add(int a, int b) { return a + b; }\nint sub(int a, int b) { return a - b; }\n\nint (*op)(int, int);  // function pointer\nop = add;\nprintf("%d\n", op(3, 2));  // 5\nop = sub;\nprintf("%d\n", op(3, 2));  // 1
22

What is string handling in C?

Strings in C are null-terminated character arrays. The standard library (string.h) provides functions for string manipulation.

Example
char str[50] = "Hello";\nstrlen(str);           // 5\nstrcpy(dest, str);     // copy\nstrcat(str, " World"); // concatenate\nstrcmp(s1, s2);        // compare (0 if equal)\nstrncpy(dest, src, n); // safe copy with limit
23

What is the difference between gets() and fgets()?

  • gets() - reads a line from stdin. Does NOT check buffer size - vulnerable to buffer overflow. Removed in C11.
  • fgets(str, size, stream) - reads at most size-1 characters. Safe. Always use fgets().
Example
char buf[100];\nfgets(buf, sizeof(buf), stdin);  // safe\nbuf[strcspn(buf, "\n")] = 0;     // remove trailing newline
24

What is file handling in C?

C provides FILE* type and functions from stdio.h for file operations.

Example
FILE *fp = fopen("data.txt", "r");\nif (fp == NULL) { perror("Error"); exit(1); }\nchar line[256];\nwhile (fgets(line, sizeof(line), fp)) {\n  printf("%s", line);\n}\nfclose(fp);
25

What is the difference between fread/fwrite and fprintf/fscanf?

  • fprintf/fscanf - text mode I/O. Data stored as human-readable text.
  • fread/fwrite - binary mode I/O. Data stored as raw bytes. Faster for structured data.
Example
FILE *fp = fopen("data.bin", "wb");\nfwrite(&student, sizeof(Student), 1, fp);\nfclose(fp);\nfp = fopen("data.bin", "rb");\nfread(&student, sizeof(Student), 1, fp);
26

What is the difference between typedef and #define for type aliases?

  • typedef - creates a true type alias. Type-checked by compiler. Works correctly with pointers.
  • #define - textual substitution. No type checking. Can cause subtle bugs with pointer types.
Example
typedef unsigned int uint;  // proper type alias\ntypedef struct Node* NodePtr;\n\n#define UINT unsigned int\n// UINT *p1, p2; -> p2 is NOT a pointer!
27

What is a linked list in C?

A linked list is a dynamic data structure where each node contains data and a pointer to the next node.

Example
struct Node {\n  int data;\n  struct Node *next;\n};\nstruct Node* createNode(int data) {\n  struct Node *n = (struct Node*)malloc(sizeof(struct Node));\n  n->data = data;\n  n->next = NULL;\n  return n;\n}
28

What is the difference between -> and . operators?

  • . (dot) - accesses members of a structure variable directly.
  • -> (arrow) - accesses members of a structure through a pointer. Equivalent to (*ptr).member.
Example
struct Point p = {3, 4};\nprintf("%d", p.x);    // dot: direct access\nstruct Point *ptr = &p;\nprintf("%d", ptr->x); // arrow: pointer access
29

What is the difference between pre-increment and post-increment?

  • ++i (pre-increment) - increments i first, then returns the new value.
  • i++ (post-increment) - returns the current value first, then increments i.
Example
int i = 5;\nprintf("%d", ++i);  // prints 6, i is 6\nprintf("%d", i++);  // prints 6, i becomes 7\nprintf("%d", i);    // prints 7
30

What is the difference between signed and unsigned integers?

  • signed int - can represent negative and positive values. Range: -2^31 to 2^31-1 for 32-bit.
  • unsigned int - only non-negative values. Range: 0 to 2^32-1 for 32-bit.
Example
unsigned int u = 4294967295; // max uint32\nint s = -1;\nprintf("%u", (unsigned int)s); // 4294967295 (same bits)
31

What is the difference between logical and bitwise operators?

  • Logical (&&, ||, !) - work on boolean values. Short-circuit evaluation.
  • Bitwise (&, |, ^, ~, <<, >>) - work on individual bits of integers.
Example
int a = 5;  // 0101\nint b = 3;  // 0011\nprintf("%d", a & b);  // 1  (0001)\nprintf("%d", a | b);  // 7  (0111)\nprintf("%d", a ^ b);  // 6  (0110)\nprintf("%d", a << 1); // 10 (1010)
32

What is the difference between void pointer and NULL pointer?

  • void* (generic pointer) - can point to any data type. Must be cast before dereferencing.
  • NULL pointer - a pointer with value 0. Points to nothing. Dereferencing causes undefined behavior.
Example
void *vp;\nint x = 10;\nvp = &x;\nprintf("%d", *(int*)vp);  // must cast\nint *np = NULL;\n// *np = 5;  // undefined behavior!
33

What is the difference between recursive and iterative solutions?

  • Recursive - function calls itself. Cleaner for tree/graph problems. Uses stack space. Risk of stack overflow.
  • Iterative - uses loops. More memory-efficient. Generally faster.
Example
int factR(int n) { return n <= 1 ? 1 : n * factR(n-1); }\nint factI(int n) {\n  int r = 1;\n  for (int i = 2; i <= n; i++) r *= i;\n  return r;\n}
34

What is the difference between enum and #define for constants?

  • enum - creates a named integer type. Values auto-assigned (0,1,2...). Type-checked. Debugger-friendly.
  • #define - textual substitution. No type. No automatic sequencing.
Example
enum Direction { NORTH, SOUTH, EAST, WEST }; // 0,1,2,3\nenum Status { OK=200, NOT_FOUND=404, ERROR=500 };\nenum Direction d = NORTH;
35

What is the difference between memcpy and memmove?

  • memcpy(dest, src, n) - copies n bytes. Undefined behavior if regions overlap.
  • memmove(dest, src, n) - copies n bytes safely even if regions overlap. Slightly slower.
Example
char str[] = "Hello World";\nmemmove(str + 6, str, 5);  // safe overlap\nchar dest[20];\nmemcpy(dest, str, strlen(str) + 1); // non-overlapping
36

What is the difference between sizeof and strlen?

  • sizeof(arr) - compile-time operator. Returns total bytes allocated including null terminator.
  • strlen(str) - runtime function. Returns number of characters before the null terminator.
Example
char str[] = "Hello";\nprintf("%zu", sizeof(str));  // 6 (5 chars + null)\nprintf("%zu", strlen(str));  // 5 (without null)
37

What is the difference between atoi and strtol?

  • atoi(str) - converts string to int. No error detection. Returns 0 for invalid input.
  • strtol(str, endptr, base) - converts string to long. Detects errors via endptr. Preferred.
Example
int n = atoi("42");          // 42, no error check\nchar *end;\nlong l = strtol("42abc", &end, 10);\nprintf("%s", end);  // "abc" - where conversion stopped
38

What is the difference between const pointer and pointer to const?

  • const int *ptr - pointer to const int. Cannot modify the value. Pointer can be reassigned.
  • int * const ptr - const pointer to int. Cannot reassign the pointer. Can modify the value.
  • const int * const ptr - both pointer and value are const.
Example
int x = 5, y = 10;\nconst int *p1 = &x;  // *p1 = 6 is error; p1 = &y is OK\nint * const p2 = &x; // p2 = &y is error; *p2 = 6 is OK
39

What is the difference between a macro function and a regular function?

  • Macro function (#define) - expanded inline by preprocessor. No type checking. No call overhead. Side effects with expressions.
  • Regular function - type-checked. Has call overhead. Safer. Use inline for performance.
Example
#define MAX(a,b) ((a)>(b)?(a):(b))  // macro\nMAX(x++, y++);  // x or y incremented twice!\nstatic inline int max(int a, int b) { return a > b ? a : b; }
40

What is the difference between stack overflow and buffer overflow?

  • Stack overflow - call stack exceeds its limit. Usually from infinite recursion or very large local arrays.
  • Buffer overflow - writing beyond the bounds of an array. Can corrupt adjacent memory and cause security vulnerabilities.
Example
void infinite() { infinite(); }  // stack overflow\nchar buf[10];\nstrcpy(buf, "This is way too long"); // buffer overflow!
41

What is the difference between while and do-while loops?

  • while - condition checked before each iteration. May not execute at all if condition is false initially.
  • do-while - executes at least once. Condition checked after each iteration.
Example
int i = 10;\nwhile (i < 5) { printf("never"); }  // never executes\ndo { printf("once"); } while (i < 5); // executes once
42

What is the difference between break and continue?

  • break - exits the loop or switch statement immediately.
  • continue - skips the rest of the current iteration and moves to the next.
Example
for (int i = 0; i < 10; i++) {\n  if (i == 3) continue;  // skip 3\n  if (i == 7) break;     // stop at 7\n  printf("%d ", i);      // 0 1 2 4 5 6\n}
43

What is the difference between call by value and call by reference for arrays?

Arrays are always passed by reference in C - the function receives a pointer to the first element. Modifying the array inside the function modifies the original.

Example
void modify(int arr[], int n) {\n  arr[0] = 99;  // modifies original\n}\nvoid readOnly(const int arr[], int n) {\n  // arr[0] = 99;  // compile error\n}
44

What is the difference between exit() and return in main()?

  • return in main() - returns control to the OS. Calls atexit() handlers and flushes buffers.
  • exit(status) - terminates from anywhere. Also calls atexit() handlers and flushes buffers.
  • _exit(status) - terminates immediately without cleanup. Use only in child processes after fork().
45

What is the difference between printf format specifiers %d, %u, %f, %s, %p?

  • %d / %i - signed decimal integer.
  • %u - unsigned decimal integer.
  • %f - floating point (decimal notation).
  • %s - null-terminated string.
  • %p - pointer address.
  • %c - single character.
  • %x - hexadecimal integer.
  • %zu - size_t (use for sizeof/strlen results).
46

What is the difference between memset and bzero?

  • memset(ptr, value, n) - fills n bytes with value. Standard C function.
  • bzero(ptr, n) - fills n bytes with zeros. POSIX only, deprecated. Use memset(ptr, 0, n) instead.
Example
int arr[10];\nmemset(arr, 0, sizeof(arr));  // zero all elements\nmemset(arr, -1, sizeof(arr)); // fill with 0xFF bytes
47

What is the difference between fopen modes r, w, a, r+, w+, a+?

  • "r" - read only. File must exist.
  • "w" - write only. Creates or truncates.
  • "a" - append only. Creates if not exists.
  • "r+" - read and write. File must exist. No truncation.
  • "w+" - read and write. Creates or truncates.
  • "a+" - read and append. Creates if not exists.
48

What is the difference between local scope, file scope, and block scope?

  • Block scope - variables inside {} braces. Accessible only within that block.
  • Function scope - labels (goto targets) are function-scoped.
  • File scope - variables declared outside all functions. Accessible throughout the file.
  • Global scope - extern variables accessible across multiple files.
49

What is the difference between structure padding and packing?

  • Structure padding - compiler adds extra bytes between members to align them to their natural alignment. Improves performance but wastes memory.
  • Structure packing - forces no padding using __attribute__((packed)) or #pragma pack. Saves memory but may be slower.
Example
struct Padded { char c; int i; };   // sizeof = 8 (padding added)\nstruct __attribute__((packed)) Packed { char c; int i; }; // sizeof = 5
50

What is the difference between static and dynamic memory allocation?

  • Static allocation - size determined at compile time. Stack or data segment. Fast. Cannot resize.
  • Dynamic allocation - size determined at runtime using malloc/calloc. Heap. Can resize with realloc. Must be freed manually.

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.