Artificial Intelligence

Pointers in Computing and Its Applications

Image Source: Sven Finger from Unsplash.

Last year, I decided to learn the C programming language due to its status as one of the foundational and primitive languages in the field. I recognized its importance as a building block for other languages like Python, C++, and Rust. During my learning journey, I encountered a significant challenge in grasping the concept of pointers. For several months, I struggled to comprehend this fundamental concept, which proved to be a hurdle in understanding other essential concepts in C such as Strings, Functions, and Arrays, all of which relied on a solid understanding of pointers. This article is intended for programmers curious about how to efficiently control and store variables while coding.

Before delving into the concept of pointers, discussing memory management in programming is essential, as it forms the core foundation of pointers.

Image Source: Vincent Botta from Unsplash.

As an illustration, let’s consider the computer’s memory components: Random Access Memory (RAM) and Read-Only Memory (ROM). RAM is utilized for running applications on the system and serves as temporary storage. However, when the system is powered down, the data in RAM is wiped out or destroyed. On the other hand, ROM also referred to as storage, is where we store data permanently on the system. The data stored in ROM remains intact regardless of whether the system is running or shut down. Typically, the size of a ROM is often larger than that of a RAM.

Another distinguishing characteristic between RAM and ROM is their ease of data retrieval and storage. To illustrate this, let’s consider a scenario where you have a library filled with books and a table in your room. Suppose there are specific books you want to read. Optimal data retrieval and storage would involve placing the desired books on your table close to you, as this saves you time from searching through your vast library. In this analogy, RAM is akin to the table in your room, while ROM represents the library. As mentioned earlier, the library (ROM) is typically larger in size compared to the table (RAM).

In programming, we also use the concept of memory management to handle variables and also size variables and data structures. Let's go ahead and discuss pointers.

What is a Pointer?

A pointer is simply a variable that stores the address of another variable.

In C, the primitive data types are basically integers, float, boolean, and characters. integer and floats typically occupy 4 bytes of memory, the boolean data type takes up 2 bytes of memory, while the character data type takes up 1 byte in memory. Understanding these sizes is crucial because memory management is often a dynamic process. Being aware of the size requirements of the data types you intend to create can help prevent memory clashes and faults during program execution.

In memory, a byte is approximately 8 bits. and each data type of variable has its specific size. The bit is a binary of 0’s and 1's.

Image by Author.

For instance, I try to create an integer variable in C as follows:

int b = 2;

C is a statically typed language, which is why we have to define the data type before the variable name. When the program is compiled, the variable b is created and stored in memory not in storage, which means that after the program is executed the variable is destroyed and doesn’t exist. The position in memory where the variable is stored is called the address of the variable.

Image by Author.

As we can see from the illustration b occupies 4 bytes of memory because we already declared that the variable b is an integer, and the base address of variable b is 1000,

NB: the address is often expressed as hexadecimal decimal values, we are using basic numbers in this article just to grasp the concept quickly.

This occurs every time we declare variables and other components of a program, and one of the concepts used to wield the complexity of memory management is pointers. Now let us go ahead and discuss pointers.

With pointers we can make reference to the variable b by storing its address in a variable called the pointer variable like so:

int *ptr;

ptr = &b;

So, we declared a pointer variable ptr using the * operator. The variable stores the address of an integer variable and then the next line of code saves the address of variable b into the pointer variable ptr using the address operator & in C.

This is how the process pans out visually in memory:

Image by Author.

To provide an analogy, let’s consider a cup of water placed in a kitchen. In this scenario, we can draw a parallel to the concept of pointers. The cup itself represents the variable b, while the water inside the cup represents the value it holds, such as the integer 2. Similarly, just as the cup’s location is the kitchen, the memory address associated with the variable b points to the memory location where the value 2 is stored.

Image Source: Clint Mckoy from Unsplash.

In the same way, when we need to access or refer to the variable b and its value, we can simply point to its memory address. Anyone who needs to access or locate the variable b can also refer to the memory address and retrieve the stored value, just like retrieving the water from the cup by pointing to the kitchen. Pointers serve as a way to navigate and manipulate data in memory efficiently.

Image Source: Author.

We can visualize the operation of pointers in code using the following code below:


#include <stdio.h>

int main()
{
int b = 2;

int *ptr;

ptr = &b;

printf("The value of variable b is %d\n", b);
printf("The value the ptr pointer points to is %d\n", *ptr);
printf("The address of variable b is %p\n", &b);
printf("The address that the pointer ptr stores is %p\n", ptr);
printf("The address of pointer ptr is %p\n", &ptr);
return 0;
}

In the code written above, we have defined a variable b and assigned a value of 2 to it. Then we go ahead and declare a pointer ptr to hold the address of an integer variable using the * operator and assign the address of the variable b to the pointer ptr.

Output:

The value of variable b is 2
The value the ptr pointer points to is 2
The address of variable b is 0x7ffdd1cdd06c
The address that the pointer ptr stores is 0x7ffdd1cdd06c
The address of pointer ptr is 0x7ffdd1cdd070

Observing the output of the given code. We utilize the %p format specifier to retrieve the address of a variable, and the addresses are represented in hexadecimal format. Additionally, it is crucial to recognize that the pointer variable itself also has an address and the size of a pointer variable is basically 8 bytes of memory. if we observe the output of the code we would notice that the address of the variable b and the address that is stored in the pointer ptr are the same.

