Codeforwin

Pointers in C – Declare, initialize and use

Pointers are the heart of C programming. It is the most distinct feature of C, which provides power and flexibility to C. Pointers separates C from other programming languages.

C programmers make extensive use of pointers, because of their numerous benefits. Below are some advantages of pointers.

  • Pointers are more efficient in handling arrays and structures.
  • Pointers are used to return multiple values from a function.
  • We use pointers to get reference of a variable or function.
  • Pointer allows dynamic memory allocation (creation of variables at runtime) in C. Which undoubtedly is the biggest advantage of pointers.
  • Pointers increases execution speed of program.

Pointers are closely related to low level memory operations. Hence, let us first understand memory in contrast to C programming.

Understanding memory

Computer memory ( RAM ) is a collection of contiguous block of bytes. Where individual block is called as cell (memory cell). Each cell has a unique numeric address (also known as physical memory address) associated with it. These addresses starts from zero and runs up to maximum memory size (in bytes).

For example, memory location of a 64KB RAM starts from 0 and ends to 65536 (or 0x10000) bytes.

Memory representation

Before I formally introduce pointers let us first see what happens during a variable definition. Consider the statement int num = 10;

  • For the above statement, the C compiler allocates memory capable to store an integer. Let say memory is allocated at address 0x1200 .
  • After memory allocation , the C compiler defines a label (variable name) to access the memory location. The label is mapped to the allocated memory.
  • Finally, the constant 10 is stored at 0x1200 . Whenever you refer num inside your program, internally C refers to the memory location of num .

What is a pointer?

A pointer is a variable that stores memory address. If it is a variable, it must have a valid C data type . Yes, every pointer variable has a data type associated with it. Which means an integer pointer can hold only integer variable addresses.

Note: We never say pointer stores or holds a memory location. Instead, we say pointer points to a memory location. So from now always use the language pointer points to a memory location.

Reference operator &

Because we are dealing with memory addresses, we must know how to get memory address of a variable. We use unary & (reference of) operator to get memory address of a variable. Reference operator is also known as address of operator .

Read more about operators in C programming .

Syntax to use reference of operator

Example program to use reference operator.

Note: Output of above program may vary on your machine.

Dereference operator *

Once you have a memory address, you must be willing to get value stored at that memory address, for that we need to dereference the memory address.

Dereferencing is the process of retrieving value at memory location pointed by a pointer. We use unary * dereference operator to get value pointed by a memory address. Dereference operator is also known as indirection operator .

Syntax to use dereference operator

Example program to use dereference operator, how to declare pointer variable.

Once you got basics of memory addresses, reference and dereference operator. Let us declare our first pointer variable.

Pointer variable declaration follows almost similar syntax as of normal variable.

Syntax to declare pointer variable

  • data-type is a valid C data type .
  • * symbol specifies it is a pointer variable. You must prefix * before variable name to declare it as a pointer.
  • pointer-variable-name is a valid C identifier i.e. the name of pointer variable.

Example to declare pointer variable

In above example I declared an integer pointer.

How to initialize pointer variable

There are two ways to initialize a pointer variable. You can use reference operator & to get memory location of a variable or you can also directly assign one pointer variable to other pointer variable.

Examples to initialize pointer variable

How pointers are stored in memory.

You got a basic picture of pointer working. Let us take a closer look on how pointer variables are stored in memory. Consider the following statements

Pointer memory representation

Example program to use pointers

Write a C program to demonstrate the use of pointers in C programming.

Note: %x format specifier is used to print hexadecimal representation of a decimal .

Output –

Note: Output of above program may differ on your system.

Working of above program

  • int *ptr = # declares an integer pointer that points at num .
  • The first two printf() in line 12 and 13 are straightforward. First prints value of num and other prints memory address of num .
  • printf("Value of ptr = %x \n", ptr); prints the value stored at ptr i.e. memory address of num . Hence, the statement prints memory address of num .
  • printf("Value pointed by ptr = %d \n\n", *ptr); , here * dereferences value pointed by ptr and prints the value at memory location pointed by ptr .
  • Next, we made some changes to num i.e. num=10 . After changes printf("Value of num = %d \n", num); prints 10.
  • Since we made changes to our original variable num , hence changes are reflected back to pointer that points to the num . *ptr in line 23, dereferences value pointed by ptr i.e. 10.
  • *ptr = 100; says assign 100 to memory location pointed by ptr . Which means, assign 100 to num indirectly.
  • Since, we again modified the value of num using *ptr = 100 . Hence, num and *ptr in line 28 and 29 will evaluate to 100.

Recommended examples to practice

  • Program to demonstrate use of pointers.
  • Program to add two numbers using pointers.
  • Program to swap two numbers using pointers.

Pointers in C Explained – They're Not as Difficult as You Think

Srijan

Pointers are arguably the most difficult feature of C to understand. But, they are one of the features which make C an excellent language.

In this article, we will go from the very basics of pointers to their usage with arrays, functions, and structure.

So relax, grab a coffee, and get ready to learn all about pointers.

A. Fundamentals

  • What exactly are pointers?
  • Definition and Notation
  • Some Special Pointers
  • Pointer Arithmetic

B. Arrays and Strings

  • Why pointers and arrays?
  • Array of Pointers
  • Pointer to Array

C. Functions

  • Call by Value v/s Call by Reference
  • Pointers as Function Arguments
  • Pointers as Function Return
  • Pointer to Function
  • Array Of Pointers to Functions
  • Pointer to Function as an Argument

D. Structure

  • Pointer to Structure
  • Array of Structure
  • Pointer to Structure as an Argument

E. Pointer to Pointer

F. conclusion, a. definition, notation, types and arithmetic, 1. what exactly are pointers.

Before we get to the definition of pointers, let us understand what happens when we write the following code:

What exactly are pointers?

A block of memory is reserved by the compiler to hold an int value. The name of this block is digit and the value stored in this block is 42 .

Now, to remember the block, it is assigned with an address or a location number (say, 24650).

The value of the location number is not important for us, as it is a random value. But, we can access this address using the & (ampersand) or address of operator.

We can get the value of the variable digit from its address using another operator * (asterisk), called the indirection or dereferencing or value at address operator.

2. Definition and Notation

The address of a variable can be stored in another variable known as a pointer variable. The syntax for storing a variable's address to a pointer is:

For our digit variable, this can be written like this:

or like this:

This can be read as - A pointer to int (integer) addressOfDigit stores the address of(&) digit variable.

Few points to understand:

dataType – We need to tell the computer what the data type of the variable is whose address we are going to store. Here, int was the data type of digit .

It does not mean that addressOfDigit will store a value of type int . An integer pointer (like addressOfDigit ) can only store the address of variables of integer type.

* – A pointer variable is a special variable in the sense that it is used to store an address of another variable. To differentiate it from other variables that do not store an address, we use * as a symbol in the declaration.

Here, we can assign the address of variable1 and variable2 to the integer pointer addressOfVariables but not to variable3 since it is of type char . We will need a character pointer variable to store its address.

We can use our addressOfDigit pointer variable to print the address and the value of digit as below:

Here, *addressOfDigit can  be read as the value at the address stored in addressOfDigit .

Notice we used %d as the format identifier for addressOfDigit . Well, this is not completely correct. The correct identifier would be %p .

Using %p , the address is displayed as a hexadecimal value. But the memory address can be displayed in integers as well as octal values. Still, since it is not an entirely correct way, a warning is shown.

The output according to the compiler I'm using is the following:

This is the warning shown when you use  %d - " warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' ".

3. Some Special Pointers

The wild pointer.

When we defined our character pointer alphabetAddress , we did not initialize it.

Such pointers are known as wild pointers . They store a garbage value (that is, memory address) of a byte that we don't know is reserved or not (remember int digit = 42; , we reserved a memory address when we declared it).

Suppose we dereference a wild pointer and assign a value to the memory address it is pointing at. This will lead to unexpected behaviour since we will write data at a  memory block that may be free or reserved.

Null Pointer

To make sure that we do not have a wild pointer, we can initialize a pointer with a NULL value, making it a null pointer .

A null pointer points at nothing, or at a memory address that users can not access.

Void Pointer

A void pointer can be used to point at a variable of any data type. It can be reused to point at any data type we want to. It is declared like this:

Since they are very general in nature, they are also known as generic pointers .

With their flexibility, void pointers also bring some constraints. Void pointers cannot be dereferenced as any other pointer. Appropriate typecasting is necessary.

Similarly, void pointers need to be typecasted for performing arithmetic operations.

