In this tutorial, you will learn about pointers in C. A pointer is a special variable that stores the address of another variable. Instead of holding a direct value, it tells where the value is kept in memory. Pointers help in handling memory, working with arrays, and using dynamic memory well.
Contents:
- What is a Pointer in C?
- Declaring and Initializing Pointers in C
- Referencing Pointer in C
- Dereferencing Pointer in C
- Types of Pointers in C
- Examples of Pointer Types in C
- Pointers and Arrays in C
- Pointers and Functions in C
- String Manipulation Using Pointers in C
- Double Pointers in C
- FAQs on Pointers in C
What is a Pointer in C?
A pointer in C is a variable that stores the memory address of another variable instead of storing a direct value. It is used to access and manipulate memory efficiently.
Declaring and Initializing Pointers in C
Syntax of a Pointer
data_type *pointer_name;
- data_type → Type of data the pointer will point to.
- *pointer_name → Declares a pointer variable.
Declaring a Pointer
int *ptr; // Pointer to an integer char *cptr; // Pointer to a character float *fptr; // Pointer to a float
Initializing a Pointer
To store the address of a variable in a pointer, use the address-of operator (&).
int num = 10; int *ptr = # // ptr stores the address of num
Example:
#include <stdio.h> int main() { // Declare a variable to store quiz score int quiz_score = 90; // Declare a pointer and store the address of quiz_score int *ptr = &quiz_score; // Display the quiz score using pointer printf("Sanfoundry Quiz Score: %d\n", *ptr); printf("Memory Address of Score: %p\n", ptr); return 0; }
Output:
Sanfoundry Quiz Score: 90 Memory Address of Score: 0x7ffee2a4bc34 (Example memory address)
This program shows how pointers work in C. It stores a quiz score in quiz_score and assigns its memory address to the pointer ptr. Using *ptr, the program prints the score, and with ptr, it displays the memory address. This helps in understanding how pointers access and manage memory.
Referencing Pointer in C
Referencing a pointer means assigning the address of a variable to a pointer using the address-of (&) operator allows the pointer to store the variable’s memory location. This enables indirect access or modification of the variable’s value.
Syntax:
data_type variable; data_type *pointer = &variable; // Pointer referencing the variable's address
Example:
#include <stdio.h> int main() { int quiz_score = 90; // Sanfoundry Quiz Score // Referencing: Assigning address of quiz_score to pointer int *ptr = &quiz_score; printf("Sanfoundry Quiz Score: %d\n", quiz_score); printf("Address of Quiz Score: %p\n", ptr); // Prints memory address return 0; }
Output:
Sanfoundry Quiz Score: 90 Address of Quiz Score: 0x7ffee9a4babc // (Example address)
This program shows how pointers work in C. It saves a quiz score in quiz_score and stores its memory address in ptr. Then, it prints the quiz score and its memory address. This helps to understand how pointers store and use memory locations.
Dereferencing Pointer in C
Dereferencing a pointer means accessing the value stored at the memory location the pointer holds. This is done using the dereference operator (*).
Syntax:
data_type variable = value; data_type *pointer = &variable; // Referencing data_type data = *pointer; // Dereferencing (access value)
Example:
#include <stdio.h> int main() { int marks = 95; // Sanfoundry Certification Exam Marks int *ptr = &marks; // Referencing: Storing address of marks in pointer // Dereferencing: Accessing value using pointer printf("Sanfoundry Certification Marks: %d\n", *ptr); return 0; }
Output:
Sanfoundry Certification Marks: 95
In this example, ptr stores the address of marks, and *ptr retrieves its value through pointer dereferencing.
Types of Pointers in C
Pointers in C are classified into different types based on their behavior and usage.
Pointer Type | Description | Example |
---|---|---|
Null Pointer | A pointer that stores NULL | int *p = NULL; |
Void Pointer | A generic pointer that can hold any type | void *ptr; |
Dangling Pointer | A pointer pointing to deallocated memory | free(p); *p = 10; (Error) |
Wild Pointer | An uninitialized pointer with a garbage value | int *p; *p = 10; (Error) |
Constant Pointer | A pointer whose address cannot change | int *const p = &x; |
Pointer to Constant | A pointer that cannot modify the value it points to | const int *p = &x; |
Constant Pointer to Constant | A pointer that cannot change the address or value | const int *const p = &x; |
Function Pointer | A pointer storing the address of a function | void (*ptr)(); |
Pointer to Pointer | A pointer storing the address of another pointer | int **p; |
Examples of Pointer Types in C
1. Null Pointer
A pointer that does not point to any memory location.
#include <stdio.h> int main() { int *ptr = NULL; // Null pointer if (ptr == NULL) { printf("Sanfoundry Certification: Pointer is NULL\n"); } return 0; }
Output:
Sanfoundry Certification: Pointer is NULL
2. Void Pointer (Generic Pointer)
A pointer that can store the address of any data type.
#include <stdio.h> int main() { int marks = 85; void *ptr = &marks; // Void pointer printf("Sanfoundry Exam Marks: %d\n", *(int *)ptr); // Type casting needed return 0; }
Output:
Sanfoundry Exam Marks: 85
3. Wild Pointer
An uninitialized pointer that may point to a random memory location.
#include <stdio.h> int main() { int *ptr; // Wild pointer (uninitialized) // printf("%d", *ptr); // Dereferencing a wild pointer causes undefined behavior return 0; }
Note: Always initialize pointers before using them.
4. Dangling Pointer
A pointer that still refers to memory after it has been freed.
#include <stdio.h> #include <stdlib.h> int main() { int *ptr = (int *)malloc(sizeof(int)); *ptr = 100; free(ptr); // Memory is freed // printf("%d", *ptr); // Accessing freed memory leads to undefined behavior return 0; }
Fix: Set ptr = NULL after free(ptr);
5. Constant Pointer
A pointer whose value (address) cannot be changed after initialization.
#include <stdio.h> int main() { int num1 = 10, num2 = 20; int *const ptr = &num1; // Constant pointer *ptr = 50; // Allowed: Changing value // ptr = &num2; // Error: Cannot change address printf("Value: %d\n", *ptr); return 0; }
Output:
Value: 50
6. Pointer to Constant
A pointer that points to a constant value (cannot modify the value).
#include <stdio.h> int main() { int num = 100; const int *ptr = # // Pointer to constant // *ptr = 200; // Error: Cannot modify the value printf("Value: %d\n", *ptr); return 0; }
Pointers and Arrays in C
In C, pointers and arrays are closely related. The name of an array acts as a pointer to its first element, and pointer arithmetic can be used to traverse the array efficiently.
1. Accessing Array Elements Using Pointers
Instead of using array indexing (arr[i]), we can access elements using pointers.
Example:
#include <stdio.h> int main() { int scores[] = {80, 90, 85, 95, 88}; int *ptr = scores; // Array name acts as a pointer printf("Sanfoundry Quiz Scores:\n"); for (int i = 0; i < 5; i++) { printf("Score %d: %d\n", i + 1, *(ptr + i)); // Pointer arithmetic } return 0; }
Output:
Sanfoundry Quiz Scores: Score 1: 80 Score 2: 90 Score 3: 85 Score 4: 95 Score 5: 88
2. Pointer Arithmetic with Arrays
ptr + 1 moves to the next element (because pointers store addresses). *(ptr + i) accesses the value at that position.
Example:
#include <stdio.h> int main() { int arr[] = {10, 20, 30, 40, 50}; int *ptr = arr; printf("First: %d\n", *ptr); printf("Second: %d\n", *(ptr + 1)); printf("Third: %d\n", *(ptr + 2)); return 0; }
Output:
First: 10 Second: 20 Third: 30
3. Array of Pointers
An array of pointers is useful for storing multiple strings.
#include <stdio.h> int main() { char *topics[] = {"Pointers", "Arrays", "Functions", "Loops"}; printf("Sanfoundry C Topics:\n"); for (int i = 0; i < 4; i++) { printf("%s\n", topics[i]); } return 0; }
Output:
Sanfoundry C Topics:
Pointers
Arrays
Functions
Loops
4. Pointer to an Array
A pointer to an array stores the address of the entire array.
#include <stdio.h> int main() { int arr[3] = {100, 200, 300}; int (*ptr)[3] = &arr; // Pointer to an array printf("C Quiz Id: %d\n", (*ptr)[0]); printf("C++ Quiz Id: %d\n", (*ptr)[1]); printf("Java Quiz Id: %d\n", (*ptr)[2]); return 0; }
Output:
C Quiz Id: 100 C++ Quiz Id: 200 Java Quiz Id: 300
Pointers and Functions in C
Pointers and functions in C work together to enhance flexibility and efficiency. By passing pointers to functions, we can modify variables directly, return multiple values, and use function pointers for dynamic execution.
#include <stdio.h> void display() { printf("Sanfoundry Certification Exam Started!\n"); } int main() { void (*ptr)(); // Function pointer declaration ptr = display; // Assign function address ptr(); // Call function using pointer return 0; }
Output:
Sanfoundry Certification Exam Started!
This C program shows how to use function pointers. The display() function prints a message. In main(), a function pointer ptr is created and set to display. Instead of calling display() directly, the program calls it using ptr();. This makes function calls more flexible and useful in advanced programming.
Example: Function Pointer with Parameters
#include <stdio.h> void greet(char *name) { printf("Hello, %s! Welcome to Sanfoundry.\n", name); } int main() { void (*ptr)(char *); // Function pointer declaration ptr = greet; // Assign address ptr("Asha"); // Call function using pointer return 0; }
Output:
Hello, Asha! Welcome to Sanfoundry.
This C program uses function pointers with parameters. The greet() function prints a welcome message using a name. In main(), a function pointer ptr is assigned to greet. Instead of calling greet(“Asha”) directly, the program calls it using ptr(“Asha”);. This makes function calls more flexible and useful for dynamic execution.
String Manipulation Using Pointers in C
In C, strings are represented as arrays of characters, and pointers provide an efficient way to manipulate them.
Example 1: Print a String Using Pointers
#include <stdio.h> int main() { char *str = "Sanfoundry Certification"; printf("Quiz Topic: %s\n", str); return 0; }
Output:
Quiz Topic: Sanfoundry Certification
Example 2: Accessing Each Character Using a Pointer
#include <stdio.h> int main() { char str[] = "Sanfoundry"; char *ptr = str; printf("Sanfoundry Quiz Letters: "); while (*ptr != '\0') { printf("%c ", *ptr); ptr++; } return 0; }
Output:
Sanfoundry Quiz Letters: S a n f o u n d r y
Example 3: String Comparison Using Pointers
#include <stdio.h> int compareStrings(char *s1, char *s2) { while (*s1 && (*s1 == *s2)) { s1++; s2++; } return *(unsigned char *)s1 - *(unsigned char *)s2; } int main() { char str1[] = "Sanfoundry"; char str2[] = "Sanfoundry"; if (compareStrings(str1, str2) == 0) printf("Certification Strings Match!\n"); else printf("Strings are Different.\n"); return 0; }
Output:
Certification Strings Match!
Double Pointers in C
A double pointer (pointer to a pointer) is a pointer that stores the address of another pointer. It is used in cases where a pointer itself needs to be modified inside a function, dynamic memory allocation, or working with arrays of pointers.
Syntax:
datatype **pointer_name;
Example:
int **ptr;
Example 1: Printing a Value Using a Double Pointer
#include <stdio.h> int main() { int quizScore = 95; int *ptr = &quizScore; int **dptr = &ptr; printf("Quiz Score: %d\n", **dptr); return 0; }
Output:
Quiz Score: 95
dptr stores the address of ptr, and ptr stores the address of quizScore. Accessing **dptr gives the actual value.
Example 2: Array of Pointers Using Double Pointer
#include <stdio.h> int main() { int scores[3] = {90, 85, 80}; int *ptr[3]; // Array of pointers int **dptr = ptr; for (int i = 0; i < 3; i++) ptr[i] = &scores[i]; printf("Sanfoundry Quiz Scores:\n"); for (int i = 0; i < 3; i++) printf("Quiz %d Score: %d\n", i + 1, **(dptr + i)); return 0; }
Output:
Sanfoundry Quiz Scores: Quiz 1 Score: 90 Quiz 2 Score: 85 Quiz 3 Score: 80
dptr points to an array of pointers, and we access elements dynamically.
FAQs on Pointers in C
1. What is a pointer in C?
A pointer is a variable that holds the memory address of another variable. It allows direct access to memory, making programs more efficient.
2. What is the difference between * and & in C?
- & (Address-of Operator) – Returns the memory address of a variable.
- * (Dereference Operator) – Accesses the value stored at the memory address.
3. What happens if you dereference a NULL pointer?
Dereferencing a NULL pointer (accessing its value) leads to errors and may crash the program because it points to nothing.
4. What is pointer arithmetic?
Pointer arithmetic allows moving through memory using addition or subtraction. This helps navigate elements in an array or structure.
5. What is a void pointer?
A void pointer can store the address of any data type but must be converted to the correct type before use.
6. What is a dangling pointer?
A dangling pointer is a pointer that refers to memory that has been freed or deleted. Using it can cause unpredictable program behavior.
7. What are the risks of using pointers in C?
- Memory Leaks – Forgetting to free allocated memory.
- Dangling Pointers – Using freed or unallocated memory.
- Segmentation Fault – Dereferencing NULL or invalid pointers.
- Uninitialized Pointers – Using pointers without proper initialization.
8. What is NULL in pointers?
NULL is a special value that represents a pointer not pointing to any valid memory. It helps prevent accidental access to invalid memory locations.
9. How do you free dynamically allocated memory?
To prevent memory leaks, free allocated memory when it’s no longer needed. This ensures efficient memory usage in programs.
Key Points to Remember
Here is the list of key points we need to remember about “Pointers in C”.
- Pointers store memory addresses, helping to access and manage data efficiently. They are useful in dynamic memory, functions, and data structures.
- The * symbol is used for pointer declaration and accessing values, while the & symbol gets a variable’s memory address.
- A null pointer (NULL) points to nothing, preventing errors from uninitialized memory access and reducing crashes.
- Pointer arithmetic lets you move through arrays and data structures easily by changing memory addresses.
- Function pointers hold addresses of functions, allowing flexible program execution like callbacks in event-driven programming.
- Dynamic memory functions (malloc, calloc, free, realloc) let you allocate and manage memory while a program runs.
- Double pointers (**ptr) store addresses of other pointers, useful for modifying function arguments and handling complex data structures.
- Watch Advanced C Programming Videos
- Apply for Computer Science Internship
- Check Computer Science Books
- Practice Computer Science MCQs
- Check C Books