LearnPracticeExamsMocks

Clear practice, useful explanations and steady progress for exam preparation.

Study

AptitudeLogical reasoningVerbal abilityTechnical aptitudeAI & modern dev

Explore

Practice libraryLocal progressExam patternsFor collegesSearchAbout AISEAFAQ

Trust & support

ContactReport a problemContent correctionsAccessibility
© 2026 AISEA. Built for focused learning.Privacy · Terms · Editorial policy
Home
›Technical Aptitude
›C Programming
Technical
Programming Concepts
Data Structures
Algorithms
DBMS
Operating Systems
Computer Networks
C ProgrammingPractice
Java
Python

C programming MCQs with answers and explanations

Revise C types, operators, loops, functions, arrays and pointers with concept notes and explained questions. Practise reasoning about code for technical placement and GATE CS preparation.

100 practice questionsPage updated 24 Sept 2026Review metadata pendingPractice questions
Practise this concept

C programming is a procedural, general-purpose programming language developed by Dennis Ritchie at Bell Labs in 1972. It is widely used for system programming, embedded systems, and developing operating systems due to its efficiency and direct hardware control capabilities. C provides low-level memory access through pointers, rich set of built-in operators, and a comprehensive standard library.

Key formulas and rules

10 rules
1

Pointer Arithmetic: *(ptr + i) accesses the element at byte address address(ptr)+i×sizeof(∗ptr)

2

Array Indexing Equivalence: arr[i] ≡ *(arr + i) ≡ *(i + arr) ≡ i[arr]

3

Array Element Count: sizeof(arr) / sizeof(arr[0]) calculates total elements in statically allocated arrays

4

Structure Padding: sizeof(struct)≥∑sizeof(members) due to alignment padding to member boundaries

5

Bitwise AND & OR: a & b =1 iff both bits are 1; a | b =1 if at least one bit is 1

6

Bitwise Shifts: a << n =a×2n (left shift); a >> n =⌊a/2n⌋ (arithmetic right shift for non-negative integers)

7

Two's Complement Representation: −x=∼x+1 (invert all bits and add 1)

8

Dynamic Memory Allocation: malloc(n * sizeof(type)) allocates n×sizeof(type) contiguous uninitialized bytes

9

String Length: strlen(s) returns the character count up to but excluding the null terminator '\0'

10

Operator Precedence Hierarchy: Postfix () [] -> > Unary ++ -- * & > Multiplicative * / % > Additive + - > Shift << >> > Relational < > > Equality == != > Bitwise & ^ | > Logical && || > Ternary ?: > Assignment =

Key concepts

Pointers and Pointer Arithmetic

A pointer is a variable that stores the memory address of another variable. In C, pointers are declared using the * operator. Key operations include: 1) Address-of (&): Gets the memory address of a variable, 2) Dereference (*): Accesses the value at a pointer's address, 3) Pointer arithmetic: Adding/subtracting integers to pointers moves by multiples of the data type size. For example, if ptr points to an int (4 bytes), ptr+1 actually adds 4 to the address. Void pointers can point to any data type but cannot be dereferenced directly. Function pointers store addresses of functions and enable callbacks. NULL pointer has value 0 and points to nothing.

Arrays and Strings

Arrays in C are contiguous memory blocks storing elements of the same type. Array name acts as a pointer to the first element, so arr[i] is equivalent to *(arr+i). Multi-dimensional arrays are stored in row-major order. Strings are character arrays terminated by '\0' (null character). The %s format specifier reads until whitespace, while %c reads a single character. Common string functions include: strcpy(), strcat(), strlen(), strcmp(), strstr(), strtok(). Important: String literals are stored in read-only memory, so modifying them causes undefined behavior. Character arrays must have space for the null terminator. fgets() is safer than gets() for string input.

Structures and Unions

A structure (struct) is a user-defined data type that groups variables of different types. Memory layout includes padding bytes for alignment optimization. The sizeof a struct may be larger than the sum of its members. Access members using dot operator (.) for structs and arrow operator (->) for struct pointers. A union is similar but all members share the same memory location - only one member can hold a value at a time. The union size is at least the size of its largest member, rounded up to its alignment requirement. Typedef creates aliases for data types, making code cleaner. Nested structures allow structures within structures. Self-referential structures (containing pointers to same type) are essential for linked lists and trees.