Void pointers are of great use in C. Library functions malloc() and calloc() which dynamically allocate memory return void pointers. qsort() , an inbuilt sorting function in C, has a function as its argument which itself takes void pointers as its argument.

Dangling Pointer

A dangling pointer points to a memory address which used to hold a variable. Since the address it points at is no longer reserved, using it will lead to unexpected results.

Though the memory has been deallocated by free(ptr) , the pointer to integer ptr still points to that unreserved memory address.

4. Pointer Arithmetic

We know by now that pointers are not like any other variable. They do not store any value but the address of memory blocks.

So it should be quite clear that not all arithmetic operations would be valid with them. Would multiplying or dividing two pointers ( having addresses ) make sense?

Pointers have few but immensely useful valid operations:

  • You can assign the value of one pointer to another only if they are of the same type (unless they're typecasted or one of them is void * ).

2.   You can only add or subtract integers to pointers.

When you add (or subtract) an integer (say n) to a pointer, you are not actually adding (or subtracting) n bytes to the pointer value. You are actually adding (or subtracting) n- times the size of the data type of the variable being pointed bytes.

The value stored in newAddress will not be 103, rather 112 .

3.   Subtraction and comparison of pointers is valid only if both are members of the same array. The subtraction of pointers gives the number of elements separating them.

4.  You can assign or compare a pointer with NULL .

The only exception to the above rules is that the address of the first memory block after the last element of an array follows pointer arithmetic.

Pointer and arrays exist together. These valid manipulations of pointers are immensely useful with arrays, which will be discussed in the next section.

1. Why pointers and arrays?

In C, pointers and arrays have quite a strong relationship.

The reason they should be discussed together is because what you can achieve with array notation ( arrayName[index] ) can also be achieved with pointers, but generally faster.

2. 1-D Arrays

Let us look at what happens when we write int myArray[5]; .

Five consecutive blocks of memory starting from myArray[0] to myArray[4] are created with garbage values in them. Each of the blocks is of size 4 bytes.

Thus, if the address of myArray[0] is 100 (say), the address of the rest of the blocks would be 104 , 108 , 112 , and 116 .

Have a look at the following code:

So, &prime , prime , and &prime[0] all give the same address, right? Well, wait and read because you are in for a surprise (and maybe some confusion).

Let's try to increment each of &prime , prime , and &prime[0] by 1.

Wait! How come &prime + 1 results in something different than the other two? And why are prime + 1 and &prime[0] + 1 still equal? Let's answer these questions.

prime and &prime[0] both point to the 0th element of the array prime . Thus, the name of an array is itself a pointer to the 0th element of the array .

Here, both point to the first element of size 4 bytes. When you add 1 to them, they now point to the 1st element in the array. Therefore this results in an increase in the address by 4.

&prime , on the other hand, is a pointer to an int array of size 5 . It stores the base address of the array prime[5] , which is equal to the address of the first element. However, an increase by 1 to it results in an address with an increase of 5 x 4 = 20 bytes.

In short, arrayName and &arrayName[0] point to the 0th element whereas &arrayName points to the whole array.

We can access the array elements using subscripted variables like this:

We can do the same using pointers which are always faster than using subscripts.

Both methods give the output:

Thus, &arrayName[i] and arrayName[i] are the same as arrayName + i and   *(arrayName + i) , respectively.

3. 2-D Arrays

Two-dimensional arrays are an array of arrays.

Here, marks can be thought of as an array of 5 elements, each of which is a one-dimensional array containing 3 integers. Let us work through a series of programs to understand different subscripted expressions.

Like 1-D arrays, &marks points to the whole 2-D array, marks[5][3] . Thus, incrementing to it by 1 ( = 5 arrays X 3 integers each X 4 bytes = 60) results in an increment by 60 bytes.

If marks was a 1-D array, marks and &marks[0] would have pointed to the 0th element. For a 2-D array, elements are now 1-D arrays . Hence, marks and &marks[0] point to the 0th array (element), and the addition of 1 point to the 1st array.

And now comes the difference. For a 1-D array, marks[0] would give the value of the 0th element. An increment by 1 would increase the value by 1.

But, in a 2-D array, marks[0] points to the 0th element of the 0th array. Similarly, marks[1] points to the 0th element of the 1st array. An increment by 1 would point to the 1st element in the 1st array.

This is the new part. marks[i][j] gives the value of the jth element of the ith array. An increment to it changes the value stored at marks[i][j] . Now, let us try to write marks[i][j] in terms of pointers.

We know marks[i] + j would point to the ith element of the jth array from our previous discussion. Dereferencing it would mean the value at that address. Thus, marks[i][j] is the same as   *(marks[i] + j) .

From our discussion on 1-D arrays, marks[i] is the same as *(marks + i) . Thus, marks[i][j] can be written as *(*(marks + i) + j) in terms of pointers.

Here is a summary of notations comparing 1-D and 2-D arrays.

Expression 1-D Array 2-D Array
&arrayName points to the address of whole array
adding 1 increases the address by 1 x sizeof(arrayName)
points to the address of whole array
adding 1 increases the address by 1 x sizeof(arrayName)
arrayName points to the 0th element
adding 1 increases the address to 1st element
points to the 0th element (array)
adding 1 increases the address to 1st element (array)
&arrayName[i] points to the the ith element
adding 1 increases the address to (i+1)th element
points to the ith element (array)
adding 1 increases the address to the (i+1)th element (array)
arrayName[i] gives the value of the ith element
adding 1 increases the value of the ith element
points to the 0th element of the ith array
adding 1 increases the address to 1st element of the ith array
arrayName[i][j] Nothing gives the value of the jth element of the ith array
adding 1 increases the value of the jth element of the ith array
Pointer Expression To Access The Elements *( arrayName + i) *( *( arrayName + i) + j)

A string is a one-dimensional array of characters terminated by a null(\0) . When we write char name[] = "Srijan"; , each character occupies one byte of memory with the last one always being \0 .

Similar to the arrays we have seen, name and &name[0] points to the 0th character in the string, while &name points to the whole string. Also, name[i] can be written as *(name + i) .

A two-dimensional array of characters or an array of strings can also be accessed and manipulated as discussed before.

5. Array of Pointers

Like an array of int s and an array of char s, there is an array of pointers as well. Such an array would simply be a collection of addresses. Those addresses could point to individual variables or another array as well.

The syntax for declaring a pointer array is the following:

Following the operators precedence , the first example can be read as -   example1 is an array( [] ) of 5 pointers to int . Similarly, example2 is an array of 8 pointers to char .

We can store the two-dimensional array to string top using a pointer array and save memory as well.

top will contain the base addresses of all the respective names. The base address of "Liverpool" will be stored in top[0] , "Man City" in top[1] , and so on.

In the earlier declaration, we required 90 bytes to store the names. Here, we only require ( 58 (sum of bytes of names) + 12 ( bytes required to store the address in the array) ) 70 bytes.

The manipulation of strings or integers becomes a lot easier when using an array of pointers.

If we try to put "Leicester" ahead of "Chelsea" , we just need to switch the values of top[3] and top[4] like below:

Without pointers, we would have to exchange every character of the strings, which would have taken more time. That's why strings are generally declared using pointers.

6. Pointer to Array

Like "pointer to int " or "pointer to char ", we have pointer to array as well. This pointer points to whole array rather than its elements.

Remember we discussed how &arrayName points to the whole array? Well, it is a pointer to array.

A pointer to array can be declared like this:

Notice the parentheses. Without them, these would be an array of pointers. The first example can be read as - ptr1 is a pointer to an array of 5 int (integers) .

When we dereference a pointer, it gives the value at that address. Similarly, by dereferencing a pointer to array, we get the array and the name of the array points to the base address. We can confirm that *pointerToGoals gives the array goals if we find its size.

If we dereference it again, we will get the value stored in that address. We can print all the elements using pointerToGoals .

Pointers and pointer to arrays are quite useful when paired up with functions. Coming up in the next section!

1. Call by Value vs Call by Reference

Have a look at the program below:

The function multiply() takes two int arguments and returns their product as int .

In the function call multiply(x,y) , we passed the value of x and y ( of main() ), which are actual arguments , to multiply() .

The values of the actual arguments are passed or copied to the formal arguments x and y ( of multiply() ). The x and y of multiply() are different from those of main() . This can be verified by printing their addresses.

Since we created stored values in a new location, it costs us memory. Wouldn't it be better if we could perform the same task without wasting space?

Call by reference helps us achieve this. We pass the address or reference of the variables to the function which does not create a copy. Using the dereferencing operator * , we can access the value stored at those addresses.

We can rewrite the above program using call by reference as well.

2. Pointers as Function Arguments

In this section, we will look at various programs where we give int , char , arrays and strings as arguments using pointers.

We created four functions, add() , subtract() , multiply() and divide() to perform arithmetic operations on the two numbers a and b .

The address of a and b was passed to the functions. Inside the function using * we accessed the values and printed the result.

Similarly, we can give arrays as arguments using a pointer to its first element.

Since the name of an array itself is a pointer to the first element, we send that as an argument to the function greatestOfAll() . In the function, we traverse through the array using loop and pointer.

Here, we pass in the string name to wish() using a pointer and print the message.

3. Pointers as Function Return

The function multiply() takes two pointers to int . It returns a pointer to int as well which stores the address where the product is stored.

It is very easy to think that the output would be 15. But it is not!

When multiply() is called, the execution of main() pauses and memory is now allocated for the execution of multiply() . After its execution is completed, the memory allocated to multiply() is deallocated.

Therefore, though c ( local to main() ) stores the address of the product, the data there is not guaranteed since that memory has been deallocated.

So does that mean pointers cannot be returned by a function? No!

We can do two things. Either store the address in the heap or global section or declare the variable to be static so that their values persist.

Static variables can simply be created by using the keyword static before data type while declaring the variable.

To store addresses in heap, we can use library functions malloc() and calloc() which allocate memory dynamically.

The following programs will explain both the methods. Both methods return the output as 15.

4. Pointer to Function

Like pointer to different data types, we also have a pointer to function as well.

A pointer to function or function pointer stores the address of the function. Though it doesn't point to any data. It points to the first instruction in the function.

The syntax for declaring a pointer to function is:

The below example will make it clearer.

The declaration for the pointer p to function multiply() can be read as ( following operator precedence ) - p is a pointer to function with two int eger pointers ( or two pointers to int ) as parameters and returning a pointer to int .

Since the name of the function is also a pointer to the function, the use of & is not necessary. Also removing * from the function call doesn't affect the program.

5. Array of Pointers to Functions

We have already seen how to create an array of pointers to int , char , and so on. Similarly, we can create an array of pointers to function.

In this array, every element will store an address of a function, where all the functions are of the same type. That is, they have the same type and number of parameters and return types.

We will modify a program discussed earlier in this section. We will store the addresses of add() , subtract() , multiply() and divide() in an array make a function call through subscript.

The declaration here can be read as - p is an array of pointer to functions with two float pointers as parameters and returning void .

6. Pointer to Function as an Argument

Like any other pointer, function pointers can also be passed to another function, therefore known as a callback function or called function . The function to which it is passed is known as a calling function .

A better way to understand would be to look at qsort() , which is an inbuilt function in C. It is used to sort an array of integers, strings, structures, and so on. The declaration for qsort() is:

qsort() takes four arguments:

  • a void pointer to the start of an array
  • number of elements
  • size of each element
  • a function pointer that takes in two void pointers as arguments and returns an int

The function pointer points to a comparison function that returns an integer that is greater than, equal to, or less than zero if the first argument is respectively greater than, equal to, or less than the second argument.

The following program showcases its usage:

Since a function name is itself a pointer, we can write compareIntegers as the fourth argument.

1. Pointer to Structure

Like integer pointers, array pointers, and function pointers, we have pointer to structures or structure pointers as well.

Here, we have declared a pointer ptrStudent of type struct records . We have assigned the address of student to ptrStudent .

ptrStudent stores the base address of student , which is the base address of the first member of the structure. Incrementing by 1 would increase the address by sizeof(student) bytes.

We can access the members of student using ptrStudent in two ways. Using our old friend * or using -> ( infix or arrow operator ).

With * , we will continue to use the . ( dot operator) whereas with -> we won't need the dot operator.

Similarly, we can access and modify other members as well. Note that the brackets are necessary while using * since the dot operator( . ) has higher precedence over * .

2. Array Of Structure

We can create an array of type struct records and use a pointer to access the elements and their members.

Note that ptrStudent1 is a pointer to student[0] whereas ptrStudent2 is a pointer to the whole array of  10 struct records . Adding 1 to ptrStudent1 would point to student[1] .

We can use ptrStudent1 with a loop to traverse through the elements and their members.

3. Pointer to Structure as an Argument

We can also pass the address of a structure variable to a function.

Note that the structure struct records is declared outside main() . This is to ensure that it is available globally and printRecords() can use it.

If the structure is defined inside main() , its scope will be limited to main() . Also structure must be declared before the function declaration as well.

Like structures, we can have pointers to unions and can access members using the arrow operator ( -> ).

So far we have looked at pointer to various primitive data types, arrays, strings, functions, structures, and unions.

The automatic question that comes to the mind is – what about pointer to pointer?

Well, good news for you! They too exist.

To store the address of int variable var , we have the pointer to int ptr_var . We would need another pointer to store the address of ptr_var .

Since ptr_var is of type int * , to store its address we would have to create a pointer to int * . The code below shows how this can be done.

We can use ptr_ptrvar to access the address of ptr_var and use double dereferencing to access var.

It is not required to use brackets when dereferencing ptr_ptrvar . But it is a good practice to use them. We can create another pointer ptr_ptrptrvar , which will store the address of ptr_ptrvar .

Since ptr_ptrvar is of type int** , the declaration for ptr_ptrptrvar will be

We can again access ptr_ptrvar , ptr_var and var using ptr_ptrptrvar .

If we change the value at any of the pointer(s) using ptr_ptrptrvar or ptr_ptrvar , the pointer(s) will stop pointing to the variable.

Phew! Yeah, we're finished. We started from pointers and ended with pointers (in a way). Don't they say that the curve of learning is a circle!

Try to recap all the sub-topics that you read. If you can recollect them, well done! Read the ones you can't remember again.

This article is done, but you shouldn't be done with pointers. Play with them. Next, you can look into Dynamic Memory Allocation to get to know pointers better .

Stay home, stay safe.

Sachin. Cricket. Dhoni. De Villiers. Buttler. In that order.

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Guru99

Pointers in C: What is Pointer in C Programming? Types

Benjamin Walker

What is Pointer in C?

The Pointer in C, is a variable that stores address of another variable. A pointer can also be used to refer to another pointer function. A pointer can be incremented/decremented, i.e., to point to the next/ previous memory location. The purpose of pointer is to save memory space and achieve faster execution time.

How to Use Pointers in C

If we declare a variable v of type int, v will actually store a value.

How to Use Pointers in C

v is equal to zero now.

However, each variable, apart from value, also has its address (or, simply put, where it is located in the memory). The address can be retrieved by putting an ampersand (&) before the variable name.

How to Use Pointers in C

If you print the address of a variable on the screen, it will look like a totally random number (moreover, it can be different from run to run).

Let’s try this in practice with pointer in C example

How to Use Pointers in C

The output of this program is -480613588.

Int *y = &v;

VARIABLE POINTER
A stored in a storage/memory address A that the storage/memory address of variable

Declaring a Pointer

Like variables, pointers in C programming have to be declared before they can be used in your program. Pointers can be named anything you want as long as they obey C’s naming rules. A pointer declaration has the following form.

  • data_type is the pointer’s base type of C’s variable types and indicates the type of the variable that the pointer points to.
  • The asterisk (*: the same asterisk used for multiplication) which is indirection operator, declares a pointer.

Let’s see some valid pointer declarations in this C pointers tutorial:

Initialize a pointer

After declaring a pointer, we initialize it like standard variables with a variable address. If pointers in C programming are not uninitialized and used in the program, the results are unpredictable and potentially disastrous.

To get the address of a variable, we use the ampersand (&)operator, placed before the name of a variable whose address we need. Pointer initialization is done with the following syntax.

Pointer Syntax

A simple program for pointer illustration is given below:

Operator Meaning
* Serves 2 purpose

& Serves only 1 purpose

Types of Pointers in C

Following are the different Types of Pointers in C :

Null Pointer

We can create a null pointer by assigning null value during the pointer declaration. This method is useful when you do not have any address assigned to the pointer. A null pointer always contains value 0.

Following program illustrates the use of a null pointer:

Void Pointer

In C programming , a void pointer is also called as a generic pointer. It does not have any standard data type. A void pointer is created by using the keyword void. It can be used to store an address of any variable.

Following program illustrates the use of a void pointer:

Wild pointer

A pointer is said to be a wild pointer if it is not being initialized to anything. These types of C pointers are not efficient because they may point to some unknown memory location which may cause problems in our program and it may lead to crashing of the program. One should always be careful while working with wild pointers.

Following program illustrates the use of wild pointer:

Other types of pointers in ‘c’ are as follows:

  • Dangling pointer
  • Complex pointer
  • Near pointer
  • Far pointer
  • Huge pointer

Direct and Indirect Access Pointers

In C, there are two equivalent ways to access and manipulate a variable content

  • Direct access: we use directly the variable name
  • Indirect access: we use a pointer to the variable

Let’s understand this with the help of program below

After compiling the program without any errors, the result is:

Pointer Arithmetic in C

The pointer operations are summarized in the following figure

Pointer Arithmetic in C

Priority operation (precedence)

When working with C pointers, we must observe the following priority rules:

  • The operators * and & have the same priority as the unary operators (the negation!, the incrementation++, decrement–).
  • In the same expression, the unary operators *, &,!, ++, – are evaluated from right to left.

If a P pointer points to an X variable, then * P can be used wherever X can be written.

The following expressions are equivalent:

Expression Equivalent Expression
Y=*P+1

*P=*P+10

*P+=2

++*P

(*P)++

Y=X+1

X=X+10

X+=2

++X

X++

In the latter case, parentheses are needed: as the unary operators * and ++ are evaluated from right to left, without the parentheses the pointer P would be incremented, not the object on which P points.

Below table shows the arithmetic and basic operation that can be used when dealing with C pointers

Operation Explanation
Assignment int *P1,*P2
P1=P2;
P1 and P2 point to the same integer variable
Incrementation and decrementation Int *P1;
P1++;P1– ;
Adding an offset (Constant) This allows the pointer to move N elements in a table.
The pointer will be increased or decreased by N times the number of byte (s) of the type of the variable.
P1+5;

C Pointers & Arrays with Examples

Traditionally, we access the array elements using its index, but this method can be eliminated by using pointers. Pointers make it easy to access each array element.

Adding a particular number to a pointer will move the pointer location to the value obtained by an addition operation. Suppose p is a pointer that currently points to the memory location 0 if we perform following addition operation, p+1 then it will execute in this manner:

C Pointers & Arrays

Since p currently points to the location 0 after adding 1, the value will become 1, and hence the pointer will point to the memory location 1.

C Pointers and Strings with Examples

A string is an array of char objects, ending with a null character ‘\ 0’. We can manipulate strings using pointers. This pointer in C example explains this section

Another way to deal strings is with an array of pointers like in the following program:

Advantages of Pointers in C

  • Pointers are useful for accessing memory locations.
  • Pointers provide an efficient way for accessing the elements of an array structure.
  • Pointers are used for dynamic memory allocation as well as deallocation.
  • Pointers are used to form complex data structures such as linked list, graph, tree, etc.

Disadvantages of Pointers in C

  • Pointers are a little complex to understand.
  • Pointers can lead to various errors such as segmentation faults or can access a memory location which is not required at all.
  • If an incorrect value is provided to a pointer, it may cause memory corruption.
  • Pointers are also responsible for memory leakage.
  • Pointers are comparatively slower than that of the variables.
  • Programmers find it very difficult to work with the pointers; therefore it is programmer’s responsibility to manipulate a pointer carefully.
  • A pointer is nothing but a memory location where data is stored.
  • A pointer is used to access the memory location.
  • There are various types of pointers such as a null pointer, wild pointer, void pointer and other types of pointers.
  • Pointers can be used with array and string to access elements more efficiently.
  • We can create function pointers to invoke a function dynamically.
  • Arithmetic operations can be done on a pointer which is known as pointer arithmetic.
  • Pointers can also point to function which make it easy to call different functions in the case of defining an array of pointers.
  • When you want to deal different variable data type, you can use a typecast void pointer.
  • Difference Between C and C++
  • C# vs C++: Difference Between Them
  • C Files I/O: Create, Open, Read, Write and Close a File
  • Functions in C Programming with Examples: Recursive & Inline
  • Functions Pointers in C Programming with Examples
  • Bitwise Operators in C: AND, OR, XOR, Shift & Complement
  • Top 50 COBOL Interview Questions (2024)
  • 21 Best C IDE (Editor) for Windows & Mac in 2024

Pointer Basics

Section 1 -- pointer rules, 1) pointers and pointees, 2) dereferencing, 3) pointer assignment, section 2 -- binky's code example.

