Pointers in C Programming Language

Pointers in C Programming Language: In the world of C programming, pointers are one of the most powerful and flexible tools. They allow you to directly interact with memory, enabling efficient memory management and performance. Understanding pointers is key to mastering C, as they are used in everything from array manipulation to dynamic memory allocation and function calls.

In the world of C programming, pointers in C are one of the most powerful and flexible tools. They allow you to directly interact with memory, enabling efficient memory management and performance. Understanding pointers is key to mastering C, as they are used in everything from array manipulation to dynamic memory allocation and function calls.

In this article, we’ll dive deep into the concept of pointers, explore their syntax, and walk through practical examples that demonstrate how they are used in real-world programming scenarios.

A pointers in C is a variable that stores the memory address of another variable. In simpler terms, it “points” to the location of another variable in memory, allowing you to access or manipulate the data stored at that location.

int *ptr;

In the above declaration:

int is the data type that the pointer points to (in this case, an integer).
*ptr means that ptr is a pointer to an integer.
A pointer itself occupies a memory location, just like any other variable, and its value is the address of the variable it points to.

int *x;

In the above declaration:

x is pointer to an interger x can hold the address of an integer variable.

Example:

int a = 100; /* the meaning of this statement is to store integer value 10 at memory location let’s say 1024 and name of that location is a; */

int *x; /* the meaning of this statement is, x is a pointer to an interger x can hold the address of an integer variable. */

x = &a; /* the meaning of this statement is, x store the address of variable a i.e., 1024 address value present at address loction let’s say 2024 memory location of x variasble. */

printf(“%u”, x); // in our case the output is here 1024.

printf(“%u”, *x); // the output of this statement is 100.

Example: Let’s say memory location of a is 1024, b is 2024 and c is 3024 then explain the following code:

int a = 100; // definition of variable a.

int *b, **c; // declaration of pointer variable b and c.

b = &a; // pointer variable b contain the address location of a.

c = &b; // pointer variable c contain the address loction of b.

printf(“%u”, b); // the output: 1024.

printf(“%u”, *b); // the output: 100.

printf(“%u”, c); // the output: 2024

printf(“%u”, *c); // the output: 1024

printf(“%u”, **c); // the output: 100

Example:

int a = 400;

char *b;

b = &a;

printf(“%d”, *b); // Output: 144

Example:

int a = 62;

char *b = &a;

parintf(“%d”, *b); // Output: 62

  • Arrays and Pointers are equivalent not equal or identical or same.
  • a[i] equivalent to * (a + i)
  • In Arrays Post increment/decrement are not allowed but in case of pointers this is perfectly Ok (i.e., a++, ++a, –a, a–).
  • The name of an arrays will never be in left side of the assignement operator but in case of pointers veriables are allowed.
  • pointers + values or pointers – values are allowed.
  • pointers++, ++pointers, –pointers and pointers– are allowed.
  • subtractions of two pointers are perfectly ok but other all cases are not allowed like pointers (+, *, / and %) pointers are not allowed.
  • We can’t apply Bitwise operations on pointers.
  • We can apply Relational Operations on pointers.

int (*a) [8];

/* How can I read? Answer: a is a pointer to an array of 8 intergers. */

Rule:

i. () parenthesis function

ii. [] square bracket an array

iii. * Astrics pointer

iv. Identifier Name of variable functions

v. Datatypes

Note:

Priority order is: i < ii < iii < iv < v and associativity: i & ii are Left to Right and iii & iv are Right to Left.

Example:

int *a;

/* a is a pointer to an integer. */

int *a[5];

/* a is an array of 2 pointers to an integer. */

int (*a)(int);

/* a is a pointer to a functions that takes an integer argument and return an integer. */

int (*a)(int, int);

/* a is a pointer to function that takes two integer arguments and function return an integer. */

Every variable in a C program is stored in a unique memory location. You can obtain the memory address of a variable by using the address-of operator (&).

Example:

int a = 10;
int *ptr = &a; // ptr now stores the memory address of a
printf(“Memory address of a: %p\n”, ptr);
Here, %p is used to print the memory address stored in the pointer.

