Pointer Variables

Pointer Variables

In the pointer operators topic, we came to know how to get the address as well as how to print the value present at that address through the pointers concept by the application of referencing and dereferencing operators. In this topic, we will study how to store the address in the pointer variables and how to play with it.

Declaration of pointer variable

The pointer declaration with syntax and the examples are given in  the below table-1

table-1

Table-1

Note-1: In the above table, it not mandatory to use pointer names as cptr for char pointer, iptr for int pointer and so on, one can use any name for the pointer, but let it be meaningful.

When pointers are declared, we are instructing to the compiler to carry out some important tasks,

Say e.g. int *iptr;

  1. In the above example, the asterisk symbol informs the compiler that the variable declared is nothing but the pointer.

  2. Since, pointer is also a variable declaring it tells to the compiler to set aside some bytes of memory to hold the address of the other variable. 

Note-2: Actually number of bytes allocated for the pointer variable depends on the architecture of the machine, say e.g. if the address bus size is 32 bits, then the sizeof(any pointer) = 4 bytes, similarly if the address bus size is 64 bits, then the sizeof(any pointer) is 8 bytes irrespective of any data type and any level pointer.

  1. The data type(int) associated with the pointer name(iptr) indicates that the pointer(iptr) can point to the address of any integer variable.

  2. From the declaration, the compiler updates the symbol table with the symbol ‘iptr’ and adds the relative address to it.

“In general, A pointer variable is declared by giving it a ‘type’ and the ‘name’. The * symbol tells the compiler that the variable named is the pointer variable and the ‘type’ tells to the compiler that what type of data, the pointer can point to.”

Let we pause a moment and think, if all pointers contains the address which is of integer, then why we need the ‘type’ to be associated with the pointer?

Declaring the pointer variables along with the ‘type’ also instructs the compiler to do the following things apart from the above 4 points,

  1. While dereferencing how many bytes to fetch from the address where pointer is pointing to in the memory.

  2. After fetching that many bytes, how to interpret that data, since all the data will be stored in the memory in binary form, i.e whether to interpret the fetch data as char form, integer form, float form, double form etc… depends on the type of the pointer.

  3. When we apply the pointer arithmetic on the pointer variables, how it will come to know how many bytes to move forward or backward, i.e if we increment / decrement the pointer or if we add a constant to a pointer / subtract a constant from a pointer, depends on the type of the pointer. (This point I will discuss in more detail in the topic pointer arithmetic)

Example-1:

Statement #1. int a = 10;                                    

example-1

Figure-1: Pictorial representation of statement int a = 10;

Statement #2. int *iptr;

example-1 (1)

Figure-2: Pictorial representation of statement int *iptr;

From statement #1, It is clear that we got some 4 bytes(assuming we are working in a 32-bit address bus machine) of memory from the location 1000 onwards to store the value ’10’ in it. ‘a’ is the name associated with this memory address, as shown in the above figures-1, 2.

Similarly, from the statement #2 for pointer also we got some 4 bytes of memory(refer note-3) from the location 2000 onwards, iptr is the name associated with this memory address. But the question is, how can one say, what is the value stored in this address? where the pointer ‘iptr’ is pointing? From the statement #2, it is only the declaration, it is not initialized, so the pointer may contain some junk value or it may contain the NULL, depending on the storage class of the pointer. Dereferencing the uninitialized pointers are always dangerous especially in case of embedded systems.

Note-3: Through out the pointer series, one assumtion is made, i.e size of address bus is 32-bits wide, so that sizeof(any pointer) = 4 bytes.

Note-3A: All the addresses mentioned in the figures are assumptions, it will change during every execution of the program.

So, how to make the pointer ‘iptr’ to point to the address of the variable ‘a’, it is very simple just take the address of the variable ‘a’ by applying the ‘&’ operator and assign it to the iptr as shown in the statement #3 below,

statement #3.  iptr = &a;

statement-3 (1)

Figure-3: Pictorial representation of statement #3

Note-4: Usually, we will not focus more about the value of the pointer variable, since the value might vary every time the program is run. Instead, we will focus on the value stored in the memory location pointed to by the pointer. It is always good practice to represent the diagrams related to pointer topics with the arrow(->) as shown below in the figure -4, but still I will limit it to the usage of some numbers for indicating the addresses because newbies can easily understand it without much difficulties.

figure-4

Figure-4

From the statement #3 and from the figure-3, it is clear that ‘iptr’ contains the address of the variable ‘a’, now I can say that ‘iptr’ points to the memory location where the value of ‘a’ is stored. We can also combine statement #2 and #3 to form a definition as given below,

int *iptr = &a;

Now, let we see how to print the address of the variable ‘a’ and the value contained in the variable through the pointer variable.

table-a.jpg

So, from the above details, we can conclude that

  1. ‘iptr’ is the pointer variable, where 4 bytes of memory is allocated for it. (From Note-3)

  2. ‘iptr’ holds the address of the variable ‘a’, pointing to the memory location where the value of ‘a’ is stored.

  3. ‘*iptr’ gives the value present at that address, i.e the value contained in the variable ‘a’. which is nothing but dereferencing the pointer.

  4. Deferencing the pointer(*iptr) means fetching 4 bytes of memory from the location 1000 onwards, since the type of the pointer is ‘int’.

  5. After fetching 4 bytes, it will interpret that data as the integer.