1. Allocate two pointers and . Allocating the pointers allocate any pointees.
2. Allocate a pointee and set to point to it. Each language has its own syntax for this. What matters is that memory is dynamically allocated for one pointee, and is set to point to that pointee.
3. Dereference to store 42 in its pointee. This is a basic example of the dereference operation. Start at , follow the arrow over to access its pointee.
4. Try to dereference to store 13 in its pointee. This crashes because does not have a pointee -- it was never assigned one.
5. Assign so that points to 's pointee. Now and point to the same pointee -- they are "sharing".
6. Try to dereference to store 13 in its pointee. This time it works, because the previous assignment gave a pointee.

Java Version

C++ version, pascal version, section 3 -- study questions.

C Code Java Code

12.7 — Introduction to pointers

The most useful thing we can do with an address is access the value stored at that address. The dereference operator (*) (also occasionally called the indirection operator ) returns the value at a given memory address as an lvalue:

The address-of operator (&) and dereference operator (*) work as opposites: address-of gets the address of an object, and dereference gets the object at an address.

Although this is sometimes used as an argument to not place the asterisk with the type name (instead placing it next to the variable name), it’s a better argument for avoiding defining multiple variables in the same statement.

C Functions

C structures, c reference, creating pointers.

You learned from the previous chapter, that we can get the memory address of a variable with the reference operator & :