To access the value stored at the memory location a pointer points to, you use the dereference operator (*).

Example:

int a = 10;
int *ptr = &a;
printf(“Value of a: %d\n”, *ptr); // prints the value stored at the address stored in ptr (10)
By using *ptr, you are accessing the actual value stored in a.

Pointers in C support arithmetic operations such as addition, subtraction, and comparison. When performing arithmetic on a pointer, you’re actually moving the pointer to different memory locations based on the size of the data type the pointer refers to.

Incrementing (p++) a pointer moves it to the next memory location for the type of variable it points to.
Decrementing (p–) moves it to the previous location.

Example:

int arr[3] = {10, 20, 30};
int *ptr = arr; // ptr points to the first element of the array (arr[0])

ptr++; // ptr now points to arr[1]
printf(“Value at arr[1]: %d\n”, *ptr); // prints 20
In this example, incrementing the pointer advances it by sizeof(int) (the size of an integer), so it now points to the next element of the array.

A pointer can also store the address of another pointer. This is known as a pointer to a pointer, or a double pointer.

Declaration of a Double Pointer:

int **pptr;
Here, pptr is a pointer to a pointer that points to an integer.

Example:

int a = 5;
int *ptr = &a;
int **pptr = &ptr; // pptr points to ptr, which points to a

printf(“Value of a using double pointer: %d\n”, **pptr); // prints 5
In this example, pptr stores the address of ptr, which in turn holds the address of a. Dereferencing pptr twice gives us the value of a.

Arrays and pointers in C are closely related. The name of an array is essentially a pointer to its first element. When you use a pointer to an array, you can access the elements of the array using pointer arithmetic.

Example:

int arr[3] = {10, 20, 30};
int *ptr = arr; // arr is equivalent to &arr[0]

for (int i = 0; i < 3; i++) {
printf(“Value at arr[%d]: %d\n”, i, *(ptr + i)); // access elements using pointer arithmetic
}
In this example, *(ptr + i) is used to access the elements of the array.

ptr can be incremented or decremented because it’s a variable.
arr is a constant pointer, which means you cannot change the address it points to (it always points to the first element of the array).

In C, you can allocate memory dynamically using pointers. Dynamic memory allocation is especially useful when you don’t know the size of an array or data structure at compile time.

  • malloc(): Allocates memory but doesn’t initialize it.
  • calloc(): Allocates memory and initializes all elements to zero.
  • realloc(): Resizes the memory previously allocated.
  • free(): Frees the allocated memory.

Example of malloc():

int ptr = (int) malloc(5 * sizeof(int)); // dynamically allocate memory for 5 integers

if (ptr == NULL) {
printf(“Memory allocation failed!\n”);
return 1;
}

for (int i = 0; i < 5; i++) {
ptr[i] = i * 2;
printf(“%d “, ptr[i]); // prints 0 2 4 6 8
}

free(ptr); // always free dynamically allocated memory


In this example, malloc() allocates memory for 5 integers, and the memory is later freed using free() to prevent memory leaks.

Pointers can be passed to functions to modify the actual values of the variables they point to. This is useful for functions that need to return more than one value or modify the caller’s variables.

Example of Passing Pointers to Functions:

void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

int main() {
int x = 5, y = 10;
swap(&x, &y); // pass the addresses of x and y
printf(“x = %d, y = %d\n”, x, y); // prints x = 10, y = 5
}
In this example, the swap() function uses pointers to exchange the values of x and y in the calling function.

A pointer to a function stores the address of a function and can be used to call that function. This feature is commonly used in callback functions and when passing functions as arguments to other functions.

Example of Function Pointer:

void greet() {
printf(“Hello, World!\n”);
}

int main() {
void (*func_ptr)() = greet; // declare and assign function pointer
func_ptr(); // call the function using the pointer
}
In this example, func_ptr is a pointer to the greet() function, and calling func_ptr() invokes the function.

Uninitialized Pointers: Using pointers without initializing them can lead to undefined behavior.

int *ptr; // uninitialized pointer
*ptr = 5; // dangerous: ptr could point to any random memory location