Dynamic Memory Management

C provides four functions for dynamic memory: malloc() allocates uninitialized memory, calloc() allocates and zero-initializes, realloc() resizes existing allocation, and free() releases memory. These functions operate on the heap. Always check if allocation returned NULL. Memory leaks occur when allocated memory is not freed. Dangling pointers point to freed memory. Double-free errors cause undefined behavior. Wild pointers are uninitialized pointers. Buffer overflow happens when writing beyond allocated memory. Valgrind and similar tools help detect memory issues. Good practice: Set pointers to NULL after freeing.

Bit Manipulation

C provides six bitwise operators: & (AND), | (OR), ^ (XOR), ~ (NOT), << (left shift), >> (right shift). Left shift by n multiplies by 2n. Right shift divides by 2n for positive numbers (implementation-defined for negatives). Common patterns: Setting a bit (x | (1<<n)), Clearing a bit (x & ~(1<<n)), Toggling a bit (x^{1<<n}), Checking a bit (x & (1<<n)). Bit fields in structures allow compact storage. Bitwise operations are faster than arithmetic and essential for embedded programming, device drivers, and low-level hardware control.

Preprocessor Directives

The C preprocessor runs before compilation. #include inserts header files. #define creates macros - object-like (constants) or function-like (with parameters). Use parentheses around macro parameters to avoid precedence issues. #ifdef, #ifndef, #if, #else, #elif, #endif provide conditional compilation. #pragma gives compiler-specific instructions. Predefined macros: __FILE__, __LINE__, __DATE__, __TIME__, __func__. Header guards (#ifndef/#define/#endif) prevent multiple inclusion. The # operator converts to string, ## concatenates tokens. Macros don't have type checking and can cause multiple evaluation of arguments.

Check the idea while it is fresh.Open a focused exercise without losing this article.Practise this concept

Worked examples

Example 1

What is the output of:
int arr[] = {10, 20, 30, 40, 50};
int∗ptr=arr;
printf("%d ", *(ptr++));
printf("%d ", ++ptr);
printf("%d ", (
ptr)++);

Solution

Step 1: ptr is initialized to point to arr[0] (value 10)
Step 2: *(ptr++) uses post-increment, so it prints *ptr (10) first, then ptr moves to arr[1]
Step 3: ++ptr uses pre-increment, so ptr moves to arr[2] first, then prints 30
Step 4: (
ptr)++ uses post-increment on the value, so it prints 30 first, then arr[2] becomes 31
Output: 10 30 30
Final array: {10, 20, 31, 40, 50}

Example 2

Find the output:
int x=5, y=10;
if (x++ > 5 && ++y > 10)
printf("True");
else
printf("False, x=%d, y=%d", x, y);

Solution

Step 1: x++ > 5 evaluates to (5 > 5) which is false, then x becomes 6
Step 2: Due to short-circuit evaluation, ++y > 10 is NOT evaluated because the first condition was false
Step 3: The if condition is false, so the else block executes
Step 4: x is now 6 (incremented), y remains 10 (not incremented)
Output: False, x=6, y=10
Key concept: && short-circuits - if left operand is false, right operand is not evaluated.

Example 3

What does this code print?
char str[] = "Hello";
char p = str;
while (
p) {
printf("%c", p++);
if (
(p-1) == 'l') break;
}

Solution

Step 1: p points to 'H' (str[0])
Step 2: Loop 1: *p is 'H' (non-zero, so true), print 'H', then p increments to 'e'
Step 3: Check *(p-1) which is 'H', not 'l', continue
Step 4: Loop 2: *p is 'e', print 'e', p increments to 'l'
Step 5: Check *(p-1) which is 'e', not 'l', continue
Step 6: Loop 3: *p is 'l', print 'l', p increments to 'l'
Step 7: Check *(p-1) which is 'l', matches 'l', break
Output: Hel
The loop prints characters until 'l' is encountered and printed.

Example 4

Analyze the output:
struct Point {int x; char y;};
printf("%lu", sizeof(struct Point));
// Assuming: int=4 bytes, char=1 byte

Solution