In the example above, &myAge is also known as a pointer .

A pointer is a variable that stores the memory address of another variable as its value.

A pointer variable points to a data type (like int ) of the same type, and is created with the * operator.

The address of the variable you are working with is assigned to the pointer:

Example explained

Create a pointer variable with the name ptr , that points to an int variable ( myAge ). Note that the type of the pointer has to match the type of the variable you're working with ( int in our example).

Use the & operator to store the memory address of the myAge variable, and assign it to the pointer.

Now, ptr holds the value of myAge 's memory address.

Dereference

In the example above, we used the pointer variable to get the memory address of a variable (used together with the & reference operator).

You can also get the value of the variable the pointer points to, by using the * operator (the dereference operator):

Note that the * sign can be confusing here, as it does two different things in our code:

  • When used in declaration ( int* ptr ), it creates a pointer variable .
  • When not used in declaration, it act as a dereference operator .

Good To Know: There are two ways to declare pointer variables in C:

Notes on Pointers

Pointers are one of the things that make C stand out from other programming languages, like Python and Java .

They are important in C, because they allow us to manipulate the data in the computer's memory. This can reduce the code and improve the performance. If you are familiar with data structures like lists, trees and graphs, you should know that pointers are especially useful for implementing those. And sometimes you even have to use pointers, for example when working with files and memory management .

But be careful ; pointers must be handled with care, since it is possible to damage data stored in other memory addresses.

C Exercises

Test yourself with exercises.

Create a pointer variable called ptr , that points to the int variable myAge:

Start the Exercise

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

Pointers are the basis for every complex data structure used in programming.  While this is not a data structures course, a basic understanding of pointers should assist you when you begin to view code that is not your own and likely implements several different types of data structures.

If you were to obtain access to a well written program that is related to your area of study, you will make two observations.

  • Everything is a user-defined TYPE.
  • Everything uses pointers.

A pointer is a variable that contains to data at all, instead, it c ontains an address in memory of another variable (that stores something useful).

  • Since a pointer is a variable (which is an object) it must also have a name.
  • Pointers will be used to not only work with dynamic memory needs, but dynamic storage structures.
  • Let's start simple first and let the focus of the bigger picture come to us through experience.

15.1 Pointers and Targets

Pointer Declaration

  • The type of the pointer must be declared even though the pointer contains no data of that type.
  • Instead, the pointer will store an address of a variable of that declared type.
  • Still don't see a need for the type?  Each data type (INTEGER, REAL, CHARACTER, or defined type) has a different set of data requirements.  We only want to "point" to enough memory of the type we wish to reference.
  • Pointers can point to user-defined types.