The summary of example-1, is given in the table below,

table-6 (1)

Table-2

Putting all together in the form of the code and the output is shown below for code-1,

/********************************************************************************************
* Demo code to show how to apply the pointer variables
* ******************************************************************************************/

#include <stdio.h>

int main()
{
//Definition of the variable
int a = 10;

//Declare the pointer of type 'int'
int *iptr;

//Init the pointer to the address of 'a'
iptr = &a;

//Printing the address as well as the value through the pointer variable
printf("The value at address[iptr]: %p: %d\n", iptr, *iptr);

//Printing the address as well as the value through the normal variable
printf("The value at address[&a]: %p: %d\n", &a, *(&a));

return 0;
}

The output of the code-1 is shown below,

out-3.jpg

Figure-5: Output of the code-1

The summary of code-1 and the output of the code-1, is given in the table-3 below,

table-7

Table-3

Example-2:

statement #1. char ch = ‘A’;

statement #2. char *cptr = &ch;

fig-14

Figure-6

From statement #1, ch is the char variable assigned with the value ‘A’, so sizeof(char) = 1 byte of memory is allocated as shown above with the address 1000.

From the statement #2, cptr is the char pointer, where sizeof(pointer) = 4 bytes according to the assumption made, means 4 bytes of memory is allocated for it and the value contained in it is the address of the ‘ch’ variable. Now, cptr is pointing to the loaction in the memory whose value is ‘A’.

The demo code-2 shown below gives the picture of usage of the above statement.

/***************************************************************************
* Demo code to show how to apply the pointer variables on char data type
* *************************************************************************/

#include <stdio.h>

int main()
{
//Definition of the variable
char ch = 'A';

//Declare the pointer of type 'char'
char *cptr;

//Init the pointer to the address of 'ch'
cptr = &ch;

//Printing the address as well as the value through the pointer variable
printf("The value at address[cptr]: %p: %c\n", cptr, *cptr);

//Printing the address as well as the value through the normal variable
printf("The value at address[&ch]: %p: %c\n", &ch, *(&ch));

return 0;
}
fig-15.jpg

Figure-7: Output of code-2

So, from the above details, we can conclude that

  1. ‘cptr’ is the pointer variable, where 4 bytes of memory is allocated for it. (From Note-3)

  2. ‘cptr’ holds the address of the variable ‘ch’, pointing to the memory location where the value of ‘ch’ is stored.

  3. ‘*cptr’ gives the value present at that address, i.e the value contained in the variable ‘ch’. which is nothing but dereferencing the pointer.

  4. Deferencing the pointer(*cptr) means fetching 1 byte of memory at the location 1000, since the type of the pointer is ‘char’.

  5. After fetching 1 byte, it will interpret that data as the character.

The summary of example-2, is given in the table below,

table-8

Table-4

Example-3:

statement #1. double d = 125.78;

statement #2. double *dptr = &d;

Fig-16

Figure-8

From statement #1, ‘d’ is the double type variable assigned with the value 125.78, so sizeof(double) = 8 bytes, according to the IEEE format so 8 bytes of memory is allocated as shown above picture from the address 1000 onwards.

From the statement #2, dptr is the double pointer, where sizeof(pointer) = 4 bytes according to the assumption made, means 4 bytes of memory is alloacted for it and the value contained in it is the address of the ‘d’ variable. Now, dptr is pointing to the loaction in the memory whose value is 125.78.

Demo code-3 is shown below,

/***************************************************************************
* Demo code to show how to apply the pointer variables on double data type
* *************************************************************************/

#include <stdio.h>

int main()
{
//Definition of the variable
double d = 125.78;

//Declare the pointer of type 'double'
double *dptr;

//Init the pointer to the address of 'd'
dptr = &d;

//Printing the address as well as the value through the pointer variable
printf("The value at address[dptr]: %p: %lf\n", dptr, *dptr);

//Printing the address as well as the value through the normal variable
printf("The value at address[&d]: %p: %lf\n", &d, *(&d));

return 0;
}
code-5

Figure-9: Output of the above code-3

So, from the above details, we can conclude that

  1. ‘dptr’ is the pointer variable, where 4 bytes of memory is allocated for it. (From Note-6)

  2. ‘dptr’ holds the address of the variable ‘d’, pointing to the memory location where the value of ‘d’ is stored.

  3. ‘*dptr’ gives the value present at that address, i.e the value contained in the variable ‘d’. which is nothing but dereferencing the pointer.

  4. Deferencing the pointer(*dptr) means fetching 8 bytes of memory from the location 1000 onwards, since the type of the pointer is ‘double’.

  5. After fetching 8 byte, it will interpret that data as the double value.

The summary of example-3, is given in the table below,

table-9

Figure-5

Conclusion:-

  1. Type of the pointer should be exactly same as the data type of the variable.

  2. To get the address of the variable, referencing operator ( & ) is used, to get the value pointed by the pointer dereferencing operator ( * ) is used.

  3. *(&variable-name) = variable-name, since ‘*’ and ‘&’ cancels each other.

  4. ‘%p’ format specifier is used to print the address.

  5. When the pointer is declared, it is always safer to initialize it with the NULL, literal meaning is not to point anywhere.

This entry was posted in Bit-fields Structure, Pointer variable. Bookmark the permalink.

Leave a comment