Step 1: struct Point has two members: int x (4 bytes) and char y (1 byte)
Step 2: Raw size would be 4+1=5 bytes
Step 3: However, padding is added for alignment. After char y, 3 padding bytes are added
Step 4: This ensures that if the struct were in an array, each Point starts at a 4-byte boundary
Step 5: Total size = 4 (x) + 1 (y) + 3 (padding) = 8 bytes
Output: 8 (on most systems)
Note: Actual padding depends on compiler and platform, but typically 8 on 32/64-bit systems.

Representative solved questions

See the kind of question in this topic before opening the full practice set.

Question 1

What is the output of:

#include <stdio.h>
int main() {
int a=10, b=20;
printf("%d", a+++++b);
return 0;
}

  1. A.

    30

  2. B.

    31

  3. C.

    Compilation error

  4. D.

    Undefined behavior

Answer: C. Compilation error

Explanation

The expression a+++++b cannot be parsed as a valid C expression after tokenization, so the program fails to compile. Answer: Compilation error.

Sources and review notes

This is an AISEA-authored practice question.

Review status: accepted · Reviewed 2026-08-13 · structure and answer-key checks, editorial quality checks, duplicate screening

Question 2

What is the output of:

#include <stdio.h>
#define SQUARE(x) x * x
int main() {
int a=5;
printf("%d", SQUARE(a + 1));
return 0;
}

  1. A.

    36

  2. B.

    11

  3. C.

    25

  4. D.

    30

Answer: B. 11

Explanation

Step 1: The macro SQUARE(x) expands to x * x.
Step 2: SQUARE(a + 1) expands to a + 1 * a + 1 (not (a+1)*(a+1)).
Step 3: Substituting a=5: 5 + 1 * 5 + 1.
Step 4: Due to operator precedence: 5+(1∗5)+1=5+5+1=11.
Answer: 11

Sources and review notes

This is an AISEA-authored practice question.

Review status: accepted · Reviewed 2026-08-13 · structure and answer-key checks, editorial quality checks, duplicate screening

Question 3

What is the size of the following structure on a 32-bit system?

struct Node {
char c;
int i;
char d;
};

  1. A.

    6 bytes

  2. B.

    8 bytes

  3. C.

    12 bytes

  4. D.

    16 bytes

Answer: C. 12 bytes

Explanation

Step 1: On a 32-bit system, int is typically 4 bytes with 4-byte alignment.
Step 2: char c (1 byte) + 3 bytes padding to align int.
Step 3: int i (4 bytes).
Step 4: char d (1 byte) + 3 bytes padding for structure alignment.
Step 5: Total: 1+3+4+1+3=12 bytes.
Answer: 12 bytes

Sources and review notes

This is an AISEA-authored practice question.

Review status: accepted · Reviewed 2026-08-13 · structure and answer-key checks, editorial quality checks, duplicate screening

Common mistakes and useful habits

  • Always initialize pointers to NULL or a valid address before use to avoid undefined behavior from wild pointers.
  • Use sizeof() instead of hardcoding sizes - it makes code portable across different architectures.
  • Check return value of malloc/calloc - if NULL, the allocation failed (out of memory).
  • Remember that array parameters in functions decay to pointers - sizeof(array) won't work as expected inside functions.
  • Use strncpy or snprintf instead of strcpy to prevent buffer overflows, noting that strncpy does not guarantee NUL-termination if the source length reaches or exceeds the destination buffer size (dest[n-1] = '\0' should be enforced).
  • When using bit manipulation with signed integers, be aware that right shift of negative numbers is implementation-defined.
  • Use parentheses liberally in macros to avoid operator precedence bugs, especially with arithmetic expressions.
  • Free dynamically allocated memory in the reverse order of allocation when possible - it helps catch double-free errors.
  • Remember that sizeof(char) is always 1 by definition, but sizeof(int) can vary between platforms.
  • In printf, %d is for int, %ld for long, %f for float/double, %c for char, %s for strings, %p for pointers.

Ready to test your understanding?

Work through 100 questions with explanations after each answer.

Start practice
Next topic: Java →

Keep building the same skill family.

Programming Concepts

Variables, loops, functions, recursion

Open practice
Data Structures

Arrays, stacks, queues, trees, graphs

Open practice
Algorithms

Sorting, searching, complexity analysis

Open practice
On this page
Formulas and rulesKey conceptsWorked examplesRepresentative questionsCommon mistakesRelated practice

Suggest a correction