Pointers in C
Pointers are one of the most powerful and unique features of the C programming language. They allow programs to work directly with memory, making C efficient, flexible, and suitable for system programming, embedded systems, operating systems, and high-performance applications.
Many beginners find pointers difficult because they involve memory addresses instead of just values. However, once you understand the relationship between variables, memory, and addresses, pointers become much easier to understand.
In this lesson, you'll learn what pointers are, why they are needed, how they work, and how they are used in real-world applications.
🎯 Learning Objectives
After completing this lesson, you will be able to:
- Understand computer memory.
- Understand memory addresses.
- Declare and initialize pointers.
- Use the address (
&) operator. - Use the dereference (
*) operator. - Work with NULL pointers.
- Perform pointer arithmetic.
- Understand pointers and arrays.
- Pass pointers to functions.
- Understand Call by Reference.
- Avoid common pointer mistakes.
📖 What is Memory?
Whenever a program runs, the operating system allocates memory (RAM) to store variables.
Example
cint age = 20;
The computer stores:
- Variable Name →
age - Value →
20 - Memory Address → Example:
1000
Memory Address
textAddress Value 1000 ---> 20
The address may differ every time the program runs.
What is a Pointer?
A pointer is a variable that stores the memory address of another variable.
Example
cint age = 20;
Suppose
textage Address : 1000 Value : 20
A pointer stores
text1000
instead of
text20
Why Do We Need Pointers?
Pointers help us to:
- Access memory directly.
- Pass large data efficiently.
- Modify variables inside functions.
- Work with arrays.
- Allocate memory dynamically.
- Build linked lists, trees, stacks, and queues.
- Develop operating systems and compilers.
Declaring a Pointer
Syntax
cdatatype *pointerName;
Example
cint *ptr;
Here,
textptr
can store the address of an integer.
The Address Operator (&)
The address operator (&) returns the memory address of a variable.
Example
c#include <stdio.h> int main() { int age = 20; printf("%p", &age); return 0; }
Possible Output
text0x7ffd98e12c44
Every computer produces different addresses.
Initializing a Pointer
Example
cint age = 20; int *ptr = &age;
Memory
textVariable Address Value age 1000 20 ptr 2000 1000
The Dereference Operator (*)
The * operator is used to access the value stored at the memory address.
Example
c#include <stdio.h> int main() { int age = 20; int *ptr = &age; printf("%d", *ptr); return 0; }
Output
text20
Understanding * and & Together
cint number = 50; int *ptr = &number;
| Expression | Meaning |
|---|---|
number | Value |
&number | Address |
ptr | Stores address |
*ptr | Value stored at address |
Pointer Example
c#include <stdio.h> int main() { int marks = 95; int *ptr = &marks; printf("Value = %d\n", marks); printf("Address = %p\n", &marks); printf("Pointer = %p\n", ptr); printf("Dereference = %d\n", *ptr); return 0; }
Changing a Value Using a Pointer
c#include <stdio.h> int main() { int number = 10; int *ptr = &number; *ptr = 100; printf("%d", number); return 0; }
Output
text100
The pointer changes the original variable.
NULL Pointer
A pointer that points to nothing is called a NULL pointer.
cint *ptr = NULL;
Always initialize unused pointers to NULL.
Wild Pointer
A pointer that has not been initialized is called a wild pointer.
Wrong
cint *ptr; printf("%d", *ptr);
The pointer contains an unknown address.
Always initialize pointers before using them.
Dangling Pointer
A dangling pointer points to memory that is no longer valid.
Example
cint *ptr; { int value = 10; ptr = &value; }
After the block ends, ptr points to invalid memory.
Pointer Arithmetic
Pointers can move from one memory location to another.
Example
c#include <stdio.h> int main() { int numbers[] = {10,20,30}; int *ptr = numbers; printf("%d\n", *ptr); ptr++; printf("%d\n", *ptr); return 0; }
Output
text10 20
Pointers and Arrays
The name of an array is the address of its first element.
cint arr[3] = {5,10,15}; int *ptr = arr;
Equivalent to
cptr = &arr[0];
Accessing Arrays Using Pointers
c#include <stdio.h> int main() { int arr[5] = {10,20,30,40,50}; int *ptr = arr; for(int i=0;i<5;i++) { printf("%d ", *(ptr+i)); } return 0; }
Output
text10 20 30 40 50
Call by Reference
Pointers allow functions to modify original variables.
c#include <stdio.h> void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int main() { int x = 10; int y = 20; swap(&x,&y); printf("%d %d",x,y); return 0; }
Output
text20 10
Void Pointer
A void pointer can point to any data type.
cvoid *ptr;
Before dereferencing, it must be typecast.
Example
cint number = 50; void *ptr = &number; printf("%d", *(int*)ptr);
Pointer Comparison
Pointers can be compared if they point into the same array.
cif(ptr1 == ptr2)
Useful for checking whether two pointers reference the same location.
Common Beginner Mistakes
Dereferencing NULL
Wrong
cint *ptr = NULL; printf("%d", *ptr);
Forgetting &
Wrong
cint *ptr = number;
Correct
cint *ptr = &number;
Forgetting *
Wrong
cprintf("%d", ptr);
Correct
cprintf("%d", *ptr);
(Use %p to print addresses.)
Using Freed or Invalid Memory
Never access memory after it becomes invalid.
Real-World Example
c#include <stdio.h> void updateProgress(int *progress) { *progress += 10; } int main() { int studentProgress = 70; updateProgress(&studentProgress); printf("KauraX Progress: %d%%", studentProgress); return 0; }
Output
textKauraX Progress: 80%
Best Practices
- Initialize every pointer.
- Prefer
NULLfor unused pointers. - Check pointers before dereferencing.
- Use meaningful pointer names.
- Avoid pointer arithmetic unless necessary.
🧠 Interview Questions
- What is a pointer?
- Why are pointers used?
- What is the difference between
*and&? - What is a NULL pointer?
- What is a wild pointer?
- What is a dangling pointer?
- Explain pointer arithmetic.
- Explain pointers and arrays.
- What is Call by Reference?
- What is a void pointer?
✍ Practice Questions
- Print the address of a variable.
- Access a variable using a pointer.
- Modify a variable using a pointer.
- Swap two numbers using pointers.
- Print array elements using pointers.
- Find the largest element using pointers.
- Reverse an array using pointers.
- Count vowels using pointer traversal.
- Compare two pointers.
- Implement a simple Call by Reference function.
📚 Lesson Summary
In this lesson, you learned:
- Memory and addresses
- Pointer declaration and initialization
- Address (
&) operator - Dereference (
*) operator - NULL, wild, and dangling pointers
- Pointer arithmetic
- Pointers and arrays
- Call by Reference
- Void pointers
- Best practices and common mistakes
Pointers are one of the defining features of the C language. Mastering them is essential for understanding dynamic memory allocation, data structures, operating systems, and advanced C programming.
🚀 What's Next?
In the next lesson, Structures and Unions in C, you'll learn:
- Structures
- Nested Structures
- Arrays of Structures
- Structures and Functions
- Unions
- Difference Between Structures and Unions
- Real-World Examples
- Interview Questions
Structures allow you to group different data types together, making it easier to represent real-world entities such as students, employees, and products.
Happy Coding with KauraX 💙