Applications of Pointers

Now, we have rigorously discussed the concept of pointers. Let’s go ahead and explore some of the applications of this important concept and examine its relevance in C.

1. Manoevring Function Scopes

One significant application and usefulness of pointers is in the context of functions. In C, local variables created within a function have limited scope and cannot be directly accessed or modified by other functions. However, by using pointers, we can overcome this limitation.

By passing the address of a variable as a pointer to a function, the function gains the ability to access and modify the original variable. This allows for data sharing and manipulation across different functions.

Pointers enable functions to operate on the same data, facilitating efficient communication and interaction between different parts of a program. This flexibility and ability to manipulate data through pointers are instrumental in solving various programming problems and optimizing memory usage.

Let's take the following code as an example:

int add_number(int num) {
num + 2;
return num;
}

int main() {
int num = 5;
add_number(num);
printf("The new value of num is %d.\n", num);
return 0;
}

In the following code, we have two functions; the add_number function to increase a number by 2 and the main function which is the entry point of the program. In the main function, we initiate the add_number function. Let’s see what the outcome of the program looks like.

Output:

The new value of num is 5

In the given code, the value of num in the add_number function does not affect the value of the num variable in the main function. This is because they have separate scopes and are distinct variables. When the program enters the add_number function and adds 2 to the local num variable within that function, it does not impact the num variable in the main function.

As a result, when the program returns to the main function after executing the add_number function, the value of the num variable in the main function remains unchanged, resulting in an output of 5instead of the expected 7.

This highlights the importance of understanding variable scope and the role of pointers in enabling communication and modification of variables across different functions.

Now let's solve the problem in the previous code using pointers, we initiate the concept of pointers into the code like so:

#include <stdio.h>

void add_number(int *num) {
*num += 2;
}

int main() {
int num = 5;
add_number(&num);
printf("The new value of num is %d\n", num);
return 0;
}

The code demonstrates the use of pointers to modify the num variable in the add_number function. The add_number function takes a pointer to an integer as a parameter and updates the value of the referenced num variable by adding 2 to it. The modified value of num is now reflected in the main function.

Output:

The new value of num is 7.

We can see now that our modified value of the num variable is now reflected in the main function because we called the variable by reference with the aid of a pointer and not by value.

2. Version Control System

A version control system is a tool used to track and manage changes in a project. It is commonly used in various activities we engage in on a daily basis. For instance, when creating a document or writing content in Microsoft Word, we frequently make modifications throughout the creation process. The application itself keeps a record of the changes made to the file, allowing us to view and revert to previous versions at any given point in time.

This also applies to programming and software development. Examples of version control system used for Software development includes GitHub, Gitlab, and Bitbucket.

A distributed version control system, such as Git, leverages the concept of pointers in its workflow. For example, in GitHub, when changes are made to a file on a local machine, the user needs to add the changes to a staged area using the command git add .. This command prepares the changes to be committed. After staging the changes, the user can then move that version of the file changes to a .git directory using the following command:

git commit -m "Commit message."

This command creates a new version of the file, known as a commit, which is stored in the .git directory. The commit acts as a pointer to the specific changes made to the file at that particular point in time. This enables the user to track and manage the history of changes made to the project, facilitating collaboration and version control in a distributed environment. The history of changes made to the file at every instance of time can be viewed using the following command:

git log

In Git, there is a HEAD pointer that points to the latest commit and branch on the project. The HEAD pointer can also be used to point to the previous commit message in the commit log. The HEAD pointer is very useful in the sense it can easily be used to retrace back to the previous version and any other version of the project incase the current version of the change includes an error.

By leveraging the HEAD pointer, Git provides a powerful mechanism for managing and undoing changes, enabling efficient version control and error correction in a project.

Image source: Author.

The provided image displays the commit log of an open-source project hosted on GitHub. It showcases the organized structure of file changes for each version, accompanied by a unique hash code assigned to each commit message. Additionally, the image illustrates the positioning of the HEAD pointer, indicating the latest commit within the Dolamu_branch branch of the project, signifying that the current state is not on the master branch.

This is how the process looks visually

Image Source: Author.

each commit message has a hash code which is analogous to addresses in basic pointers concept, so we can use the hash code to easily navigate to each version of the file changes.

to learn more about version control systems you can read this article by Knoldus inc.

We have successfully discussed the basic concept of pointers and explored some of the applications. The knowledge of pointers is fundamental to the concept of functions, arrays, strings, and struct in the C programming language.

Thank you for reading.

More content at PlainEnglish.io.

Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.


Pointers in Computing and Its Applications was originally published in Artificial Intelligence in Plain English on Medium, where people are continuing the conversation by highlighting and responding to this story.

https://ai.plainenglish.io/pointers-in-computing-and-its-applications-d57812c34b56?source=rss—-78d064101951—4
By: Dolamu Oludare
Title: Pointers in Computing and Its Applications
Sourced From: ai.plainenglish.io/pointers-in-computing-and-its-applications-d57812c34b56?source=rss—-78d064101951—4
Published Date: Wed, 14 Jun 2023 13:42:49 GMT

Did you miss our previous article…
https://e-bookreadercomparison.com/unstructured-data-decoding-the-concierge-nlp-cluster-way/

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version