Table of Contents
C Pointers In C
Pointers are indeed a fundamental concept in the C programming language. They are used to store memory addresses of variables, functions, and other pointers, enabling powerful features like low-level memory access, dynamic memory allocation, and more. Pointers are a crucial tool for manipulating and managing memory and data structures in C.
What is a Pointer in C?
A pointer is indeed a derived data type that can store the memory address of other C variables or memory locations. Using pointers, you can access and manipulate the data stored in the memory locations they point to. This capability is essential for tasks such as dynamic memory allocation, data structure manipulation, and low-level memory access in the C programming language.
Syntax
The syntax of pointers will be similar to the variable declaration in C, however, we can use the ( * ) dereferencing operator in the pointer declaration.
datatype * ptr;
where
- ptr – Name of the pointer.
- datatype – The type of data it is pointing to.
How to Use Pointers?
The use of pointers can be classified into 3 :
- Pointer Declaration
- Pointer Initialization
- Dereferencing
1. Pointer Declaration
In pointer declaration, we will declare the pointer won’t initialize it. To declare a pointer, we have to use the ( * ) dereference operator before its name.
Example
int *ptr;
The pointer which is declared will hence point to some random memory address as it is not initialized. Such pointers are called wild pointers.
2. Pointer Initialization
When initializing a pointer in C, you typically assign an initial value that is a memory address. The &
(ampersand) operator is used to obtain the memory address of a variable, and you can store that memory address in a pointer variable.
int var = 10;
int * ptr;
ptr = &var;
Although, We can also declare and initialize the pointer in a single step. Therefore, This method is called pointer definition as the pointer is declared and initialized at a time.
Example
int *ptr = &var;
3. Dereferencing
Dereferencing a pointer in C involves using the *
(asterisk) operator to access the value stored in the memory address specified by the pointer. This allows you to work with the actual data pointed to by the pointer.
Pointer In C Example
// C program to illustrate Pointers
#include <stdio.h>
void geeks()
{
int var = 10;
// declare pointer variable
int* ptr;
// note that data type of ptr and var must be same
ptr = &var;
// assign the address of a variable to a pointer
printf("Value at ptr = %p \n", ptr);
printf("Value at var = %d \n", var);
printf("Value at *ptr = %d \n", *ptr);
}
// Driver program
int main()
{
geeks();
return 0;
}
Output
Value at ptr = 0x7fff1038675c
Value at var = 10
Value at *ptr = 10
Type Of Pointers
Pointers are classified into different types depending on the parameters. For instance, we can take a look at the type of variable stored in the memory location pointed by the pointer. Thus, the pointers can be classified into the following types:
1. Integer Pointers
Integer pointers will point to the integer values
Syntax
int *ptr;
They are also referred as the Pointer to integer
Indeed, a pointer can point to any primitive data type. Moreover, It can also point to derived data types such as arrays and user-defined data types such as structures.
2. Array Pointer
Pointers and arrays are closely related in C. An array name can be considered a pointer to its first element. This relationship is often referred to as “arrays and pointers” in C programming.
Syntax
char *ptr = &array_name;
3. Structure Pointer
The pointer pointing to Structure type is called Structure Pointer or Pointer to Structure
Syntax
struct struct_name *ptr;
In C, structure pointers are mostly seen in data structures such as linked lists, trees, etc.
4. Function Pointers
Function pointers will point to the functions. Although, they are different from the rest of the pointers in the sense that instead of pointing to the data, they will point to the code. For example, a function prototype – int func (int, char), the function pointer for this function will be.
Syntax
int (*ptr)(int, char);
5. Double Pointers
In C, you can define pointers that store the memory address of other pointers. These are referred to as double-pointers or pointers-to-pointer. Instead of pointing directly to a data value, they point to another pointer.
Syntax
datatype ** pointer_name;
Dereferencing Double Pointer
*pointer_name; // get the address stored in the inner level pointer
**pointer_name; // get the value pointed by inner level pointer
6. Null Pointer
Null pointers are the pointers that won’t point to any memory location. Also, it can developed by providing a value to the null pointer. Hence, pointer of any type can be given values.
data_type *pointer_name = NULL;
or
pointer_name = NULL
7. Void Pointer
Void pointers, also known as generic pointers, are pointers that don’t have an associated data type. They are used to create more flexible and versatile pointers because they can point to data of any data type, and they can be typecasted to any other data type.
Syntax
void * pointer_name;
8. Wild Pointers
Wild pointers in C are pointers that have not been initialized with a valid memory address or have been left pointing to a memory location that is no longer valid. They can cause serious issues in programs, such as crashes, memory corruption, and unexpected behavior, because they lack a well-defined target.
int *ptr;
char *str;
9. Constant Pointers
A constant pointer is a pointer where the memory address is constant and cannot be modified once defined. It always points to the same memory address.
Syntax
data_type * const pointer_name;
10. Pointer to Constant
A pointer to a constant is a pointer where the memory address is not constant, but the data it points to is constant and cannot be modified through the pointer. The pointer itself can be changed to point to different memory locations
Syntax
const data_type * pointer_name;
Other Type of Pointers
These are specialized types of pointers with specific purposes:
- Far Pointer: A far pointer is typically 32-bit and can access memory outside the current segment. They are often used in segmented memory models.
- Dangling Pointer: A dangling pointer is a pointer that points to a memory location that has been deleted (or freed). Using a dangling pointer can lead to undefined behavior.
- Huge Pointer: A huge pointer is a 32-bit pointer that contains both a segment address and an offset address. These were used in older memory models.
- Complex Pointer: Complex pointers are pointers with multiple levels of indirection, often used in more advanced data structures.
- Near Pointer: A near pointer is used to store 16-bit addresses within the current segment, typically on a 16-bit machine.
- Normalized Pointer: A normalized pointer is a 32-bit pointer designed to have as much of its value in the segment register as possible. This was relevant in segmented memory models.
- File Pointer: A file pointer is a pointer to a
FILE
data type, often referred to as a stream pointer or a file pointer. It is used to interact with files and input/output operations in C.
These various types of pointers serve specific purposes and are used in different contexts, depending on the memory model and requirements of the application.
Size Of Pointers In C
Your explanation of pointer sizes in C is mostly accurate. The size of pointers in C is indeed determined by the operating system and CPU architecture, not the type they point to. However, the sizes you provided are not universally true for all systems. The actual size of pointers can vary depending on the platform and the compiler.
Here’s a more accurate description:
- On many 64-bit systems, pointers are typically 8 bytes in size, as they store 64-bit memory addresses.
- On many 32-bit systems, pointers are usually 4 bytes in size, as they store 32-bit memory addresses.
The reason for the same size of pointers of a specific architecture is consistent with your explanation: Pointers store memory addresses, and the size of memory addresses is determined by the CPU architecture, not the data type they point to. However, it’s important to note that there can be exceptions and variations on different platforms, so it’s always a good practice to use the sizeof
operator to determine the size of pointers on a specific system.
How to find the size of pointers in C?
Example: C Program to find the size of different pointer types.
// C Program to find the size of different pointers types
#include <stdio.h>
// dummy structure
struct str {
};
// dummy function
void func(int a, int b){};
int main()
{
// dummy variables definitions
int a = 10;
char c = 'G';
struct str x;
// pointer definitions of different types
int* ptr_int = &a;
char* ptr_char = &c;
struct str* ptr_str = &x;
void (*ptr_func)(int, int) = &func;
void* ptr_vn = NULL;
// printing sizes
printf("Size of Integer Pointer \t:\t%d bytes\n",
sizeof(ptr_int));
printf("Size of Character Pointer\t:\t%d bytes\n",
sizeof(ptr_char));
printf("Size of Structure Pointer\t:\t%d bytes\n",
sizeof(ptr_str));
printf("Size of Function Pointer\t:\t%d bytes\n",
sizeof(ptr_func));
printf("Size of NULL Void Pointer\t:\t%d bytes",
sizeof(ptr_vn));
return 0;
}
Output
Size of Integer Pointer : 8 bytes
Size of Character Pointer : 8 bytes
Size of Structure Pointer : 8 bytes
Size of Function Pointer : 8 bytes
Size of NULL Void Pointer : 8 bytes
No matter what the type of pointer it is, the size of each and every pointer will be the same.
The type declaration is needed in the pointer for dereferencing and pointer arithmetic purposes.
Pointer Arithmetic
Pointer arithmetic refers to the set of valid arithmetic operations that can be performed on pointers. These operations are different from regular mathematical calculations and are limited to a specific set of operations
- Increment in a Pointer
- Decrement in a Pointer
- Addition of integer to a pointer
- Subtraction of integer to a pointer
- Subtracting two pointers of the same type
- Comparison of pointers of the same type.
- Assignment of pointers of the same type.
// C program to illustrate Pointer Arithmetic
#include <stdio.h>
int main()
{
// Declare an array
int v[3] = { 10, 100, 200 };
// Declare pointer variable
int* ptr;
// Assign the address of v[0] to ptr
ptr = v;
for (int i = 0; i < 3; i++) {
// print value at address which is stored in ptr
printf("Value of *ptr = %d\n", *ptr);
// print value of ptr
printf("Value of ptr = %p\n\n", ptr);
// Increment pointer ptr by 1
ptr++;
}
return 0;
}
Output
Value of *ptr = 10
Value of ptr = 0x7ffe8ba7ec50
Value of *ptr = 100
Value of ptr = 0x7ffe8ba7ec54
Value of *ptr = 200
Value of ptr = 0x7ffe8ba7ec58
C Pointers And Arrays
In C, pointers and arrays are closely related, and the array name acts as a pointer constant to the address of the first element. Here are some key points:
- An array name, such as
val
, can be used interchangeably with&val[0]
to refer to the address of the first element of the array. - If you assign the value of this pointer constant to a non-constant pointer of the same type, you can access the elements of the array using that pointer.
Example 1 – Accessing Array Elements using Pointer with Array Subscript
// C Program to access array elements using pointer
#include <stdio.h>
void skill()
{
// Declare an array
int val[3] = { 5, 10, 15 };
// Declare pointer variable
int* ptr;
// Assign address of val[0] to ptr.
// We can use ptr=&val[0];(both are same)
ptr = val;
printf("Elements of the array are: ");
printf("%d, %d, %d", ptr[0], ptr[1], ptr[2]);
return;
}
// Driver program
int main()
{
skill();
return 0;
}
Output
Elements of the array are: 5 10 15
Example 2: Accessing Array Elements using Pointer Arithmetic
// C Program to access array elements using pointers
#include <stdio.h>
int main()
{
// defining array
int arr[5] = { 1, 2, 3, 4, 5 };
// defining the pointer to array
int* ptr_arr = &arr;
// traversing array using pointer arithmetic
for (int i = 0; i < 5; i++) {
printf("%d ", *ptr_arr++);
}
return 0;
}
Output
1 2 3 4 5
Use Of Pointers
Pointers are indeed a fundamental and essential concept in C, and they serve various purposes, including:
- Passing Arguments by Reference: Pointers allow functions to modify the original data in memory, providing a way to pass arguments by reference.
- Accessing Array Elements: Pointers are commonly used to traverse and manipulate array elements efficiently.
- Returning Multiple Values from Functions: By using pointers, functions can return multiple values or modify values outside of the function.
- Dynamic Memory Allocation: Pointers are crucial for dynamic memory allocation functions like
malloc
,calloc
, andrealloc
to manage memory at runtime. - Implementing Data Structures: Pointers are used to build complex data structures like linked lists, trees, and graphs.
- System-Level Programming: In low-level system programming, memory addresses are often used, and pointers provide a means to access and manipulate memory directly.
- Locating the Exact Value at a Memory Location: Pointers are used to access data at specific memory addresses.
- Avoiding Compiler Confusion: Pointers can be used to distinguish between variables with the same name in different scopes.
- Control Tables: Pointers can be used in data structures like control tables, which define the behavior of a program.
Overall, understanding and effectively using pointers is essential for a wide range of programming tasks in C, from basic memory manipulation to building complex data structures and working with low-level system programming.
Disadvantages of Pointers
- Memory Corruption with Incorrect Values: Providing incorrect values to pointers can indeed lead to memory corruption, especially when writing to memory locations that should not be accessed.
- Complexity of Pointers: Pointers can be complex to understand, especially for beginners, because they involve low-level memory manipulation and require a good understanding of memory management.
- Responsibility for Memory Leaks: Pointers can be a source of memory leaks in C if dynamically allocated memory is not properly deallocated with functions like
free
. - Speed Compared to Variables: Pointers themselves are not inherently slower than variables. However, using pointers for certain operations might introduce a slight overhead, but in many cases, the performance difference is negligible.
- Uninitialized Pointers and Segmentation Faults: Uninitialized pointers can indeed cause segmentation faults, as they may point to random or invalid memory locations. It’s important to initialize pointers before using them to avoid such issues.
It’s crucial to handle pointers carefully, especially when working with memory allocation and manipulation, to prevent memory-related errors and issues like memory corruption and memory leaks.
FAQ- C Pointers In C
Q1. What is C pointer in C?
Ans. In C, a pointer is a variable that stores the memory address of another variable, which can be of various types. The size of a pointer is determined by the platform, typically 4 bytes in 32-bit architectures, but it can vary. Use sizeof
to check the pointer size on your platform.
Q2. What is the use of pointers in C?
Ans. In C, pointers are essential for data structures, flexible array access, and file handling.
Q3. What is the syntax of pointer?
Ans. In C, you declare a pointer by adding a *
before the name and associate it with a specific data type (e.g., int
or double
). It’s a common convention to use “p” or “ptr” as a prefix or suffix in pointer variable names, like iPtr
, numberPtr
, pNumber
, or pStudent
.
Hello, I’m Hridhya Manoj. I’m passionate about technology and its ever-evolving landscape. With a deep love for writing and a curious mind, I enjoy translating complex concepts into understandable, engaging content. Let’s explore the world of tech together