Pointers to Arrays

  • Pointers may also point to an array.
  • A pointer to an array is declared with a deferred-shape array, meaning that the rank of the array (number of dimensions) is specified but the actual extent of each dimension is not indicated.
  • A pointer can point to any variable or array of the pointer's type as long as the variable has been declared to be a TARGET.
  • A target is a data object whose address has been made available for use with pointers.
  • I've never seen anything like this before either!  But such is the way of FORTRAN! :)
  • The need for the TARGET attribute is based on the nature of FORTRAN compilers.
  • When memory is no longer needed for a variable (because the program is done with it) the memory is collected and permitted to be used by another variable (or other action requiring some memory). 
  • The optimizer of the compiler tries to identify variables that are no longer needed and free that memory unless an attribute like TARGET is listed and such a variable will be spared from the collection of unused (no longer used) variables.

15.1.1 Pointer Assignment Statements

A pointer can be associated with a given target by means of a pointer assignment .  A pointer assignment takes the form of:

Now the memory address of x has been stored in the pointer ptr .

Changing where a pointer points.

  • It is possible to switch to what a pointer points.  This is what is variable about a pointer, the address to which it points!
  • One pointer can also point the same place as another.  See above where r is reassigned to point to q ?

Does one pointer follow another?

15.1.2 Pointer Association Status (Are you a member of the Pointer Association?)

The association status of a pointer indicates whether or not the pointer currently points to a valid target. 

There are three states of association possible:

  • Undefined - an uninitialized pointer
  • Associated - a pointer assigned to valid target
  • How does one disassociate a pointer from its target?
  • NULLIFY(ptr)

A pointer can only be used to reference (or dereference) a target when it is associated with that target.  Any attempt to use a pointer when it is not associated with a target results in an error and the program aborts.

The ASSOCIATED Function

15.2 Using Pointers in Assignment Statements

Dereferencing Pointers and Assigning them to Other Pointers

  • The pointer b does not point anywhere valid, how can you send a value to nowhere?

Another Example

  • Overview of C
  • Features of C
  • Install C Compiler/IDE
  • My First C program
  • Compile and Run C program
  • Understand Compilation Process
  • C Syntax Rules
  • Keywords and Identifier
  • Understanding Datatypes
  • Using Datatypes (Examples)
  • What are Variables?
  • What are Literals?
  • Constant value Variables - const
  • C Input / Output
  • Operators in C Language
  • Decision Making
  • Switch Statement
  • String and Character array
  • Storage classes

C Functions

  • Introduction to Functions
  • Types of Functions and Recursion
  • Types of Function calls
  • Passing Array to function

C Structures

  • All about Structures
  • Pointers concept
  • Declaring and initializing pointer
  • Pointer to Pointer
  • Pointer to Array
  • Pointer to Structure
  • Pointer Arithmetic
  • Pointer with Functions

C File/Error

  • File Input / Output
  • Error Handling
  • Dynamic memory allocation
  • Command line argument
  • 100+ C Programs with explanation and output

Using Pointers in C

In this tutorial, we will learn how to declare, initialize and use a pointer in C language .

Before you continue, check these topics out:

Introduction to Pointers

C Loops - while , do while , for loops

A pointer is a variable used to store memory address. Hence, we have to declare and initialise(assign it a value) it just like any other variable. Pointers can be very useful in some use-cases, like:

  • They make accessing array elements easier.
  • We can implement linked lists, trees, and graphs using pointers.
  • We use pointers for accessing dynamically allocated memory.
  • We can return more than one value from a function using pointers.

So let's see how we can create pointers, assign values to pointers, perform pointer coversions, pointer arithmetic and pointer comparisons.

Declaring a Pointer in C

The general syntax of pointer declaration is,

Here, pointer_name is the name of the pointer and that should be a valid C identifier .

The datatype of the pointer and the variable to which the pointer variable is pointing must be the same.

Following are some examples of declaring a pointer in C:

Just like a variable, pointer is declared in the same way, just with an additional pointer operator * .

Assigning Value to a Pointer Variable

When we declare a pointer, it contains garbage value , which means it could be pointing anywhere in the memory. Pointer Initialization is the process of assigning the address of a variable to a pointer. In C language, the address operator & is used to determine the address of a variable. The & (immediately preceding a variable name) returns the address of the variable associated with it.

For example,

Value at ptr is: 10 Address pointed by ptr is: 0x7fff99c0e6c4

Run Code →

initialize pointer variable in C

Pointer variables must always point to variables of the same datatype.

For example, if we have a float type variable and an int type pointer, then C compiler will give error.

warning: assignment from incompatible pointer type ptr = &x; ^

While declaring a pointer variable, if it is not assigned to anything then it contains garbage value . And that can lead to unexpected errors in your program. Hence, it is recommended to assign a NULL value to it.

When we assign NULL to a pointer, it means that it does not point to any valid address. NULL denotes the value 'zero'.

set pointer variable value

A pointer that is assigned a NULL value is called a NULL pointer in C .

We can give a pointer a null value by assigning it zero to it. For example,

The above code will initialize the ptr pointer will a null value.

We can also use the NULL macro, which is nothing but a predefined constant for null pointer. This is defined in the <stdio.h> header library.

Pointer to Pointer Assignment in C

We can use an assignment operator to assign value of a pointer to another pointer variable. But for such assignment, types of both the pointer should be same.

Let's take a code example,

Value at p1 and p2: 10 10 Address pointed by p1 and p2: 0x7fff99c0e6c4 0x7fff99c0e6c4

As you can see in the code example above, multiple pointers can point to the same variable but they should be of the same data type.

Pointer Type Conversion in C

1. void * pointer.

The pointers of type void * are known as Generic pointers , and they can be assigned to any other type of pointer. Also, any other type of pointer can be assigned to a void * pointer.

2. Pointer type conversion

For pointer type other than void * , we have to explicitly cast pointer from one type to another. But this can lead to unexpected behaviour for incompatible datatypes.

For example, if we have a variable of type double , and we want to use a pointer of type int to point to this variable. Even after using explicit cast, the pointer will work as if it is pointing to a int type value. Now, a double type is of 8 bytes whereas an int type is of 4 bytes , hence, 4 bytes of information will be lost.

Let's see how we can use explicit cast for pointer conversion.

Value of a is: -858993459.000000

Pointer and Arrays

Derefrencing pointer in c.

Once a pointer has been assigned the address of a variable, the pointer is dereferenced , using the indirection operator or dereferencing operator , which is a * , to access the value of the variable.

For example, if we have,

Here is one complete program,

10 10 3795480300 3795480300 3795480304

Points to Remember while using Pointers

A pointer variable stores the address of a variable. We use * to declare and identify a pointer.

We can find the address of any variable using the & (ampersand) operator.

The declaration int *a doesn't mean that a is going to contain an integer value. It means that a is going to contain the address of a variable of int type.

We can dereference a pointer variable using a * operator. Here, the * can be read as 'value at' .

Since you have now learned the basics of Pointers in C, you can check out some C Pointer Programs where pointers are used for different use-cases.

Simple Pointer Program

Array of Pointer Program

What is Double Pointer?

Pointer with Function

  • ← Prev
  • Next →

Learn C practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c interactively, c introduction.

  • Getting Started with C
  • Your First C Program

C Fundamentals

  • C Variables, Constants and Literals
  • C Data Types
  • C Input Output (I/O)
  • C Programming Operators

C Flow Control

  • C if...else Statement
  • C while and do...while Loop
  • C break and continue
  • C switch Statement
  • C goto Statement
  • C Functions
  • C User-defined functions
  • Types of User-defined Functions in C Programming
  • C Recursion
  • C Storage Class

C Programming Arrays

  • C Multidimensional Arrays
  • Pass arrays to a function in C

C Programming Pointers

  • Relationship Between Arrays and Pointers
  • C Pass Addresses and Pointers
  • C Dynamic Memory Allocation
  • C Array and Pointer Examples

C Programming Strings

  • String Manipulations In C Programming Using Library Functions
  • String Examples in C Programming

C Structure and Union

C structs and Pointers

  • C Structure and Function

C Programming Files

  • C File Handling

C Files Examples

C Additional Topics

  • C Keywords and Identifiers
  • C Precedence And Associativity Of Operators
  • C Bitwise Operators
  • C Preprocessor and Macros
  • C Standard Library Functions

C Tutorials

  • Access Array Elements Using Pointer

Before you learn about the relationship between arrays and pointers, be sure to check these two topics:

An array is a block of sequential data. Let's write a program to print addresses of array elements.

There is a difference of 4 bytes between two consecutive elements of array x . It is because the size of int is 4 bytes (on our compiler).

Notice that, the address of &x[0] and x is the same. It's because the variable name x points to the first element of the array.

Relation between arrays and pointers

