Pointers in C

Pointers in C

In this article, I am going to discuss Pointers in C Language with Examples. Please read our previous articles, where we discussed Strings in C. As part of this article, you will learn what is Pointers in C, it’s type, and when and how to use Pointers in C Program with examples.

What are Pointers in C?

A Pointer is a derived data type in C which is constructed from the fundamental data type of C Language. A pointer is a variable that holds the address of another variable. A pointer can be defined as it is a memory variable that stores a memory address. It is denoted by ‘*’ operator.

What are the Advantages of using Pointers in C Langauge?
  1. Data access: C programming language is a procedure-oriented language i.e. applications are developed by using functions. From one function to another function, when we required to access the data, a pointer is required.
  2. Memory Management: By using pointers only, dynamic memory allocation is possible i.e. we can handle runtime memory management.
  3. Database/ Data structures: By using pointer we can handle the data structure more efficiently. Any kind of data structures required to develop by using pointers only, if data structures are not available then the database is not possible to create.
  4. Performance: By using pointers, we can increase the execution speed of the program.
  5. By using a pointer, we can access the data which is available outside of the function.
Operators used in Pointer:

When we are working with the pointer, we need to use the following two operators.

  1. * (Indirection operator or dereference operator or object at location or value at address)
  2. & (address-of operator)
& (address-of operator):

The & is a unary operator. The address of operator always returns the base address of a variable. The starting cell address of any variable is called the base address.

* (Indirection operator):

The Indirection (*) Operator is a unary operator. It is used to create a pointer variable. Indirection Operator always returns the value of an address, i.e. what address we are passing, from that address corresponding value will be retrieved.

Declaration of Pointer:

Syntax: Datatype *ptr_name;
Example: int *p;
Here, the * mark before the variable indicates that it is a pointer variable. Indirection operators must be required between datatype and variable name. Space is not mandatory to place in the declaration of the pointer variable.

Initialization of Pointer:

Syntax:
Datatype variable;
Datatype *ptr = &variable;

Example:
void main()
{
 int i;
 Int * ptr;
}

Here, i is a variable of type integer and it is a value type variable that always holds an integer value. ptr is a variable of type int* and it is an address type variable that always holds an integer variable address.

Program:
#include <stdio.h>
int main()
{
    int a;
    printf("Enter a Number: ");
    scanf("%d", &a);
    printf("Entered Value is %d: ", a);
    printf("\n");
    printf("The Address is %d: ", &a);
    return 0;
}

Output:

What is Pointer in C?

Example to show the use of pointer
#include<stdio.h>
int main ()
{
    int a;
    int *ptr;
    ptr = &a;
    a = 10;
    printf ("\n %p %p", &a, ptr);
    printf ("\n %d %d", a, *ptr);
    *ptr = 20;
    printf ("\n %u %u", &a, ptr);
    printf ("\n %d %d", a, *ptr);
    return 0;
}

Output:

Example to show the use of pointer

On any variable when we are applying address-of operator (&) then always it will collect the base address only i.e. the starting cell location. On address when we are applying indirection operator (*) then it returns the value of that address.

In the above program, ptr holds the address of a (&a) that’s why ptr and & value are the same. *ptr always returns object i.e. value that’s why ‘*ptr’ and ‘a’ value are the same.

In implementation when we are printing the address of the variable then go for %x, %p, %u. %lu and %lp format specifiers. %x, %p, %lp will print the address in hexadecimal format, and %u, %lu will print the address in decimal format.

Note: For printing the address we cannot use the %d format specifier because the physical address will be there in hexadecimal format from the range of 0*0000 to 0*ffff, in decimal format 0 to 65535 so this range will not be supported by %d. There is no –ve representation are available in physical address but %d will print –ve data also,

Example to show the difference between %p and %x
#include<stdio.h>
int main ()
{
    int a;
    int *ptr;
    ptr = &a;
    a = 11;
    printf ("\n %p %p", &a, ptr);
    printf ("\n %d %d", a, *ptr);
    *ptr = 22;
    printf ("\n %x %x", &a, ptr);
    printf ("\n %d %d", a, *ptr);
    return 0;
}

Output:

Example to show the difference between %p and %x

What will be the output in the below program?
#include<stdio.h>
int main ()
{
    int a, b;
    int *ptr;
    ptr = &a;
    a = 10;
    b = 20;
    printf ("\n %d %d %d", a, b, *ptr);
    *ptr = 30;
    ptr = &b;
    *ptr = 40;
    printf ("\n %d %d %d", a, b, *ptr);
    return 10;
}

Output:

C Pointers Example

Note: in implementation when we need to change the pointer location from one variable to another variable than by re-assigning the address to the pointer, we can change the pointer location.

Data Access mechanism using Pointers in C Language:

Different types of variables are having different types of sizes because internal content is different. Any type of pointer having the same size only because internal content is the address which is common for any type of variable.

