Pointer Practice questions in C and C++ with clear explanations, memory concepts, and real coding examples. Perfect for beginners and interview prep.
Pointer Practice Questions are designed to help beginners and intermediate programmers master pointers step by step. This collection includes easy to advanced pointer questions with clear explanations, real coding logic, and common interview-based problems to improve your confidence in C and C++ programming.
Pointer Basic Question
1. What is the output?
#include <stdio.h>
int main() {
int a = 10;
int *p = &a;
printf("%d", *p);
return 0;
}
Answer: 10
Why: p stores address of a. *p gives the value stored at that address → 10.
2. What will be printed?
int a = 5;
int *p = &a;
printf("%d", a);
Answer: 5
Why: Pointer is not used in printf. Direct variable access.
3. What is the output?
int a = 7;
int *p;
p = &a;
printf("%d", *p);
Answer: 7
Why: Pointer assigned later, still valid.
4. Identify correct pointer declaration
int a = 10;
int *p = a;
Answer: Compilation Error
Why: Pointer must store address, not value.
Correct:
int *p = &a;
5. What will be the output?
int a = 10;
int *p = &a;
*p = 20;
printf("%d", a);
Answer: 20
Why: Changing *p changes the value of a.
6. What is printed?
int a = 3;
int b = 4;
int *p = &a;
p = &b;
printf("%d", *p);
Answer: 4
Why: Pointer now points to b.
7. What is the output?
int a = 5;
int *p = &a;
printf("%p", p);
Answer: Address of a (hex value)
Why: %p prints memory address.
8. What will be printed?
int a = 10;
int *p = &a;
printf("%p", &a);
Answer: Same address as pointer value.
Why: p == &a
Output?
int a = 1;
int b = 2;
int *p = &a;
*p = b;
printf("%d", a);
Answer: 2
Why: *p = b assigns value of b to a.
10. What happens?
int *p;
printf("%d", *p);
Answer: Undefined Behavior
Why: Pointer is uninitialized.
11. Output?
int a = 10;
int *p = &a;
printf("%d %d", a, *p);
Answer: 10 10
12. Pointer and variable relation
int a = 5;
int *p = &a;
a = 8;
printf("%d", *p);
Answer: 8
Why: Pointer always reflects current value of variable.
13. Output?
int a = 10;
int *p = &a;
printf("%d", ++(*p));
Answer: 11
Why: Increment value at address.
14. What will be printed?
int a = 10;
int *p = &a;
(*p)++;
printf("%d", a);
Answer: 11
15. Output?
int a = 10;
int *p = &a;
printf("%d", *p++);
Answer: Tricky / Undefined for beginner
Why: Pointer moves, dereference happens first. Avoid this at beginner level.
Correct way to print value using pointer?
Correct answer:
printf("%d", *p);
Wrong:
printf("%d", p);
16. Output?
int a = 5;
int *p = &a;
*p = *p + 5;
printf("%d", a);
Answer: 10
17. What will be printed?
int a = 10;
int b = 20;
int *p = &a;
int *q = &b;
printf("%d %d", *p, *q);
Answer: 10 20
18. Output?
int a = 100;
int *p = &a;
printf("%d", *(&a));
Answer: 100
Why: &a gives address, * gets value.
19. Final beginner check
int a = 10;
int *p = NULL;
p = &a;
printf("%d", *p);
Answer: 10
Why: Pointer safely assigned before use.
POINTER + ARRAY
1. What is the output?
int arr[] = {10, 20, 30, 40};
int *p = arr;
printf("%d", *p);
Answer: 10
Why: Array name stores address of first element.
2. Output?
int arr[] = {5, 10, 15};
int *p = arr;
printf("%d", *(p + 1));
Answer: 10
Why: p + 1 → next integer (4 bytes ahead).
Output?
int arr[] = {1, 2, 3};
int *p = arr;
printf("%d", *(arr + 2));
Answer: 3
Why: arr behaves like pointer to first element.
3.What will be printed?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d", p[1]);
Answer: 20
Why: p[i] is same as *(p + i).
4.Output?
int arr[] = {10, 20, 30};
printf("%d", *(arr + 1));
Answer: 20
5. Output?
int arr[] = {10, 20, 30};
printf("%d", arr[2]);
Answer: 30
6. Output?
int arr[] = {1, 2, 3};
int *p = arr;
printf("%d", *p + 1);
Answer: 2
Why: Dereference first → 1 + 1.
7. Output?
int arr[] = {1, 2, 3};
int *p = arr;
printf("%d", *(p + 1) + 1);
Answer: 3
8. Output?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d", *p++);
Answer: 10
Why: Dereference first, then pointer moves.
POINTER ARITHMETIC
1.Output?
int arr[] = {10, 20, 30};
int *p = arr;
p++;
printf("%d", *p);
Answer: 20
Why: Pointer moves to next element.
2. Output?
int arr[] = {10, 20, 30};
int *p = &arr[1];
printf("%d", *(p - 1));
Answer: 10
3. Output?
int arr[] = {5, 10, 15};
int *p = arr;
printf("%d", *(p + 2));
Answer: 15
4. What will be printed?
int arr[] = {1, 2, 3, 4};
int *p = arr;
printf("%d", *(p + 3));
Answer: 4
5. Output?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d", *(++p));
Answer: 20
Why: Pointer increment happens first.
6. Output?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d", *(p++));
Answer: 10
7. Output?
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d %d", *p, *(p + 1));
Answer: 10 20
8. Output?
int arr[] = {10, 20, 30};
int *p = arr;
*p = *(p + 2);
printf("%d", arr[0]);
Answer: 30
9. Output?
int arr[] = {1, 2, 3};
int *p = arr;
*(p + 1) = 10;
printf("%d", arr[1]);
Answer: 10
10. Output?
int arr[] = {2, 4, 6};
int *p = arr;
printf("%d", *(p + 1) * 2);
Answer: 8
11. Array traversal using pointer
int arr[] = {1, 2, 3};
int *p = arr;
for(int i = 0; i < 3; i++) {
printf("%d ", *(p + i));
}
Answer: 1 2 3
POINTER + FUNCTION PRACTICE QUESTIONS
1. Passing variable by value
#include <stdio.h>
void update(int x) {
x = 20;
}
int main() {
int a = 10;
update(a);
printf("%d", a);
}
Answer: 10
Why: Only copy of a is passed.
2. Passing variable using pointer
void update(int *x) {
*x = 20;
}
int main() {
int a = 10;
update(&a);
printf("%d", a);
}
Answer: 20
Why: Pointer modifies original variable.
3. Output?
void change(int *p) {
*p = *p + 5;
}
int main() {
int a = 10;
change(&a);
printf("%d", a);
}
Answer: 15
4. Swap without pointer
void swap(int a, int b) {
int t = a;
a = b;
b = t;
}
int main() {
int x = 10, y = 20;
swap(x, y);
printf("%d %d", x, y);
}
Answer: 10 20
Why: Swap fails without pointers.
5. Swap using pointer
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
int main() {
int x = 10, y = 20;
swap(&x, &y);
printf("%d %d", x, y);
}
Answer: 20 10
6. Passing array to function
void print(int *p) {
printf("%d", p[1]);
}
int main() {
int arr[] = {10, 20, 30};
print(arr);
}
Answer: 20
Why: Array decays to pointer.
7. Same example, different syntax
void print(int p[]) {
printf("%d", *(p + 2));
}
int main() {
int arr[] = {5, 10, 15};
print(arr);
}
Master C structures and unions with this practice set. Learn memory, pointers, bitfields, and flexible arrays for interviews and real-world coding.
Master the essential Structure and Union Interview Questions in C with this comprehensive practice set. “Structure and Union Interview Questions in C: Master Practice Set #2” is designed for students, freshers, and professionals who want to strengthen their C programming skills. Explore in-depth questions covering structure memory layout, padding, alignment, nested structures, unions, bitfields, flexible arrays, and pointers to structures. Each question comes with clear explanations to help you understand concepts thoroughly and perform confidently in interviews. Ideal for exam preparation, technical interviews, and real-world programming scenarios.
If you’re learning C programming and want to strengthen your fundamentals before practicing Structures and Unions Interview Questions, you should explore this detailed beginner-friendly guide on structures: Structures in C – Complete Guide It explains structure syntax, memory layout, padding, nesting, and real-world examples in a very simple way. Reading this will give you a strong foundation before jumping into advanced interview questions.
Structure and union interview questions in c
1.What is structure padding?
Structure padding is the extra unused bytes automatically inserted by the compiler inside a structure to satisfy data alignment requirements of the CPU.
Most processors access data faster when variables are placed at specific memory boundaries (usually multiples of 2, 4, or 8 bytes). To achieve this, the compiler inserts padding bytes between structure members so that each member starts at its natural alignment boundary.
Example (Easy Explanation)
struct example {
char c; // 1 byte
int x; // 4 bytes
};
Without padding
char c; → 1 byte
int x; → 4 bytes
Total = 5 bytes
But compiler actually allocates 8 bytes, not 5.
Why?
int must start at 4-byte boundary.
After the 1-byte char, compiler inserts 3 padding bytes.
Final structure size becomes:
c | _ | _ | _ | x x x x
Total size = 8 bytes
Simple Rule
Each member must start at an address which is multiple of its size (alignment).
Example:
char → 1-byte alignment
short → 2-byte alignment
int → 4-byte alignment
double → 8-byte alignment
Example with Full Padding
struct test {
char a; // 1 byte
double b; // 8 bytes
int c; // 4 bytes
};
Memory layout:
a | _ _ _ _ _ _ _ | b b b b b b b b | c c c c
Breakdown:
After a, compiler inserts 7 padding bytes to align double b.
After b, int c needs 4-byte alignment → fits directly.
Final struct size = 1 + 7 + 8 + 4 = 20 bytes
Compiler rounds to nearest multiple of largest alignment (8) → 24 bytes total
Why Padding Is Used?
Padding exists because:
a)Faster memory access
Aligned data is fetched in 1 CPU cycle instead of multiple cycles.
b)Prevent bus alignment faults
Some CPUs cannot fetch misaligned data at all → program crashes.
How to Remove Padding (Packing)
#pragma pack(1)
struct test {
char a;
double b;
int c;
};
This makes struct size = 1 + 8 + 4 = 13 bytes (no padding)
But accessing unaligned memory is slower and unsafe on some CPUs.
In simple : Structure padding = automatic empty bytes added to align structure members for fast memory access and CPU efficiency.
2.What is structure alignment?
Structure alignment is the rule that each member inside a structure must start at an address that matches its natural alignment requirement, and the structure itself must also be aligned according to the largest member’s alignment.
In simple words:
Structure Alignment = How structure members are arranged in memory to meet CPU alignment rules
Why Alignment Is Needed?
Most CPUs are designed to access data faster when variables are located at specific memory boundaries:
char → 1-byte boundary
short → 2-byte boundary
int → 4-byte boundary
double → 8-byte boundary
If data is misaligned (not on correct boundary), CPU needs extra cycles, or sometimes crashes (on some architectures).
Structure Alignment Rules
Rule 1 : Member Alignment
Each member of a structure is placed at an offset that is multiple of its alignment requirement.
Example:
struct A {
char c; // alignment 1
int x; // alignment 4
};
Memory layout:
c | _ _ _ | x x x x
Here:
char c starts at offset 0 (OK).
int x must start at 4-byte boundary, so compiler inserts 3 padding bytes.
Rule 2 : Structure Alignment
The overall size of the structure is padded to be a multiple of the largest alignment of its members.
struct Test {
char a; // 1 byte
int b; // 4 bytes
char c; // 1 byte
};
Step-by-step alignment:
a at offset 0
b must start at offset 4 → 3 padding bytes added
c at offset 8
Structure must align to largest member (4 bytes) → padded to 12 bytes
Layout:
a | _ _ _ | b b b b | c | _ _ _
Difference Between Padding vs Alignment
Concept
Meaning
Padding
Extra unused bytes added by compiler
Alignment
Rules that decide when padding is needed
Alignment causes padding.
Why Structure Alignment Is Important?
Faster memory access
Avoids multiple memory cycles.
Prevents hardware traps
Some processors cannot read misaligned memory.
Ensures consistent layout
Important in embedded systems, device drivers, networking packets, OS work.
Simple One-Line Definition
Structure alignment ensures each member and the entire structure are placed at memory addresses that match the CPU’s required boundaries for fastest and safest access.
3.What is structure packing?
Structure packing means telling the compiler NOT to insert padding bytes between structure members. It forces the structure to be stored in memory using the minimum number of bytes, even if alignment rules are violated.
In simple words:
Structure Packing = Remove padding → store structure in tight, compact memory
Why Use Structure Packing?
Structure packing is used when:
Memory is very limited (embedded systems)
You are sending/receiving data over network or protocols (CAN, UART, I2C frames)
Reading hardware registers where exact byte layout matters
Packing ensures the structure layout matches your exact required binary format.
Example Without Packing
struct Normal {
char a; // 1 byte
int b; // 4 bytes
};
✔ All members are stored back-to-back ✔ Structure size becomes equal to the sum of member sizes ✔ No padding bytes are inserted
2. Using GCC/Clang __attribute__((packed)) (Linux, QNX, Embedded)
struct Test {
char a;
int b;
char c;
} __attribute__((packed));
Works on Linux, QNX, Bare-metal, ARM, ESP32, STM, etc.
No padding
Useful in embedded systems & protocol structures
3. Using #pragma options align=packed (For Some Compilers)
(Used in some older compilers or non-GCC embedded compilers)
#pragma options align=packed
struct Test {
char a;
int b;
char c;
};
#pragma options align=reset
IMPORTANT NOTE
Disabling padding → creates unaligned memory access, which may cause:
Slower access
Extra instructions
Crashes on some CPUs (ARM, DSP, some microcontrollers)
So only use packing when:
Working with communication protocols
Defining hardware registers
Sending/receiving binary data
Memory is critical
One-Line Answer (Interview Ready)
Structure padding can be disabled using #pragma pack(1) or __attribute__((packed)), which forces the compiler to place members without adding any padding bytes.
4.Why does padding exist in structures?
Padding exists in structures because the CPU and memory system work fastest and safest when data is stored at aligned memory addresses. To satisfy these alignment rules, the compiler adds extra unused bytes (padding) between structure members.
Below is the complete explanation
Why Does Padding Exist in Structures?
Padding exists for three main reasons:
To Improve CPU Performance (Speed)
Most CPUs (x86, ARM, Cortex-M, RISC-V) can access data much faster when variables start at specific memory boundaries.
Examples:
Data Type
Natural Alignment
char
1 byte
short
2 bytes
int
4 bytes
double
8 bytes
If an int is placed at a misaligned address (not divisible by 4), the CPU may need:
2 memory cycles instead of 1, or
Special handling instructions
Multiple reads and merges
Padding avoids this slowdown.
To Avoid Hardware Alignment Faults
Some processors CANNOT read misaligned data at all.
For example:
Many ARM Cortex processors (Cortex-M3, M4, M7)
Many DSP processors
Some embedded controllers
Will crash (bus fault) if you try to read an unaligned int or double.
Padding ensures that every structure member meets alignment rules → no crash.
To Maintain Consistent, Predictable Memory Layout
The compiler uses a standard alignment rule so that:
Different compilers
Different systems
Different CPU architectures
all interpret structures the same way (unless packing is enabled).
This is important for:
ABI (Application Binary Interface) compatibility
Library functions
OS data structures
Device drivers
Hardware register mapping
Example: Why Padding Needed
struct S {
char a; // 1 byte
int b; // needs 4-byte alignment
};
Without padding:
Address: 0 1 2 3 4 5 ...
Data a b b b b
Here b starts at address 1, which is NOT divisible by 4 → misaligned.
With padding (compiler version):
a | _ _ _ | b b b b
b now starts at 4, a correct aligned boundary.
In Simple Words
Padding exists to make the processor happy. It keeps data aligned so the CPU can access it quickly and safely.
One-Line Interview Answer
Padding exists to align structure members according to CPU alignment requirements, ensuring faster memory access and preventing hardware faults.
5.Why do unions not have padding between members?
Unions do not have padding between members because all members share the same memory location. There is only ONE memory block, so the compiler does not need to insert padding between members (since they are not stored one after another).
Let’s break it down clearly .
Key Reason
In a union, all members start at the same memory address → no padding needed.
Unlike structures:
struct {
char a;
int b; // placed after 'a' → padding needed
}
In a union:
union {
char a; // starts at offset 0
int b; // also starts at offset 0
}
Since every member begins from offset 0, there is no gap (padding) between them.
Why Is This Possible?
A union works with overlapping memory:
Only one member is active at a time
All members share the same storage
Compiler allocates memory equal to the size of the largest member
Example:
union U {
char c; // 1 byte
int x; // 4 bytes
};
Size of union U = 4 bytes (size of int, the largest member)
There is no arrangement of fields, so no alignment adjustment is needed inside.
Important Point
Padding inside a union does not exist. But the union itself may have padding at the end to satisfy its overall alignment.
Example:
union U {
char c; // 1 byte
int x; // 4 bytes (biggest)
};
Alignment of union = alignment of the largest member (int = 4 bytes)
Size of union = 4 (already aligned, so no extra padding needed after union)
One-Line Interview Answer
Unions do not have padding between members because all members share the same starting address and occupy the same memory block, so the compiler does not need to align them separately.
6.Can we compare two structures using == operator?
No, you cannot compare two structures using the == operator in C. The == operator does not support structure-to-structure comparison.
Trying this:
struct A { int x; float y; };
struct A a1, a2;
if (a1 == a2) { }
Compilation error:invalid operands to binary ==
Why Can’t We Compare Structures with ==?
Because:
A structure may contain multiple members, different types → no single rule for ==
It may contain padding bytes, so memory layout is not guaranteed identical
Structure comparison is not defined in the C standard
Example: Padding Makes Comparison Unsafe
struct S {
char c; // 1 byte
int x; // 4 bytes (but after padding)
};
Even if:
s1.c == s2.c AND s1.x == s2.x
The padding bytes between them may contain garbage, so a memory-level comparison becomes invalid.
b)Use memcmp() (only if no padding or packed struct)
if (memcmp(&a1, &a2, sizeof(a1)) == 0)
printf("Equal");
Use this only if:
You pack the structure (#pragma pack(1) or __attribute__((packed)))
OR you know there is no padding
Otherwise, padding bytes may differ → false result.
Interview Perfect Answer
No. Structures cannot be compared using the == operator because C does not support direct comparison of composite types, and padding makes memory comparison unreliable. You must compare structure members manually or use memcmp() only for packed or padding-free structures.
7.Can we compare two union variables using == operator?
No, you cannot compare two union variables using the == operator in C. Just like structures, unions are composite data types, and C does not allow direct comparison using relational operators.
Trying this:
union U {
int x;
float y;
};
union U u1, u2;
if (u1 == u2) { }
Compilation Error:invalid operands to binary ==
Why Can’t We Compare Unions with ==?
a)Union is a composite type
The == operator works only on:
integers
floats
pointers
Not on struct/union/array types.
b)Only one member is valid at a time
A union may contain:
union U { int x; float y; char c; };
If you write:
u1.x = 10;
u2.y = 10.0;
Even though both “look” equal, their bit patterns are different, so comparing entire union memory is meaningless for C language rules.
c)Union may contain padding at the end
Even though unions don’t have padding between members, the total size may be padded to meet alignment requirements.
This makes raw comparison unreliable.
Correct Way to Compare Two Union Variables
a)Compare the active member explicitly
You must know which member is active.
if (u1.x == u2.x)
printf("Equal");
This is the correct method.
b)Use memcmp() (only sometimes safe)
If you know:
union contains only plain integer/char types
no padding is added
then:
if (memcmp(&u1, &u2, sizeof(u1)) == 0)
printf("Equal");
Not recommended unless union layout is 100% controlled (typical in embedded, protocol, register maps)
Interview Answer
No. Two union variables cannot be compared with the == operator because C does not allow comparison of composite types like structs or unions. You must compare the specific active member manually.
8.How do you pass a structure to a function?
You can pass a structure to a function in three ways in C:
1. Pass structure by value (copy of structure)
This is the most common interview answer.
#include <stdio.h>
struct Emp {
int id;
float salary;
};
void display(struct Emp e) { // receives a COPY
printf("ID = %d, Salary = %.2f\n", e.id, e.salary);
}
int main() {
struct Emp e1 = {101, 50000.5};
display(e1); // pass structure by value
}
Function gets a copy
Original structure is not modified
2. Pass structure by pointer (pass address)
Used in embedded, large structures, modifying data.
You can return a structure by value, by returning a pointer (static/global/heap), or by filling a structure through an output pointer parameter. In Embedded C, returning via a pointer parameter is most efficient and safest.
10.Can a structure be initialized at the time of declaration?
Yes, a structure can be initialized at the time of declaration in C. This is called structure initialization and it is fully supported by the C language.
1. Initialization at Declaration (Normal Initialization)
struct Date {
int d, m, y;
};
struct Student {
int roll;
struct Date dob;
};
struct Student s = {1, {10, 5, 2000}};
Works for multi-level structures
Not Allowed: Initialization inside a function using assignment for whole struct (C89 limitation)
struct Emp e;
e = {101, 20000}; // ❌ invalid in C
But in C99, you can do:
e = (struct Emp){101, 20000}; // ✔ compound literal
Interview Answer
Yes. A structure can be initialized at the time of declaration using either normal initialization or designated initializers. Partial initialization is allowed, and remaining members are set to zero.
11.Can a union be initialized at the time of declaration?
Yes, a union can be initialized at the time of declaration, but with some important rules that are different from structures.
1. Only the FIRST member of the union can be initialized
Because all members share the same memory, C allows initialization of only the first member during declaration.
union U {
int x;
float y;
char c;
};
union U u1 = {10}; // initializes x = 10
Valid
Allowed by C standard
Only x (first member) gets initialized
Invalid: initializing any other member
This is NOT allowed:
union U u2 = {.y = 5.5}; // ❌ Not allowed in traditional C
2. But in C99, designated initializer is allowed
C99 allows:
union U u3 = {.y = 5.5}; // ✔ allowed in C99
This initializes y (even if not first member)
Only one member can be initialized
3. You cannot initialize multiple union members
Because all share the same memory location:
union U u4 = {10, 5.5}; // ❌ Not allowed
4. Strings can initialize a char[] or char* first member
Example:
union A {
char str[10];
int x;
};
union A a = {"Hello"}; // ✔ valid
Summary Table
Operation
Allowed?
Notes
Initialize union at declaration
✔
Only one member
Initialize first member
✔
Default rule
Designated initializer
✔
Allowed in C99
Initialize multiple members
❌
Only one allowed
Initialize non-first member (C89)
❌
Not supported
Initialize non-first member (C99)
✔
Using .member = value
Interview Answer
Yes, a union can be initialized at declaration, but only one member can be initialized, and by default only the first member may be initialized. C99 allows designated initializers, enabling initialization of any one specific member.
12.What happens if we read a union member that was not last written?
Reading a union member that was not the last written leads to undefined behavior in C.
What Happens? – Undefined Behavior
A union shares the same memory for all its members. Only one member is valid at a time — the one that was most recently written.
If you read a different member (not the last written one):
You get garbage data
Bytes are interpreted according to the type you read.
Since the bytes belong to a different type, the result is unpredictable.
No compiler error
The compiler will not warn you; it is logically wrong but syntactically correct.
Potential memory alignment issues
Reading incorrectly can break strict aliasing rules and cause undefined behavior.
Example: Reading Wrong Union Member
#include <stdio.h>
union U {
int x;
float y;
};
int main() {
union U u;
u.x = 10; // Last written member = x
printf("%f\n", u.y); // Reading y → undefined behavior
return 0;
}
u.y will interpret the binary bits of integer 10 as a float → garbage output.
Why is it undefined?
Because:
The C standard says only the active member (last stored) has a defined value.
Reading another member violates strict aliasing.
Valid Case: Type-Punning via Union (Only in GCC/Clang extension)
Some compilers allow:
union U {
int x;
float y;
};
u.x = 10;
float f = u.y; // works as type-punning (compiler extension)
But this is not standard C. Portable code must not rely on this.
Correct Practice (use memcpy)
int i = 10;
float f;
memcpy(&f, &i, sizeof(int)); // Safe type-punning
Final Answer
If you read a union member that was not last written, it results in undefined behavior because the memory contains data for a different type. The value is unpredictable and may violate strict aliasing rules.
13.What is a pointer to a structure?
A pointer to a structure is a pointer variable that stores the memory address of a structure variable. It allows you to access and modify structure members using the pointer, typically with the arrow operator (->).
Simple Explanation
If a structure is like a house, a structure pointer stores the address of that house.
Example
struct Student {
int id;
float marks;
};
struct Student s = {101, 85.5};
struct Student *ptr = &s; // pointer to structure
Here:
ptr stores the address of structure s
ptr->id gives access to the id member
ptr->marks gives access to marks
Accessing Members Through Pointer
Using arrow operator:
ptr->id
ptr->marks
Equivalent (but less readable):
(*ptr).id
(*ptr).marks
Why use structure pointers?
Efficient to pass to functions (only address copied)
Needed for dynamic memory allocation (malloc)
Used in linked lists, trees, stacks, queues
Allows modifying the original structure inside functions
One-line Interview Answer
A pointer to a structure is a pointer variable that holds the address of a structure and accesses its members using the -> operator.
If you want, I can also give MCQs, examples, or memory diagrams.
14.What is the arrow operator (->) used for?
The arrow operator (->) in C is used to access members of a structure or union through a pointer.
Simple Definition
The -> operator is used when you have a pointer to a structure and want to access its members directly.
Syntax
pointer_variable->member_name
Equivalent to:
(*pointer_variable).member_name
(but shorter and cleaner)
Example
struct Student {
int roll;
float marks;
};
struct Student s = {101, 85.5};
struct Student *ptr = &s; // pointer to structure
printf("%d", ptr->roll); // using -> operator
printf("%f", ptr->marks);
Why do we need ->?
Because a pointer does not directly contain structure members; it only contains the structure’s address.
So:
You cannot write ptr.roll ❌
You must write ptr->roll ✔
Or (*ptr).roll ✔ (but ugly)
Interview Answer
The arrow operator (->) is used to access structure or union members through a pointer variable.
15.What is a typedef structure?
A typedef structure in C is a way to give a new name (alias) to a structure type, so you can declare variables without writing the struct keyword every time.
It makes your code shorter, cleaner, and easier to read.
Syntax
typedef struct {
int id;
float salary;
} Employee;
struct Employee {
int id;
float salary;
};
struct Employee e1, e2; // must use 'struct' keyword every time
typedef removes the need for repeating struct.
Why use typedef with structures?
Cleaner and shorter code
Makes function parameters easier to read
Useful for complex/nested structures
Common in embedded systems, APIs, and libraries
Interview One-Liner
A typedef structure is a structure that is given an alias name using typedef, allowing you to declare variables without using the struct keyword.
16.What is a flexible array member in a structure?
A flexible array member (FAM) is a special type of array in a structure that has no fixed size, allowing the structure to have a variable-length array at the end.
It is mainly used in dynamic memory allocation when you don’t know the array size at compile time.
Key Points About Flexible Array Members
Declaration:
Must be the last member of the structure
Declared with empty square brackets []
Size:
The size is not specified in the structure definition
Memory is allocated dynamically at runtime
C Standard:
Introduced in C99
Syntax
struct Data {
int length;
int arr[]; // flexible array member
};
arr[] has no size; you provide size dynamically.
Example
#include <stdio.h>
#include <stdlib.h>
struct Data {
int length;
int arr[]; // flexible array member
};
int main() {
int n = 5;
// Allocate memory for structure + flexible array
struct Data *d = malloc(sizeof(struct Data) + n * sizeof(int));
d->length = n;
// Fill array
for(int i = 0; i < n; i++)
d->arr[i] = i * 10;
// Print array
for(int i = 0; i < n; i++)
printf("%d ", d->arr[i]);
free(d);
return 0;
}
Output:
0 10 20 30 40
Rules of Flexible Array Members
Must be the last member of the structure.
Cannot have more than one FAM in a structure.
Cannot have a size in declaration (just []).
Structure size does not include the FAM; you must allocate memory dynamically.
Use Cases
Dynamic-length strings or buffers in structures
Networking packets
Embedded systems with variable-length data
Data serialization/deserialization
One-Liner
A flexible array member is an array with no fixed size placed at the end of a structure, allowing dynamic memory allocation for variable-length data.
17.What are bitfields in structures?
Bitfields in structures allow you to store data using a specific number of bits instead of the full size of the data type. This is useful when you want memory-efficient storage for small data values or flags.
Key Points About Bitfields
Declared inside structures using a colon : followed by the number of bits.
Only works with integer types (int, unsigned int, signed int, char sometimes).
Useful for memory optimization in embedded systems or low-level programming.
Can be packed together by the compiler within the word boundary.
Syntax
struct Flags {
unsigned int a : 1; // 1-bit wide
unsigned int b : 3; // 3-bit wide
unsigned int c : 4; // 4-bit wide
};
a can store values 0 or 1
b can store values 0 to 7 (3 bits)
c can store values 0 to 15 (4 bits)
Example
#include <stdio.h>
struct Flags {
unsigned int a : 1;
unsigned int b : 3;
unsigned int c : 4;
};
int main() {
struct Flags f;
f.a = 1;
f.b = 5;
f.c = 12;
printf("a = %u\n", f.a);
printf("b = %u\n", f.b);
printf("c = %u\n", f.c);
printf("Size of struct = %zu bytes\n", sizeof(f));
return 0;
}
Output (example):
a = 1
b = 5
c = 12
Size of struct = 4 bytes
Notice how 8 bits are enough to store a + b + c logically, but compiler may align the struct to 4 bytes.
Advantages of Bitfields
Save memory when storing small integers or flags
Useful in embedded systems, device drivers, hardware registers
Can manipulate bits directly
Limitations
Cannot take address of bitfield (&f.a is illegal)
Bitfield type must be integer or char
Compiler-dependent padding and alignment
Overflow occurs silently if value exceeds bit width
Interview-Friendly One-Liner
Bitfields in structures allow specifying the exact number of bits for a member, enabling memory-efficient storage of small integers or flags.
18.Can unions contain bitfields?
Yes, unions can contain bitfields in C.
A union allows multiple members to share the same memory, and some or all of these members can be bitfields. This is commonly used in embedded systems, hardware registers, and protocol parsing.
Key Points
Bitfields inside a union share the same memory space as other union members.
Only one member is active at a time (like all unions).
Useful for accessing individual bits of a larger variable or register.
Example
#include <stdio.h>
union Register {
unsigned int all; // access all 8 bits at once
struct {
unsigned int bit0 : 1;
unsigned int bit1 : 1;
unsigned int bit2 : 1;
unsigned int bit3 : 1;
unsigned int bit4 : 1;
unsigned int bit5 : 1;
unsigned int bit6 : 1;
unsigned int bit7 : 1;
} bits; // access individual bits
};
int main() {
union Register reg;
reg.all = 0; // clear all bits
reg.bits.bit0 = 1; // set only bit0
printf("Register value = %u\n", reg.all); // shows 1
reg.all = 255; // set all bits
printf("Bit3 = %u\n", reg.bits.bit3); // shows 1
return 0;
}
Output:
Register value = 1
Bit3 = 1
Why Use Unions with Bitfields?
Access entire register or individual bits efficiently.
Save memory by combining multiple flags in the same space.
Common in embedded programming and device drivers.
Interview-Friendly One-Liner
Yes, unions can contain bitfields, allowing access to individual bits or the entire memory region using the same storage location.