From the above example, it is clear that &x[0] is equivalent to x . And, x[0] is equivalent to *x .

  • &x[1] is equivalent to x+1 and x[1] is equivalent to *(x+1) .
  • &x[2] is equivalent to x+2 and x[2] is equivalent to *(x+2) .
  • Basically, &x[i] is equivalent to x+i and x[i] is equivalent to *(x+i) .

Example 1: Pointers and Arrays

When you run the program, the output will be:

Here, we have declared an array x of 6 elements. To access elements of the array, we have used pointers.

In most contexts, array names decay to pointers. In simple words, array names are converted to pointers. That's the reason why you can use pointers to access elements of arrays. However, you should remember that pointers and arrays are not the same .

There are a few cases where array names don't decay to pointers. To learn more, visit: When does array name doesn't decay into a pointer?

Example 2: Arrays and Pointers

In this example, &x[2] , the address of the third element, is assigned to the ptr pointer. Hence, 3 was displayed when we printed *ptr .

And, printing *(ptr+1) gives us the fourth element. Similarly, printing *(ptr-1) gives us the second element.

Table of Contents

  • Example 1: Arrays and pointers
  • Example 2: Arrays and pointers

Sorry about that.

Related Tutorials

CProgramming Tutorial

  • C Programming Tutorial
  • Basics of C
  • C - Overview
  • C - Features
  • C - History
  • C - Environment Setup
  • C - Program Structure
  • C - Hello World
  • C - Compilation Process
  • C - Comments
  • C - Keywords
  • C - Identifiers
  • C - User Input
  • C - Basic Syntax
  • C - Data Types
  • C - Variables
  • C - Integer Promotions
  • C - Type Conversion
  • C - Type Casting
  • C - Booleans
  • Constants and Literals in C
  • C - Constants
  • C - Literals
  • C - Escape sequences
  • C - Format Specifiers
  • Operators in C
  • C - Operators
  • C - Arithmetic Operators
  • C - Relational Operators
  • C - Logical Operators
  • C - Bitwise Operators
  • C - Assignment Operators
  • C - Unary Operators
  • C - Increment and Decrement Operators
  • C - Ternary Operator
  • C - sizeof Operator
  • C - Operator Precedence
  • C - Misc Operators
  • Decision Making in C
  • C - Decision Making
  • C - if statement
  • C - if...else statement
  • C - nested if statements
  • C - switch statement
  • C - nested switch statements
  • C - While loop
  • C - For loop
  • C - Do...while loop
  • C - Nested loop
  • C - Infinite loop
  • C - Break Statement
  • C - Continue Statement
  • C - goto Statement
  • Functions in C
  • C - Functions
  • C - Main Function
  • C - Function call by Value
  • C - Function call by reference
  • C - Nested Functions
  • C - Variadic Functions
  • C - User-Defined Functions
  • C - Callback Function
  • C - Return Statement
  • C - Recursion
  • Scope Rules in C
  • C - Scope Rules
  • C - Static Variables
  • C - Global Variables
  • Arrays in C
  • C - Properties of Array
  • C - Multi-Dimensional Arrays
  • C - Passing Arrays to Function
  • C - Return Array from Function
  • C - Variable Length Arrays
  • Pointers in C
  • C - Pointers
  • C - Pointers and Arrays
  • C - Applications of Pointers
  • C - Pointer Arithmetics
  • C - Array of Pointers
  • C - Pointer to Pointer
  • C - Passing Pointers to Functions
  • C - Return Pointer from Functions
  • C - Function Pointers
  • C - Pointer to an Array
  • C - Pointers to Structures
  • C - Chain of Pointers
  • C - Pointer vs Array
  • C - Character Pointers and Functions
  • C - NULL Pointer
  • C - void Pointer
  • C - Dangling Pointers
  • C - Dereference Pointer
  • C - Near, Far and Huge Pointers
  • C - Initialization of Pointer Arrays
  • C - Pointers vs. Multi-dimensional Arrays
  • Strings in C
  • C - Strings
  • C - Array of Strings
  • C - Special Characters
  • C Structures and Unions
  • C - Structures
  • C - Structures and Functions
  • C - Arrays of Structures
  • C - Self-Referential Structures
  • C - Lookup Tables
  • C - Dot (.) Operator
  • C - Enumeration (or enum)
  • C - Structure Padding and Packing
  • C - Nested Structures
  • C - Anonymous Structure and Union
  • C - Bit Fields
  • C - Typedef
  • File Handling in C
  • C - Input & Output
  • C - File I/O (File Handling)
  • C Preprocessors
  • C - Preprocessors
  • C - Pragmas
  • C - Preprocessor Operators
  • C - Header Files
  • Memory Management in C
  • C - Memory Management
  • C - Memory Address
  • C - Storage Classes
  • Miscellaneous Topics
  • C - Error Handling
  • C - Variable Arguments
  • C - Command Execution
  • C - Math Functions
  • C - Static Keyword
  • C - Random Number Generation
  • C - Command Line Arguments
  • C Programming Resources
  • C - Questions & Answers
  • C - Quick Guide
  • C - Cheat Sheet
  • C - Useful Resources
  • C - Discussion
  • Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Effective Resume Writing
  • HR Interview Questions
  • Computer Glossary

Pointer to Pointer (Double Pointer) in C

What is a double pointer in c.

A pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer.

A variable in C that stores the address of another variable is known as a pointer . A pointer variable can store the address of any type including the primary data types, arrays, struct types, etc. Likewise, a pointer can store the address of another pointer too, in which case it is called "pointer to pointer" (also called "double pointer" ).

A "pointer to a pointer" is a form of multiple indirection or a chain of pointers. Normally, a pointer contains the address of a variable. When we define a "pointer to a pointer", the first pointer contains the address of the second pointer, which points to the location that contains the actual value as shown below −

Pointer to Pointer

Declaration of Pointer to a Pointer

The declaration of a pointer to pointer ( double pointer ) is similar to the declaration of a pointer, the only difference is that you need to use an additional asterisk ( * ) before the pointer variable name.

For example, the following declaration declares a "pointer to a pointer" of type int −

When a target value is indirectly pointed to by a "pointer to a pointer", accessing that value requires that the asterisk operator be applied twice.

Example of Pointer to Pointer (Double Pointer)

The following example demonstrates the declaration, initialization, and using pointer to pointer (double pointer) in C:

How Does a Normal Pointer Work in C?

Assume that an integer variable "a" is located at an arbitrary address 1000. Its pointer variable is "b" and the compiler allocates it the address 2000. The following image presents a visual depiction −

Normal Pointer

Let us declare a pointer to int type and store the address of an int variable in it.

The dereference operator fetches the value via the pointer.

Here is the complete program that shows how a normal pointer works −

It will print the value of int variable, its address, and the value obtained by the dereference pointer −

How Does a Double Pointer Work?

Let us now declare a pointer that can store the address of "b", which itself is a pointer to int type written as "int *".

Let's assume that the compiler also allocates it the address 3000.

Double Pointer

Hence, "c" is a pointer to a pointer to int, and should be declared as "int **".

