Pointers in C – Complete Notes with MCQs for CDAC C-CAT
Pointers in C – Complete Notes with MCQs for CDAC C-CAT
Pointers are the single most tested concept in the CDAC C-CAT C Programming section. Nearly every tricky output-based question — arrays, strings, function calls, dynamic memory — eventually comes back to how a pointer is declared, incremented, or dereferenced.
This guide covers everything you need for the exam and technical interviews.
What is a Pointer?
A pointer is a variable that stores the address of another variable, instead of storing a value directly.
int x = 10;
int *p = &x;
printf("%d", *p);
Output
10
Here, p holds the address of x, and *p dereferences the pointer to get the value stored at that address.
Declaring a Pointer
int *p; // pointer to int
char *c; // pointer to char
float *f; // pointer to float
The * in a declaration means “this variable is a pointer,” not “dereference” — that distinction only matters after declaration.
Address-of and Dereference Operators
int x = 5;
int *p = &x;
printf("%d", x); // 5
printf("%p", &x); // address of x
printf("%d", *p); // 5 (value at that address)
printf("%p", p); // same address as &x
& gives an address. * gives the value stored at an address.
Pointer Size
int x = 10;
int *p = &x;
printf("%zu", sizeof(p));
Typical Output (64-bit system)
8
A pointer’s size does not depend on the data type it points to — it depends on the architecture. sizeof(int*), sizeof(char*), and sizeof(double*) are all the same on a given machine.
Pointer Arithmetic
Pointer arithmetic is scaled by the size of the pointed-to type, not by 1 byte.
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;
printf("%d", *(p + 2));
Output
30
p + 1 does not mean “address + 1 byte.” It means “address + sizeof(int) bytes.”
char *cp;
int *ip;
cp + 1; // moves 1 byte
ip + 1; // moves 4 bytes (typically)
Arrays and Pointers
An array name decays into a pointer to its first element in most expressions.
int arr[3] = {1, 2, 3};
printf("%d", *arr); // 1
printf("%d", *(arr + 1)); // 2
printf("%d", arr[2]); // 3
arr[i] is exactly equivalent to *(arr + i).
Important: arr is not a pointer variable. sizeof(arr) gives the full array size, while sizeof(a pointer to arr[0]) would give the pointer size.
printf("%zu", sizeof(arr)); // 12 (3 ints × 4 bytes)
Pointer to Pointer
A pointer can store the address of another pointer.
int x = 10;
int *p = &x;
int **pp = &p;
printf("%d", **pp);
Output
10
*pp gives p (an address), and **pp gives x (the value).
NULL Pointer
A pointer initialized to point to nothing.
int *p = NULL;
if (p == NULL)
printf("Empty pointer");
Output
Empty pointer
Dereferencing a NULL pointer (*p) causes undefined behavior — typically a segmentation fault.
Void Pointer
A generic pointer that can point to any data type, but cannot be dereferenced directly without casting.
int x = 10;
void *vp = &x;
printf("%d", *(int *)vp);
Output
10
void * is commonly used in functions like malloc() and memcpy(), which must work with any data type.
Dangling Pointer
A pointer that still points to a memory location after that memory has been freed or has gone out of scope.
int *p = (int *)malloc(sizeof(int));
free(p);
// p is now a dangling pointer
*p = 10; // undefined behavior
To avoid this, set the pointer to NULL immediately after freeing it.
Wild Pointer
A pointer that is declared but never initialized.
int *p; // wild pointer
*p = 10; // undefined behavior — points to a random address
The difference: a dangling pointer once pointed somewhere valid; a wild pointer never did.
Constant Pointers vs Pointers to Constants
int x = 10, y = 20;
const int *p1 = &x; // value cannot change via p1, pointer can move
int *const p2 = &x; // pointer cannot move, value can change
*p1 = 5; // Error
p1 = &y; // OK
*p2 = 5; // OK
p2 = &y; // Error
Read the declaration right to left starting from the variable name to keep this straight.
Pointers and Function Calls (Call by Reference)
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int x = 5, y = 10;
swap(&x, &y);
printf("%d %d", x, y);
}
Output
10 5
Passing addresses lets a function modify the caller’s original variables — normal call-by-value cannot do this.
Array of Pointers vs Pointer to Array
int *arr1[3]; // array of 3 pointers to int
int (*arr2)[3]; // pointer to an array of 3 ints
int a[3] = {1, 2, 3};
int (*p)[3] = &a;
printf("%d", (*p)[1]);
Output
2
arr1 is three separate pointers. arr2/p is one pointer to an entire array — the parentheses around *arr2 are what force this meaning; without them, int *arr2[3] reverts to an array of pointers.
Common Mistakes
Mistake 1
int *p;
*p = 10;
Wrong. p is uninitialized (wild pointer) — this writes to a random address.
Mistake 2
int arr[5];
printf("%zu", sizeof(arr));
Assuming this prints the pointer size. Wrong — sizeof on an array name gives the full array size, not sizeof(int*).
Mistake 3
int *p = (int *)malloc(sizeof(int));
free(p);
free(p); // double free — undefined behavior
Freeing the same pointer twice is a classic CDAC MCQ trap.
Frequently Asked Interview Questions
Can a pointer be negative?
Pointer arithmetic that moves before the start of an array is undefined behavior, even though the resulting address value may print as a valid-looking number.
What is the difference between p++ and *p++?
p++ moves the pointer to the next element. *p++ dereferences first, then increments the pointer (postfix binds to p, not the dereferenced value), due to operator precedence.
Does sizeof(p) depend on the type p points to?
No. All pointer types have the same size on a given system, since a pointer always stores just an address.
Can you perform arithmetic on a void *?
No, standard C does not allow arithmetic on void * since the compiler doesn’t know the size to scale by. Some compilers allow it as an extension, treating it like char *.
CDAC C-CAT MCQs
MCQ 1
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;
printf("%d", *(p + 3));
A. 30
B. 40
C. 3
D. Error
Answer: B
MCQ 2
int x = 5;
int *p = &x;
int **pp = &p;
**pp = 20;
printf("%d", x);
A. 5
B. 20
C. Error
D. Garbage value
Answer: B
MCQ 3
int a[3] = {1, 2, 3};
printf("%zu", sizeof(a));
A. 4
B. 8
C. 12
D. 3
Answer: C
MCQ 4
char *p = "hello";
printf("%c", *(p + 1));
A. h
B. e
C. l
D. Error
Answer: B
MCQ 5
int x = 10;
const int *p = &x;
*p = 20;
A. Prints 20
B. Compilation error
C. Prints 10
D. Undefined behavior
Answer: B
MCQ 6
int a = 10, b = 20;
int *p = &a;
p = &b;
printf("%d", *p);
A. 10
B. 20
C. Error
D. Garbage value
Answer: B
MCQ 7
int arr[4] = {1, 2, 3, 4};
int *p = arr;
p++;
printf("%d", *p);
A. 1
B. 2
C. Address of arr
D. Error
Answer: B
MCQ 8
int *p = NULL;
printf("%d", *p);
A. 0
B. NULL
C. Segmentation fault (undefined behavior)
D. Compilation error
Answer: C
Key Takeaways
- A pointer stores an address, not a value.
&gets an address;*dereferences an address.- Pointer arithmetic scales by the size of the pointed-to type, not by 1 byte.
- An array name decays into a pointer to its first element, but is not itself a pointer variable.
sizeof(pointer)is the same for every pointer type on a given machine;sizeof(array)gives the full array size.- A dangling pointer once pointed to valid memory that was later freed; a wild pointer was never initialized at all.
void *is a generic pointer that must be cast before dereferencing.- Pointers enable call-by-reference, letting a function modify the caller’s variables.
Next Topics
To strengthen your C programming for CDAC C-CAT, continue with:
- Dynamic Memory Allocation in C (malloc, calloc, realloc, free)
- Arrays vs Pointers in C
- Structures and Unions
- Function Pointers in C
- Array of Pointers vs Pointer to Array