Any kind of pointer can hold any kind of variable address but at the time of manipulating the data, we see the difference. In implementation when we need to hold an integer variable address then go for int *, float variable address then go for float * and for char variable address go for char * only.

DOS Operating system doesn’t have any memory management that’s why at run time addresses are limited. On the DOS-based compiler, the size of the pointer is 2 bytes because the address is limited. Windows, Unix, and Linux OS are having proper memory management that’s why the address is not limited (depends on RAM capacity). On a windows-based compiler, the size of the pointer is 4 bytes because addresses are unlimited. On 64-bit OS, when we are using a 64-bit compiler then the size of pointer is 8 bytes. On 32-bit OS, we are using a 16-bit compiler then the size of pointer is 2 bytes. On 64-bit OS, 16-bit compiler is not compatible only 32-bit & 64-bit compiler will work.

Any type of pointer size is 2 bytes only because it maintains the offset address from the range of 0X0000 to 0XFFFF, so for holding this many addresses we require 2 data. Any type of pointer holds single-cell info only i.e. Base address, but data can be present in multiple cells. On address when we are applying indirection operator then its deference to a pointer type, so depending on pointer type given base address (n no. of bytes will be accessed). In C programming language, any type of pointer can hold, any kind of variable address because the address doesn’t maintain any type of information. In implementation when we are manipulating an integer variable then go for an int*, float variable float* and character variable is char* because we can see the difference when we are applying indirection operator.

Program:
#include<stdio.h>
int main ()
{
    int a, b;
    char *ptr;
    ptr = &a;
    a = 32767;
    b = *ptr;
    printf ("%d %d %d", a, b, *ptr);
    *ptr = 0;
    printf ("\n%d %d %d", a, b, *ptr);
    return 0;
}

Output:

Data Access mechanism using Pointers

On integer variable, when we are applying char pointer, then it can access and manipulate only 1byte data because indirection operator behavior is datatype dependent.

Program:
#include<stdio.h>
int main ()
{
    int a, b;
    char *ptr;
    ptr = &a;
    a = 543;
    b = *ptr;
    printf ("%d %d %d", a, b, *ptr);
    *ptr = 255;
    printf ("\n%d %d %d ", a, b, *ptr);
    return 0;
}

Output:

What are the Advantages of using Pointers in C?

All integer variable, when we are applying char ptr then always it will access low order byte data only. When we are working with 2 bytes integers, then 1st byte is called low order byte and 2nd-byte data is called high order byte. 

Example:
#include<stdio.h>
int main ()
{
    int a, b;
    char *ptr;
    ptr = &a;
    a = 511;
    b = *ptr;
    printf ("\n %d %d %d", a, b, *ptr);
    *ptr = 10;
    printf ("\n %d %d %d", a, b, *ptr);
    return 0;
}

Output:

when and how to use Pointers in C Program

Note: we can see this difference in Turbo-c but in the case of GCC and devC it will give the compile-time error.

Types of Pointer in C Language:

Depending on memory management model pointers are classified into 3 types:

  1. Near Pointer
  2. Far Pointer
  3. Huge Pointer
Near Pointer:

The pointer variable which can handle only 1 segment of 1MB data it is called near pointer. Near pointer doesn’t point to any other segments except the data segment. The size of the near pointer is 2 bytes. When we are incrementing the near pointer value then it increments offset address only. When we are applying the relational operators on near pointer then it compares offset address only. By default, any type of pointer is near only. When we are printing the address, by using near pointer, then we required to use %d or %x or %u format specifier only. By using the near keyword, we can create near the pointer.

Far Pointer:

The pointer variable which can handle any segment of 1MB data is called far pointer. When we are working with the far pointer, it can handle any segment from the range of 0X0-0XF, but at a time only one segment. The size of the far pointer is 4bytes because it holds segment & offset address also. When we are incrementing the far pointer value, then it increases offset address only. When we are applying a relational operator on the far pointer then it compares the segment address along with offset address. When we are printing the address by using far pointer then we required to use %lp or %lu format specifier. By using far keyword, we can create a far pointer.

Huge Pointer:

The pointer variable which can handle any segment of 1MB data is called huge pointer. When we are working with a huge pointer, it can handle any segment from the range of 0X0-0XF, but at a time only 1 segment. When we are working with a huge pointer, then it occupies 4B of memory because it holds segment & offset address also. When we are incrementing the huge pointer value, then it increases the segment address along with the offset address. When we are comparing the huge pointer, it compares normalization value. When we are printing the address by using a huge pointer then we required to use %lp or %lu format specifier. By using the huge keyword, we can create a huge pointer.

In the next article, I am going to discuss Arithmetic Operations on Pointers in C language. Here, in this article, I try to explain Pointers in C Langauge with examples. I hope you enjoy this Pointers in C Language article. I would like to have your feedback. Please post your feedback, question, or comments about this Pointers in C Language article.

Leave a Reply

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