You get the value of "b" (which is the address of "a"), the value of "c" (which is the address of "b:), and the dereferenced value from "c" (which is the address of "a") −

Here, "c" is a double pointer. The first asterisk in its declaration points to "b" and the second asterisk in turn points to "a". So, we can use the double reference pointer to obtain the value of "a" from "c".

This should display the value of 'a' as 10.

Here is the complete program that shows how a double pointer works −

Run the code and check its output −

A Double Pointer Behaves Just Like a Normal Pointer

A "pointer to pointer" or a "double pointer" in C behaves just like a normal pointer. So, the size of a double pointer variable is always equal to a normal pointer.

We can check it by applying the sizeof operator to the pointers "b" and "c" in the above program −

This shows the equal size of both the pointers −

Note: The size and address of different pointer variables shown in the above examples may vary, as it depends on factors such as CPU architecture and the operating system. However, they will show consistent results.

Multilevel Pointers in C (Is a Triple Pointer Possible?)

Theoretically, there is no limit to how many asterisks can appear in a pointer declaration.

If you do need to have a pointer to "c" (in the above example), it will be a "pointer to a pointer to a pointer" and may be declared as −

Mostly, double pointers are used to refer to a two−dimensional array or an array of strings.

  • C++ Data Types
  • C++ Input/Output

C++ Pointers

  • C++ Interview Questions
  • C++ Programs
  • C++ Cheatsheet
  • C++ Projects
  • C++ Exception Handling
  • C++ Memory Management

Pointers are symbolic representations of addresses. They enable programs to simulate call-by-reference as well as to create and manipulate dynamic data structures. Iterating over elements in arrays or other data structures is one of the main use of pointers. 

The address of the variable you’re working with is assigned to the pointer variable that points to the same data type (such as an int or string).

How pointer works in C++

How to use a pointer?

  • Define a pointer variable
  • Assigning the address of a variable to a pointer using the unary operator (&) which returns the address of that variable.
  • Accessing the value stored in the address using unary operator (*) which returns the value of the variable located at the address specified by its operand.

The reason we associate data type with a pointer is that it knows how many bytes the data is stored in . When we increment a pointer, we increase the pointer by the size of the data type to which it points.

Pointers in C++

References and Pointers

There are 3 ways to pass C++ arguments to a function:

  • Call-By-Value
  • Call-By-Reference with a Pointer Argument
  • Call-By-Reference with a Reference Argument

In C++, by default arguments are passed by value and the changes made in the called function will not reflect in the passed variable. The changes are made into a clone made by the called function. If wish to modify the original copy directly (especially in passing huge object or array) and/or avoid the overhead of cloning, we use pass-by-reference. Pass-by-Reference with Reference Arguments does not require any clumsy syntax for referencing and dereferencing.

  • Function pointers in C
  • Pointer to a Function

Array Name as Pointers

An array name contains the address of the first element of the array which acts like a constant pointer. It means, the address stored in the array name can’t be changed. For example, if we have an array named val then val and &val[0] can be used interchangeably. 

Representation of data in memory

 If pointer ptr is sent to a function as an argument, the array val can be accessed in a similar fashion. Pointer vs Array

Pointer Expressions and Pointer Arithmetic

A limited set of arithmetic operations can be performed on pointers which are:

  • incremented ( ++ )
  • decremented ( — )
  • an integer may be added to a pointer ( + or += )
  • an integer may be subtracted from a pointer ( – or -= )
  • difference between two pointers (p1-p2)

( Note: Pointer arithmetic is meaningless unless performed on an array.) 

Representation of data in memory

Advanced Pointer Notation

Consider pointer notation for the two-dimensional numeric arrays. consider the following declaration

In general, nums[ i ][ j ] is equivalent to *(*(nums+i)+j)  

Pointer notation in C++

Pointers and String literals

String literals are arrays containing null-terminated character sequences. String literals are arrays of type character plus terminating null-character, with each of the elements being of type const char (as characters of string can’t be modified).

This declares an array with the literal representation for “geek”, and then a pointer to its first element is assigned to ptr. If we imagine that “geek” is stored at the memory locations that start at address 1800, we can represent the previous declaration as: 

Pointers and String Literals

As pointers and arrays behave in the same way in expressions, ptr can be used to access the characters of a string literal. For example:

Here, both x and y contain k stored at 1803 (1800+3).

Pointers to pointers

In C++, we can create a pointer to a pointer that in turn may point to data or another pointer. The syntax simply requires the unary operator (*) for each level of indirection while declaring the pointer.

Here b points to a char that stores ‘g’ and c points to the pointer b.

Void Pointers

This is a special type of pointer available in C++ which represents the absence of type. Void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties). This means that void pointers have great flexibility as they can point to any data type. There is a payoff for this flexibility. These pointers cannot be directly dereferenced. They have to be first transformed into some other pointer type that points to a concrete data type before being dereferenced. 

Invalid pointers

A pointer should point to a valid address but not necessarily to valid elements (like for arrays). These are called invalid pointers. Uninitialized pointers are also invalid pointers.

Here, ptr1 is uninitialized so it becomes an invalid pointer and ptr2 is out of bounds of arr so it also becomes an invalid pointer. (Note: invalid pointers do not necessarily raise compile errors)

NULL Pointers

A null pointer is a pointer that point nowhere and not just an invalid address. Following are 2 methods to assign a pointer as NULL;

Advantages of Pointers

  • Pointers reduce the code and improve performance. They are used to retrieve strings, trees, arrays, structures, and functions.
  • Pointers allow us to return multiple values from functions.
  • In addition to this, pointers allow us to access a memory location in the computer’s memory.

Related Articles:

  • Opaque Pointer
  • Near, Far and huge Pointers
  • Pointer Basics
  • Advanced Pointer

Please Login to comment...

Similar reads.

  • cpp-pointer

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Pointer to pointer assignment and dereference in C++

Let's say I have a linked list node like the following:

The goal is to write a function to delete a node in a singly-linked list. One efficient way to do it in constant time is something like this:

This works, but why do we need to dereference the pointers?

If node is a pointer and tmp is a pointer, why does it need to dereferenced? Why can't I do node = tmp ?

  • dereference

Adrian's user avatar

  • 1 Assigning to a function's (non-reference) parameter has no effect outside the function. There is nothing special about pointers. –  molbdnilo Commented Feb 4, 2021 at 15:47
  • If I understand it right, then you are actually copying the tmp_node to the current node, before you delete tmp. –  Devolus Commented Feb 4, 2021 at 15:48
  • If *node = *tmp does a copy of values, how I can just move node 's address (without any copy)? –  Adrian Commented Feb 4, 2021 at 15:51
  • "One efficient way to do it" I doubt it. Copying pointed-to objects instead of manipulating pointers is only efficient in cases of very small objects with non-complex assignment operators... With a pointer to the node preceeding the to be deleted one, things would be much more efficient. Please explain why that is not an option. –  Yunnosch Commented Feb 4, 2021 at 15:52
  • 3 @Adrian It is an immutable absolute rule in C++ that under no circumstance can the address of an object change. –  François Andrieux Commented Feb 4, 2021 at 15:52

8 Answers 8

When performing *node=*tmp you copy all the bytes of *tmp into *node thus node->val now holds tmp->val and node->next now holds tmp->next .

