Topic 12 — Pointers
A pointer is one of the most important concepts in C programming. Instead of storing an ordinary value such as 25, a pointer stores the address of an object.
Pointers connect many major C concepts: variables, arrays, strings, functions, structures, dynamic memory, files and low-level programming.
12.1 What Is a Pointer?
A pointer is an object whose value is the address of another object or, in some contexts, a function.
Consider:
int age = 20; The variable age stores the value 20. The computer also associates age with a memory location. A pointer can store that memory address.
int age = 20; int *ptr = &age; Here:
agestores20.&ageproduces the address ofage.ptrstores that address.*ptraccesses the object stored at that address.
Variable ┌─────────────┐ age │ 20 │ └─────────────┘ ▲ │ │ address of age │ ┌─────────────┐ ptr │ &age │ └─────────────┘ *ptr → 20 12.2 Why Do We Need Pointers?
1. Access Memory Indirectly
A pointer allows a program to reach an object through its address.
2. Modify Caller Data
A pointer can be passed to a function so the function can modify an object belonging to the caller.
3. Work with Arrays
Arrays and pointers are closely related in C expressions and function calls.
4. Work with Strings
Character pointers are commonly used to process C strings.
5. Dynamic Memory
Functions such as malloc() and free() use pointers.
6. Advanced C
Structures, linked lists, trees, function pointers and system programming all depend heavily on pointer concepts.
12.3 The Two Most Important Pointer Operators
| Operator | Name | Meaning | Example |
|---|---|---|---|
& | Address-of | Produces the address of an object | &number |
* | Indirection / Dereference | Accesses the object referred to by a pointer | *ptr |
* can mean multiplication in a * b, but dereference a pointer in *ptr. Similarly, & can mean address-of in &x, while it can mean bitwise AND in a & b. 12.4 Declaring a Pointer
The basic syntax is:
data_type *pointer_name; Examples:
int *p; float *pricePtr; char *letterPtr; double *valuePtr; The type tells the compiler what kind of object the pointer is intended to point to.
int *p; means that p has pointer type capable of pointing to an int object. It does not mean that p itself is an integer variable. 12.5 Understanding int *p
Beginners often read:
int *p; as:
"p is an integer."
That is incorrect.
The correct interpretation is:
p is a pointer to an int.
int number = 50; int *p = &number; number ┌──────────────┐ │ 50 │ └──────────────┘ ▲ │ │ │ points to │ p ┌──────────────┐ │ address │ └──────────────┘ 12.6 Address-of Operator &
The address-of operator obtains the address of an object.
int number = 25; printf("%p\n", (void *)&number); The actual address is implementation-dependent, so you should not expect the same address on every execution or every computer.
printf, use %p and convert the pointer to void *: printf("%p\n", (void *)ptr); 12.7 Dereference Operator *
The dereference operator accesses the object referred to by a valid pointer.
int number = 25; int *ptr = &number; printf("%d\n", *ptr); Output:
25 The expression *ptr means:
"Access the object that ptr points to."
12.8 Reading and Modifying Through a Pointer
Dereferencing is not limited to reading. If the pointer points to a modifiable object, dereferencing can also be used to modify that object.
#include <stdio.h> int main(void) { int number = 10; int *ptr = &number; printf("Before = %d\n", number); *ptr = 50; printf("After = %d\n", number); return 0; } Output:
Before = 10 After = 50 Why did number change? Because *ptr refers to the same object as number.
12.9 Pointer Program Tracing
number and ptrint number = 10; int *ptr = &number; *ptr = 50; | Step | Statement | number | ptr | *ptr |
|---|---|---|---|---|
| 1 | int number = 10; | 10 | Not created yet | — |
| 2 | int *ptr; | 10 | Uninitialized | Do not dereference |
| 3 | ptr = &number; | 10 | Address of number | 10 |
| 4 | *ptr = 50; | 50 | Same address | 50 |
points to ptr ─────────────────────► number ┌─────────┐ │ 50 │ └─────────┘ *ptr means: "Go to the object at ptr's address." 12.10 Pointer and Pointee
The object whose address is stored in a pointer is often called the pointee.
int x = 100; int *p = &x; Here:
pis the pointer.xis the pointee.&xis the address stored inp.*paccessesx.
12.11 Pointer Initialization
A pointer should be initialized before it is dereferenced.
int value = 40; int *p = &value; A pointer can also intentionally contain a null pointer value:
int *p = NULL; A null pointer does not point to an object. It can be used to represent "no valid object is currently referenced."
*p is invalid when p == NULL. 12.12 NULL Pointer
A null pointer is a pointer value that compares unequal to a pointer to any object or function.
int *ptr = NULL; if (ptr == NULL) { printf("Pointer is NULL\n"); } Modern C code may use nullptr in C23, but many educational and existing C programs use NULL. The important concept is that the pointer must not be dereferenced while it is null.
12.13 Uninitialized Pointers
This is dangerous:
int *p; *p = 10; The pointer has not been given a valid target address. Dereferencing it can cause undefined behavior.
Use:
int value = 10; int *p = &value; or, when there is no target yet:
int *p = NULL; 12.14 Pointer Types
| Pointer | Can point to |
|---|---|
int * | int object |
char * | char object |
float * | float object |
double * | double object |
struct Student * | struct Student object |
The pointer type is important because pointer arithmetic and dereferencing depend on the pointed-to type.
12.15 Why Pointer Type Matters
Suppose:
int *p; When *p is evaluated, the compiler interprets the object using the pointed-to type int.
Pointer arithmetic also uses the size of the pointed-to type. This becomes especially important when pointers are used with arrays.
12.16 Pointer Size vs Pointed-to Object Size
Do not assume that the size of a pointer is the size of the object it points to.
int x = 10; int *p = &x; printf("%zu\n", sizeof(x)); printf("%zu\n", sizeof(p)); The exact sizes are implementation-dependent. A pointer's size does not have to equal the size of the pointed-to type.
12.17 Pointers and Functions
C passes function arguments by value. However, if a function receives a pointer value, the function can use that pointer to access the caller's object.
Example:
#include <stdio.h> void changeValue(int *p) { *p = 100; } int main(void) { int number = 20; changeValue(&number); printf("%d\n", number); return 0; } Output:
100 The pointer itself is passed by value, but the copied pointer points to the same number object.
12.18 Program Tracing — Function + Pointer
main() │ │ number = 20 │ │ changeValue(&number) ▼ changeValue(int *p) │ │ p receives a copy of number's address │ │ *p = 100 ▼ number becomes 100 │ ▼ return to main() | Stage | number | p |
|---|---|---|
| Before function call | 20 | — |
| Inside function | 20 | Address of number |
After *p = 100 | 100 | Address of number |
| After return | 100 | Function's local pointer no longer exists |
12.19 Swapping Two Numbers Using Pointers
A classic pointer application is swapping two objects inside a function.
#include <stdio.h> void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main(void) { int x = 10; int y = 20; printf("Before: %d %d\n", x, y); swap(&x, &y); printf("After: %d %d\n", x, y); return 0; } Output:
Before: 10 20 After: 20 10 x and y directly. It receives their addresses, allowing it to access and modify the original objects. 12.20 Pointer Arithmetic
Pointers to elements of the same array support arithmetic operations within the array object and one-past-the-end position.
For example:
int numbers[] = {10, 20, 30, 40}; int *p = numbers; printf("%d\n", *p); printf("%d\n", *(p + 1)); printf("%d\n", *(p + 2)); Output:
10 20 30 The expression p + 1 does not mean "add one byte." It advances to the next int element.
12.21 Pointer Arithmetic and Array Elements
int numbers[] = {10, 20, 30, 40}; Index: 0 1 2 3 │ │ │ │ ▼ ▼ ▼ ▼ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ 10 │ │ 20 │ │ 30 │ │ 40 │ └─────┘ └─────┘ └─────┘ └─────┘ ▲ │ p p + 1 → points to element 1 p + 2 → points to element 2 The exact byte distance depends on sizeof(int), but C pointer arithmetic automatically scales by the size of the pointed-to type.
12.22 Incrementing a Pointer
int numbers[] = {10, 20, 30}; int *p = numbers; printf("%d\n", *p); p++; printf("%d\n", *p); Output:
10 20 After p++, the pointer refers to the next array element.
12.23 Pointer Subtraction
Two pointers to elements of the same array can be subtracted. The result represents the number of elements between them.
int numbers[] = {10, 20, 30, 40, 50}; int *p1 = &numbers[1]; int *p2 = &numbers[4]; printf("%td\n", p2 - p1); Output:
3 The result type is ptrdiff_t, for which %td is the appropriate printf conversion.
12.24 One-Past-the-End Pointer
C permits forming a pointer to one position past the last element of an array. It may be used for comparison and iteration, but it must not be dereferenced.
int numbers[] = {10, 20, 30}; int *p = numbers; int *end = numbers + 3; while (p != end) { printf("%d\n", *p); p++; } Here end is valid as a pointer value for the iteration boundary, but *end must not be evaluated.
12.25 Pointers and Arrays
An array expression often converts to a pointer to its first element when used in most expressions.
int numbers[] = {10, 20, 30}; int *p = numbers; Here p points to numbers[0].
Therefore:
numbers[0] *(numbers + 0) numbers[1] *(numbers + 1) numbers[2] *(numbers + 2) refer to corresponding elements.
12.26 Array Indexing Is Related to Pointer Arithmetic
For an array or pointer expression, the notation:
a[i] is defined in terms of pointer arithmetic as:
*(a + i) For example:
int a[] = {5, 10, 15}; printf("%d\n", a[1]); printf("%d\n", *(a + 1)); Both print:
10 12.27 Pointers as Function Parameters for Arrays
When an array is passed to a function, the parameter declaration is adjusted so that the function receives a pointer to the first element.
#include <stdio.h> void printArray(int a[], int n) { for (int i = 0; i < n; i++) { printf("%d ", a[i]); } } int main(void) { int numbers[] = {10, 20, 30, 40}; printArray(numbers, 4); return 0; } Output:
10 20 30 40 12.28 Important Interview Point: sizeof and Array Parameters
Consider:
void showSize(int a[]) { printf("%zu\n", sizeof(a)); } Inside this parameter declaration, a is adjusted to a pointer parameter. Therefore sizeof(a) gives the size of the pointer, not the size of the original array.
This is why a function commonly receives the array length separately:
void process(int a[], int n) 12.29 Pointers and Strings
A C string is an array of characters terminated by a null character '\0'. A pointer can point to its first character.
char name[] = "Bhavya"; char *p = name; printf("%s\n", p); Output:
Bhavya The pointer can also be used to traverse the characters:
while (*p != '\0') { putchar(*p); p++; } 12.30 Character Pointer vs Character Array
| Declaration | Meaning |
|---|---|
char text[] = "Hello"; | Creates a modifiable character array initialized from the string literal. |
char *p = text; | Pointer points to the first character of the array. |
Be careful with:
char *p = "Hello"; The string literal should not be modified through p. Attempting to modify it results in undefined behavior.
12.31 Pointer to Pointer
A pointer can itself have an address. Therefore, another pointer can point to it.
int value = 25; int *p = &value; int **pp = &p; pp │ │ points to ▼ ┌───────────────┐ │ p │ │ address of │ │ value │ └───────────────┘ │ │ points to ▼ ┌───────────────┐ │ value │ │ 25 │ └───────────────┘ *pp → p **pp → value → 25 12.32 Dereferencing Multiple Levels
int value = 25; int *p = &value; int **pp = &p; printf("%d\n", **pp); Output:
25 Explanation:
pppoints top.*ppgivesp.**ppaccesses the object pointed to byp.
12.33 Const and Pointers
The const qualifier can be combined with pointer declarations in several different ways.
Pointer to const data
const int *p; The object should not be modified through p. The pointer itself may be changed to point elsewhere.
Const pointer
int *const p = &value; The pointer itself cannot be changed to point elsewhere after initialization, but the pointed-to int can be modified through p.
Const pointer to const data
const int *const p = &value; Neither the pointer itself nor the object can be modified through that pointer.
12.34 Pointer Compatibility
Pointer types should be used carefully. For example:
int *p; double *q; These pointers are intended to point to different types of objects. Do not simply treat one as the other without an appropriate conversion.
The special pointer type void * can hold the address of an object of any object type and is widely used in generic C interfaces.
12.35 Void Pointers
int number = 50; void *ptr = &number; A void * is a generic object pointer. Before dereferencing it, convert it to an appropriate pointer type or assign it to one.
printf("%d\n", *(int *)ptr); The compiler cannot directly determine the pointed-to object type from void * alone.
void * as a replacement for understanding pointer types. It is useful for generic programming, but the programmer must still know what object the address actually refers to. 12.36 Pointer Comparisons
Pointers can be compared in specific meaningful situations. For example, pointers into the same array can be compared using relational operators.
int a[] = {10, 20, 30}; int *p = &a[0]; int *q = &a[2]; if (p < q) { printf("p comes before q\n"); } Equality and inequality comparisons are also commonly used when checking for null pointers:
if (p == NULL) { printf("No object\n"); } 12.37 Pointer Safety
Many serious C bugs involve invalid pointers.
Null Pointer
Do not dereference a null pointer.
Dangling Pointer
Do not use a pointer after the object it referred to has ceased to exist.
Uninitialized Pointer
Initialize pointers before using them.
Out-of-Bounds Pointer
Do not access outside the valid array/object boundaries.
Wrong Pointer Type
Use compatible pointer types and conversions.
String Literal Modification
Never modify a string literal through a pointer.
12.38 Dangling Pointers
A dangling pointer is a pointer whose stored address is no longer a valid way to access the object it previously referred to.
For example, returning the address of an ordinary local variable from a function is invalid:
int *wrong(void) { int x = 10; return &x; } When the function returns, the lifetime of the local object x has ended. The returned pointer cannot safely be dereferenced.
12.39 Common Pointer Mistakes
| Mistake | Problem |
|---|---|
| Dereferencing an uninitialized pointer | Undefined behavior |
Dereferencing NULL | Invalid access |
| Accessing outside an array | Undefined behavior |
| Using a pointer after object lifetime ends | Dangling pointer / invalid access |
| Returning address of local automatic variable | Pointer becomes invalid after function returns |
| Writing through a pointer to read-only data | Invalid modification |
12.40 Pointer vs Value
| Expression | Meaning |
|---|---|
x | The value stored in object x |
&x | Address of object x |
p | Address stored in pointer p |
*p | Object accessed through pointer p |
12.41 Pointer Visualization
int marks = 85; int *p = &marks; stores 85 ┌─────────────┐ marks ───────►│ 85 │ └─────────────┘ ▲ │ │ address │ ┌─────────────┐ p ───────────►│ &marks │ └─────────────┘ p = address of marks *p = 85 &marks = same address stored in p 85. It contains the address used to reach the object containing 85. 12.42 Complete Program Analysis
#include <stdio.h> void update(int *p) { *p = *p + 10; } int main(void) { int marks = 70; int *ptr = &marks; printf("Before = %d\n", marks); update(ptr); printf("After = %d\n", marks); return 0; } Step 1 — Create the variable
int marks = 70; An integer object named marks is initialized with 70.
Step 2 — Store its address
int *ptr = &marks; ptr stores the address of marks.
Step 3 — Call the function
update(ptr); A copy of the pointer value is passed to update.
Step 4 — Dereference
*p = *p + 10; The function reads the caller's marks object through the pointer and changes it from 70 to 80.
Step 5 — Return to main
The updated value remains in marks.
Output:
Before = 70 After = 80 12.43 Pointers and Memory Layout — Conceptual View
The following is a conceptual model rather than a promise about exact addresses or physical memory organization.
Object Pointer ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ value │◄─────────│ address │ │ │ │ │ └──────────────┘ └──────────────┘ ▲ │ │ │ └────────── *p ───────────┘ This mental model is enough to understand the basic relationship: a pointer provides an indirect route to an object.
12.44 Pointers and sizeof
Remember that sizeof measures the size of its operand's type or object representation, not the size of the memory region conceptually "owned" by a pointer.
int x = 10; int *p = &x; printf("%zu\n", sizeof(x)); printf("%zu\n", sizeof(p)); printf("%zu\n", sizeof(*p)); The third expression, sizeof(*p), corresponds to the size of the pointed-to type, int, without requiring the pointed-to object's value to be read.
12.45 Pointer Expressions to Remember
| Expression | Meaning |
|---|---|
p | Pointer value |
*p | Object pointed to by p |
&x | Address of x |
p + 1 | Next element for an appropriate array pointer |
p - 1 | Previous element for an appropriate array pointer |
p == NULL | Check whether pointer is null |
**pp | Dereference a pointer-to-pointer twice |
12.46 Common Confusions
Confusion 1 — Pointer vs Address
&x is an expression that produces an address. A pointer object such as p stores a pointer value.
Confusion 2 — *p vs p
p is the pointer value. *p accesses the object referred to by that pointer.
Confusion 3 — Array vs Pointer
An array is not a pointer. An array expression commonly converts to a pointer to its first element in expressions.
Confusion 4 — C Pass-by-Reference
C has pass-by-value. Passing a pointer allows the function to access the same caller object, which provides reference-like behavior without changing C's parameter passing rule.
13.18 Quick Revision
📌 &x → address of x.
📌 *p → value at address stored in p.
📌 Pointer arithmetic is commonly used with arrays.
📌 Arrays and pointers are closely related, but they are not identical concepts.
📌 Pointers allow functions to modify caller data when addresses are passed.
📌 malloc() → dynamic allocation.
📌 calloc() → zero-initialized allocation.
📌 realloc() → resize allocation.
📌 free() → release allocation.
📌 NULL pointer → intentionally points to no valid object.
🎬 Pointers — Address and Dereference Flow
Follow the relationship between a variable, its address, a pointer, dereferencing, and modifying the original value.
🎬 Pointer Memory Relationship Visualizer
The active relationship changes as the pointer is created, dereferenced, and used to modify x.
🔎 Program Tracing — Pointers
Trace how a pointer stores an address, modifies the original variable, and reads the updated value through dereferencing.
—
13.19 Quick MCQs
Select an answer first, then click Check Answer. A correct choice becomes green. If the answer is wrong, your choice becomes red and the correct option becomes green. The explanation appears below.
A pointer stores an address value that can refer to an object or function of a compatible type.
The address-of operator & produces the address of an object such as &x.
The unary * operator accesses the object referenced by the pointer.
A null pointer is a special pointer value that does not point to a valid object or function.
malloc() allocates a requested number of bytes dynamically and returns a pointer to the allocated storage or NULL on failure.
free() releases dynamically allocated storage obtained from allocation functions such as malloc(), calloc(), or realloc().
13.20 🎯 Practice Problems
Pointers become clear through repeated address, dereference, array, string, and dynamic-memory practice. Use 💻 Solve It Yourself first, open Hint only when needed, and use Show Program after attempting the problem.
Problem 1: Read an integer, print its value, and verify that a pointer stores the address of that variable.
Input: One integer.
Output: Print the value and "Address Match = Yes".
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x;
scanf("%d", &x);
int *p = &x;
printf("Value = %d\n", x);
printf("Address Match = %s", p == &x ? "Yes" : "No");
return 0;
}
Problem 2: Read an integer and print its value by dereferencing a pointer.
Input: One integer.
Output: Print the value obtained through *p.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x;
scanf("%d", &x);
int *p = &x;
printf("%d", *p);
return 0;
}
Problem 3: Read an integer and a new value. Modify the original variable through a pointer.
Input: Two integers: original value and new value.
Output: Print the modified variable.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x, newValue;
scanf("%d %d", &x, &newValue);
int *p = &x;
*p = newValue;
printf("%d", x);
return 0;
}
Problem 4: Read two integers and calculate their sum by dereferencing pointers.
Input: Two integers.
Output: Print the sum.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d", &a, &b);
int *p = &a;
int *q = &b;
printf("%d", *p + *q);
return 0;
}
Problem 5: Swap two integers using a function that receives pointers.
Input: Two integers.
Output: Print the swapped values.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int x, y;
scanf("%d %d", &x, &y);
swap(&x, &y);
printf("%d %d", x, y);
return 0;
}
Problem 6: Find the larger of two integers using pointers.
Input: Two integers.
Output: Print the maximum value.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d", &a, &b);
int *p = &a;
int *q = &b;
printf("%d", *p > *q ? *p : *q);
return 0;
}
Problem 7: Read N integers and print every array element using pointer notation.
Input: N followed by N integers.
Output: Print the elements separated by spaces.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", arr + i);
for (int i = 0; i < n; i++)
{
if (i > 0)
printf(" ");
printf("%d", *(arr + i));
}
return 0;
}
Problem 8: Find the sum of an integer array using pointer arithmetic.
Input: N followed by N integers.
Output: Print the sum.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int n;
long long sum = 0;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", arr + i);
for (int i = 0; i < n; i++)
sum += *(arr + i);
printf("%lld", sum);
return 0;
}
Problem 9: Find the maximum element of an integer array using pointer access.
Input: N greater than 0 followed by N integers.
Output: Print the maximum element.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", arr + i);
int maximum = *arr;
for (int i = 1; i < n; i++)
{
if (*(arr + i) > maximum)
maximum = *(arr + i);
}
printf("%d", maximum);
return 0;
}
Problem 10: Reverse an array in place using pointer-based swapping.
Input: N followed by N integers.
Output: Print the reversed array.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
int *left = arr;
int *right = arr + n - 1;
while (left < right)
{
int temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
for (int i = 0; i < n; i++)
{
if (i > 0)
printf(" ");
printf("%d", arr[i]);
}
return 0;
}
Problem 11: Find the length of a string using pointer traversal.
Input: One line of text.
Output: Print the string length excluding the newline.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <string.h>
int main()
{
char text[200];
fgets(text, sizeof(text), stdin);
text[strcspn(text, "\n")] = '\0';
char *p = text;
while (*p != '\0')
p++;
printf("%ld", (long)(p - text));
return 0;
}
Problem 12: Reverse a string in place using pointers.
Input: One line of text.
Output: Print the reversed string.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <string.h>
int main()
{
char text[200];
fgets(text, sizeof(text), stdin);
text[strcspn(text, "\n")] = '\0';
int length = (int)strlen(text);
if (length > 0)
{
char *left = text;
char *right = text + length - 1;
while (left < right)
{
char temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
printf("%s", text);
return 0;
}
Problem 13: Count vowels in a string by traversing it with a pointer.
Input: One line of text.
Output: Print the vowel count.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
char text[200];
int count = 0;
fgets(text, sizeof(text), stdin);
for (char *p = text; *p != '\0'; p++)
{
char ch = *p;
if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u' ||
ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U')
{
count++;
}
}
printf("%d", count);
return 0;
}
Problem 14: Check whether a string is a palindrome using left and right pointers.
Input: One line of text.
Output: Print "Palindrome" or "Not Palindrome".
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <string.h>
int main()
{
char text[200];
int palindrome = 1;
fgets(text, sizeof(text), stdin);
text[strcspn(text, "\n")] = '\0';
int length = (int)strlen(text);
if (length > 0)
{
char *left = text;
char *right = text + length - 1;
while (left < right)
{
if (*left != *right)
{
palindrome = 0;
break;
}
left++;
right--;
}
}
printf("%s", palindrome ? "Palindrome" : "Not Palindrome");
return 0;
}
Problem 15: Create a pointer to a pointer and print a variable's value through double dereferencing.
Input: One integer.
Output: Print the value using **pp.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x;
scanf("%d", &x);
int *p = &x;
int **pp = &p;
printf("%d", **pp);
return 0;
}
Problem 16: Dynamically allocate an integer array using malloc(), read values, and print their sum.
Input: N followed by N integers.
Output: Print the sum, or Allocation Failed if memory allocation fails.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
long long sum = 0;
scanf("%d", &n);
int *arr = malloc((size_t)n * sizeof(int));
if (arr == NULL)
{
printf("Allocation Failed");
return 0;
}
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
sum += arr[i];
}
printf("%lld", sum);
free(arr);
return 0;
}
Problem 17: Allocate an integer array using calloc() and print its initial values before assigning anything.
Input: One positive integer N.
Output: Print N zero values separated by spaces, or Allocation Failed.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int *arr = calloc((size_t)n, sizeof(int));
if (arr == NULL)
{
printf("Allocation Failed");
return 0;
}
for (int i = 0; i < n; i++)
{
if (i > 0)
printf(" ");
printf("%d", arr[i]);
}
free(arr);
return 0;
}
Problem 18: Allocate N integers, resize the array to M integers using realloc(), read the new elements, and print the complete resized array.
Input: N, N integers, M where M >= N, followed by M-N new integers.
Output: Print all M elements, or Allocation Failed.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, m;
scanf("%d", &n);
int *arr = malloc((size_t)n * sizeof(int));
if (arr == NULL)
{
printf("Allocation Failed");
return 0;
}
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
scanf("%d", &m);
int *temp = realloc(arr, (size_t)m * sizeof(int));
if (temp == NULL)
{
free(arr);
printf("Allocation Failed");
return 0;
}
arr = temp;
for (int i = n; i < m; i++)
scanf("%d", &arr[i]);
for (int i = 0; i < m; i++)
{
if (i > 0)
printf(" ");
printf("%d", arr[i]);
}
free(arr);
return 0;
}
Problem 19: Create a structure variable and access its members through a structure pointer.
Input: Student roll number and marks.
Output: Print both values using the -> operator.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
struct Student
{
int roll;
float marks;
};
int main()
{
struct Student student;
scanf("%d %f", &student.roll, &student.marks);
struct Student *p = &student;
printf("Roll = %d\n", p->roll);
printf("Marks = %.1f", p->marks);
return 0;
}
Problem 20: Create a function pointer for an addition function and use it to calculate the sum of two integers.
Input: Two integers.
Output: Print their sum.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main()
{
int a, b;
scanf("%d %d", &a, &b);
int (*operation)(int, int) = add;
printf("%d", operation(a, b));
return 0;
}
13.21 Key Takeaway
&x → Address of x
p → Address stored in p
*p → Value at that address
Once this becomes clear, pointers become much easier to understand.
🎤 Pointers — Interview Questions
💡 Pointers — Placement Tips
- Always separate the three ideas: address, pointer value, and dereferenced object.
- Initialize pointers before dereferencing them, and check dynamically allocated pointers against
NULL. - For array-pointer questions, remember
arr[i]and*(arr + i)refer to the same element. - Pointer arithmetic is scaled by the pointed-to type;
p + 1moves to the next element of that type. - After
free(p), do not dereference p. Setting it toNULLcan help avoid accidental reuse. - For
realloc(), use a temporary pointer so the original allocation is not lost if resizing fails.
✍️ Pointers — Extra Practice Questions
- Use pointers to find the second largest element of an array.
- Use pointer arithmetic to count positive and negative array elements.
- Copy one string to another using only pointers.
- Concatenate two strings using pointer traversal without
strcat(). - Dynamically allocate a matrix using pointers and calculate each row sum.
- Create an array of function pointers for addition, subtraction, multiplication, and division.