Memory Leaks: Forgetting to free dynamically allocated memory leads to memory leaks.

int ptr = (int) malloc(5 * sizeof(int));
// Forgetting to use free(ptr); can cause memory leaks.

Dereferencing Null or Invalid Pointers: Dereferencing a null pointer or a pointer that doesn’t point to valid memory can crash the program.

int *ptr = NULL;
printf(“%d”, *ptr); // error: dereferencing null pointer

What is a pointer in C programming?

A pointer is a variable that stores the memory address of another variable. Instead of holding a value like a regular variable, a pointer holds the address where the value is stored in memory.

How do you declare a pointer in C?

To declare a pointer, you use the * operator with the data type the pointer will point to. For example:
int *ptr;
This declares a pointer ptr that can store the address of an integer variable.

What is the purpose of the & operator in relation to pointers?

The & operator is called the address-of operator. It is used to obtain the memory address of a variable. For example, if you have an integer a, using &a gives you the memory address of a.

What does the * operator do in pointer operations?

The * operator is called the dereference operator. It is used to access the value stored at the memory address a pointer is pointing to. For example, if ptr is a pointer, *ptr gives the value stored at the address held by ptr.

What is NULL pointer in C?

A NULL pointer is a special pointer that doesn’t point to any valid memory location. It is typically used as a sentinel value to indicate that the pointer isn’t currently pointing to anything.
int *ptr = NULL;

Can you perform arithmetic operations on pointers?

Yes, you can perform arithmetic operations on pointers. You can increment (++), decrement (–), add (+), or subtract (-) pointers, which will move the pointer to the next or previous memory locations based on the size of the data type it points to.

What is pointer arithmetic?

Pointer arithmetic involves modifying the address stored in a pointer using arithmetic operators. For instance, incrementing a pointer (p++) moves it to the next memory location of the type it points to. For example:
int arr[3] = {1, 2, 3};
int *ptr = arr;
ptr++; // ptr now points to the second element of arr

How do you pass a pointer to a function in C?

To pass a pointer to a function, you use the pointer variable as an argument. This allows the function to modify the actual data that the pointer points to.
Example:
void increment(int p) { (p)++;
}
int main() {
int a = 10;
increment(&a); // Pass the address of a
printf(“%d”, a); // prints 11
}

What is the difference between pointers and arrays?

In C, the name of an array is a pointer to the first element of the array. However, an array is a block of memory with a fixed size, while a pointer is a variable that can be reassigned to point to different memory locations. Additionally, you cannot change the address held by an array name, but you can modify the value of a pointer.

What are double pointers (pointer to pointer)?

A double pointer is a pointer that stores the address of another pointer. It is used when you need to manipulate the pointer itself, not just the value it points to.
int a = 10;
int *p = &a;
int **pp = &p;

What is dynamic memory allocation, and how is it related to pointers?

Dynamic memory allocation is the process of allocating memory at runtime using pointers. In C, functions like malloc(), calloc(), and realloc() are used for dynamic memory allocation. Pointers are crucial for accessing and managing dynamically allocated memory, and free() is used to release it when it’s no longer needed.

Why should you free dynamically allocated memory?

Dynamically allocated memory remains allocated until the program terminates or until it is explicitly freed using the free() function. Failing to free memory can cause memory leaks, where memory is consumed but never released, which can degrade the performance of the program over time.

What are common mistakes when using pointers in C?

Some common mistakes include:
Dereferencing a null or uninitialized pointer, which can cause a crash.
Memory leaks: Forgetting to free dynamically allocated memory.
Incorrect pointer arithmetic, which can lead to accessing invalid memory locations.
Double freeing memory, which can result in undefined behavior.
Previous

Learn More

Subscribe “JNG ACADEMY” for more learning best content.

C Programming Language Lecture-01

C Programming Language Lecture-02

C Programming Language Lecture-03

C Programming Language Lecture-04

C Programming Language Lecture-05

C Programming Language Lecture-06

C Programming Langauge Lecture-07

C Programming Language Lecture-08

C Programming Language Youtube Playlist

Thank You So Much, Guys… For Visiting our Website and Youtube.

Leave a Comment