The old content of node has been forgotten (it's normal since you want to get rid of this node) but you saved the content of the next node at this same place. Then if you delete the next node (known through tmp ) you don't lose its content (it has been saved in the previous node).

prog-fh's user avatar

Let's break down the three lines of your deleteNode function:

This creates a local variable, tmp which will be a copy of the next field of the passed node parameter. This is a pointer to the next structure in the list and, once we've made a copy of it, we can erase or overwrite that member.

This copies the actual data of the structure pointed to by tmp (that is, the next node in the list) to the current node, overwriting the next field as it does so. We need to dereference both pointers in order to copy the values of the structures pointed to.

This deletes the 'next' node in the given list. However, we have already copied all its data (including its next member) into our current node, so our modified list now starts with (effectively) the second one in the original list (the passed parameter); notably, the next field of *node will now be the address originally stored in node->next->next – thus, we have 'skipped' an entry (the second) in the list and deleted it.

Adrian Mole's user avatar

The reason you can't just write node = tmp is because that wouldn't change anything outside of your function.

Given this linked list

If you want to delete node1, the desired outcome would be

If you don't want to actively modify the pointer value (that is, the address next ) in node0 , you have to move the value inside node2 to where node1 was.

OhadShwartzman's user avatar

Why can't I do node = tmp ?

You can do that, but it won't do anything useful. node is a local variable in deleteNode . As it is a pointer you can use that local pointer to modify what it points to, but modfying the pointer itself has no effect outside of the function.

Actually pointers are not different with respect to that. You also cannot observe any effect from outside when you have

Passing a reference is different:

Same with pointers:

463035818_is_not_an_ai's user avatar

If you do node = tmp and after that delete tmp you will be deleting the ListNode , which node points to.

Nikolay Karashtranov's user avatar

  • As others pointed out, node = tmp just changes the argument(local variable)
  • *node = *tmp is to copy the content of ListNode which is equivalent to node.val = tmp.val; node.next = tmp.next
  • This function actually removes the next element - it works, but it invalidates the next pointer(if there was something that refers node->next as a pointer, it is now a dangling pointer)

Hanjoung Lee's user avatar

  • I don't think the next pointer is dangling (because of point 2) –  prog-fh Commented Feb 4, 2021 at 16:07
  • Well, I mean it works, but should be careful when pointers are already used in other part of code. Probably we wouldn't expect a pointer to get invalidated when its prev node was deleted. –  Hanjoung Lee Commented Feb 4, 2021 at 16:16

What your function really does, is that it doesn't delete the node from the parameter, but the next node, overwriting the current node with the follower.

The dereferencing of the pointer acts like a memcpy() and moves the data from the next node to the current. You are not copying the pointers but the data it points to.

This way you can repeatedly call the function with the same node pointer, and it will move down the chain. However, since you are not checking the pointer, the last node probably has a NULL pointer and will crash on derefencing.

So you need to do

Devolus's user avatar

but why do we need to dereference the pointers?

Let's explore what happens if we don't indirect through the pointers:

This would be equivalent to just

So, we end up with wrong node being deleted, and with a dangling pointer in the node that was supposed to be deleted.

Note that even the correct inirecting version is broken when attempting to delete the last node.

eerorika's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c++ pointers dereference or ask your own question .

  • The Overflow Blog
  • Scaling systems to manage all the metadata ABOUT the data
  • Navigating cities of code with Norris Numbers
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites
  • Feedback requested: How do you use tag hover descriptions for curating and do...

Hot Network Questions

  • How would a culture living in an extremely vertical environment deal with dead bodies?
  • Why is this white line between the two vertical boxes?
  • Terminal autocomplete (tab) not completing when changing directory up one level (cd ../)
  • What's the airplane with the smallest wingspan to fuselage ratio?
  • Guitar amplifier placement for live band
  • Output of a Diffractometer
  • Finding the point that a sequence of midpoints converges to
  • tmux - How to remove delay after pressing prefix key and Up key
  • Dial “M” for murder
  • A short story where a space pilot has a device that sends the ship back in time just before losing a space battle. He is duplicated by accident
  • Cover letter format in Germany
  • Fisher claims Σ(x - λ)²/λ is chi-squared when x is Poisson – how is that?
  • How to handle stealth before combat starts?
  • Why HIMEM was implemented as a DOS driver and not a TSR
  • A study on the speed of gravity
  • If Venus had a sapient civilisation similar to our own prior to global resurfacing, would we know it?
  • Violation of the Law of Total Expectation in the Unit Square?
  • How predictable are the voting records of members of the US legislative branch?
  • Trace operation as contraction - how can we contract only contravariant indices?
  • Advice needed: Team needs developers, but company isn't posting jobs
  • Stargate "instructional" videos
  • Base change in Chriss-Ginzburg
  • Why does editing '/etc/shells' file using 'sudo open' shows an error saying I don't own the file?
  • Is there a "simplest" way to embed a graph in 3-space?

explain pointer assignment

IMAGES

  1. PPT

    explain pointer assignment

  2. Pointer Assignment || Lesson 61 || C Programming || Learning Monkey ||

    explain pointer assignment

  3. Pointer Assignment Detailed Explanation Made Easy Lec-61 Learning Monkey

    explain pointer assignment

  4. Pointer Assignment

    explain pointer assignment

  5. PPT

    explain pointer assignment

  6. Explain the Pointer in Deatil and Make Notes on them

    explain pointer assignment

COMMENTS

  1. C Pointers

    Comparison of pointers of the same type. Assignment of pointers of the same type. C // C program to illustrate Pointer Arithmetic #include <stdio.h> int main () ... So this article will firstly explain how cout behaves differently with character pointers, and then the reason and the working mechanism behind it will be discussed. Example 1: C ...

  2. C Pointers (With Examples)

    Explanation of the program. int* pc, c; Here, a pointer pc and a normal variable c, both of type int, is created. Since pc and c are not initialized at initially, pointer pc points to either no address or a random address. And, variable c has an address but contains random garbage value.; c = 22; This assigns 22 to the variable c.That is, 22 is stored in the memory location of variable c.

  3. Pointers in C

    Pointers are more efficient in handling arrays and structures. Pointers are used to return multiple values from a function. We use pointers to get reference of a variable or function. Pointer allows dynamic memory allocation (creation of variables at runtime) in C. Which undoubtedly is the biggest advantage of pointers.

  4. Pointers in C Explained

    Pointers are arguably the most difficult feature of C to understand. But, they are one of the features which make C an excellent language. In this article, we will go from the very basics of pointers to their usage with arrays, functions, and structure. ... The following programs will explain both the methods. Both methods return the output as 15.

  5. Pointers in C: What is Pointer in C Programming? Types

    A pointer is nothing but a memory location where data is stored. A pointer is used to access the memory location. There are various types of pointers such as a null pointer, wild pointer, void pointer and other types of pointers. Pointers can be used with array and string to access elements more efficiently.

  6. Pointer Arithmetics in C with Examples

    Note: Pointers can be outputted using %p, since, most of the computers store the address value in hexadecimal form using %p gives the value in that form. But for simplicity and understanding we can also use %u to get the value in Unsigned int form. 2. Addition of Integer to Pointer. When a pointer is added with an integer value, the value is first multiplied by the size of the data type and ...

  7. Pointer Basics

    Pointer assignment between two pointers makes them point to the same pointee. So the assignment y = x; makes y point to the same pointee as x. Pointer assignment does not touch the pointees. It just changes one pointer to have the same reference as another pointer. After pointer assignment, the two pointers are said to be "sharing" the pointee.

  8. 12.7

    Pointers and assignment. We can use assignment with pointers in two different ways: To change what the pointer is pointing at (by assigning the pointer a new address) To change the value being pointed at (by assigning the dereferenced pointer a new value) First, let's look at a case where a pointer is changed to point at a different object:

  9. Pointer Expressions in C with Examples

    Pointer Arithmetic is the set of valid arithmetic operations that can be performed on pointers. The pointer variables store the memory address of another variable. It doesn't store any value. Hence, there are only a few operations that are allowed to perform on Pointers in C language. The C pointer arithmetic operations are slightly different from

  10. C Pointers

    Example explained. Create a pointer variable with the name ptr, that points to an int variable (myAge).Note that the type of the pointer has to match the type of the variable you're working with (int in our example).Use the & operator to store the memory address of the myAge variable, and assign it to the pointer.. Now, ptr holds the value of myAge's memory address.

  11. Pointers in C Programming with examples

    By using * operator we can access the value of a variable through a pointer. For example: double a = 10; double *p; p = &a; *p would give us the value of the variable a. The following statement would display 10 as output. printf("%d", *p); Similarly if we assign a value to *pointer like this: *p = 200;

  12. Pointers

    A pointer is a variable that contains to data at all, instead, it c ontains an address in memory of another variable (that stores something useful). Since a pointer is a variable (which is an object) it must also have a name. Pointers will be used to not only work with dynamic memory needs, but dynamic storage structures.

  13. Using Pointers in C

    The general syntax of pointer declaration is, type *pointer_name; Here, pointer_name is the name of the pointer and that should be a valid C identifier. The datatype of the pointer and the variable to which the pointer variable is pointing must be the same. Following are some examples of declaring a pointer in C:

  14. Pointers in C

    The general form of a pointer variable declaration is −. type *var-name; Here, type is the pointer's base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for multiplication. However, in this statement the asterisk is being used to ...

  15. How to explain C pointers (declaration vs. unary operators) to a

    To explain the pointer to a beginner, the meaning of * symbol in different context should be explained. In the declaration. int *bar = &foo; the * symbol is not the indirection operator. Instead, it helps to specify the type of bar informing the compiler that bar is a pointer to an int.

  16. Relationship Between Arrays and Pointers

    In most contexts, array names decay to pointers. In simple words, array names are converted to pointers. That's the reason why you can use pointers to access elements of arrays. However, you should remember that pointers and arrays are not the same. There are a few cases where array names don't decay to pointers.

  17. C

    The pointer to a pointer in C is used when we want to store the address of another pointer. The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double-pointers. We can use a pointer to a pointer to change the values of normal ...

  18. Pointer to Pointer (Double Pointer) in C

    A "pointer to pointer" or a "double pointer" in C behaves just like a normal pointer. So, the size of a double pointer variable is always equal to a normal pointer. We can check it by applying the sizeof operator to the pointers "b" and "c" in the above program −. This shows the equal size of both the pointers −.

  19. Different ways to assign pointer in C , using & or

    The type of int* is "pointer to an int", while, again, the type of int& (C++ only) is int. It modifies the type. int *p = NULL; //p is a pointer to an int, that currently points to nothing. int f(int & x); //f is a function that takes in an int by reference & in front of an existing variable means "a pointer to", or "address of". It's an ...

  20. C++ Pointers

    The reason we associate data type with a pointer is that it knows how many bytes the data is stored in. When we increment a pointer, we increase the pointer by the size of the data type to which it points. C++. // C++ program to illustrate Pointers #include <bits/stdc++.h> using namespace std; void geeks() { int var = 20; // declare pointer ...

  21. Pointer to pointer assignment and dereference in C++

    1. Let's break down the three lines of your deleteNode function: auto *tmp = node->next; This creates a local variable, tmp which will be a copy of the next field of the passed node parameter. This is a pointer to the next structure in the list and, once we've made a copy of it, we can erase or overwrite that member.