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.

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

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

Pointers are powerful features of C and C++ programming. Before we learn pointers, let's learn about addresses in C programming.

  • Address in C

If you have a variable var in your program, &var will give you its address in the memory.

We have used address numerous times while using the scanf() function.

Here, the value entered by the user is stored in the address of var variable. Let's take a working example.

Note: You will probably get a different address when you run the above code.

Pointers (pointer variables) are special variables that are used to store addresses rather than values.

Pointer Syntax

Here is how we can declare pointers.

Here, we have declared a pointer p of int type.

You can also declare pointers in these ways.

Let's take another example of declaring pointers.

Here, we have declared a pointer p1 and a normal variable p2 .

  • Assigning addresses to Pointers

Let's take an example.

Here, 5 is assigned to the c variable. And, the address of c is assigned to the pc pointer.

Get Value of Thing Pointed by Pointers

To get the value of the thing pointed by the pointers, we use the * operator. For example:

Here, the address of c is assigned to the pc pointer. To get the value stored in that address, we used *pc .

Note: In the above example, pc is a pointer, not *pc . You cannot and should not do something like *pc = &c ;

By the way, * is called the dereference operator (when working with pointers). It operates on a pointer and gives the value stored in that pointer.

  • Changing Value Pointed by Pointers

We have assigned the address of c to the pc pointer.

Then, we changed the value of c to 1. Since pc and the address of c is the same, *pc gives us 1.

Let's take another example.

Then, we changed *pc to 1 using *pc = 1; . Since pc and the address of c is the same, c will be equal to 1.

Let's take one more example.

Initially, the address of c is assigned to the pc pointer using pc = &c; . Since c is 5, *pc gives us 5.

Then, the address of d is assigned to the pc pointer using pc = &d; . Since d is -15, *pc gives us -15.

  • Example: Working of Pointers

Let's take a working example.

Explanation of the program

A pointer variable and a normal variable is created.

Common mistakes when working with pointers

Suppose, you want pointer pc to point to the address of c . Then,

Here's an example of pointer syntax beginners often find confusing.

Why didn't we get an error when using int *p = &c; ?

It's because

is equivalent to

In both cases, we are creating a pointer p (not *p ) and assigning &c to it.

To avoid this confusion, we can use the statement like this:

Now you know what pointers are, you will learn how pointers are related to arrays in the next tutorial.

Table of Contents

  • What is a pointer?
  • Common Mistakes

Sorry about that.

Related Tutorials

DEV Community

DEV Community

AbdulKarim

Posted on Oct 29, 2023

How C-Pointers Works: A Step-by-Step Beginner's Tutorial

In this comprehensive C Pointers tutorial, my primary goal is to guide you through the fundamentals of C pointers from the ground up. By the end of this tutorial, you will have gained an in-depth understanding of the following fundamental topics:

  • What is a Pointer?
  • How Data is Stored in Memory?
  • Storing Memory Addresses using Pointers

Accessing Data through Pointers

  • Pointer Arithmetic
  • Pointer to Pointer (Double Pointers)
  • Passing Pointers as Function Arguments

Arrays of Pointers

Null pointers, prerequisite:.

To grasp pointers effectively, you should be comfortable with basic C programming concepts, including variables, data types, functions, loops, and conditional statements. This familiarity with C programming forms the foundation for understanding how pointers work within the language. Once you have a solid grasp of these fundamental concepts, you can confidently delve into the intricacies of C pointers.

What is a pointer?

A pointer serves as a reference that holds the memory location of another variable. This memory address allows us to access the value stored at that location in the memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory

Pointers can be a challenging concept for beginners to grasp, but in this tutorial, I'll explain them using real-life analogies to make the concept clearer. However, Before delving into pointers and their workings, it's important to understand the concept of a memory address.

A memory address is a unique identifier that points to a specific location in a computer's memory. Think of it like a street address for data stored in your computer's RAM (Random Access Memory). Just as a street address tells you where a particular house is located in the physical world, a memory address tells the computer where a specific piece of information or data is stored in its memory.

Take a look at the image below for a better understanding:

Block of memory

In this illustration, each block represents one byte of memory. It's important to note that every byte of memory has a unique address. To make it easier to understand, I've represented the addresses in decimal notation, but computers actually store these addresses using hexadecimal values. Hexadecimal is a base-16 numbering system commonly used in computing to represent memory addresses and other low-level data. It's essential to be aware of this representation when working with memory-related concepts in computer programming

How data is stored in the memory:

Every piece of data in your computer, whether it's a number, a character, or a program instruction, is stored at a specific memory address. The amount of space reserved for each data type can vary, and it is typically measured in bytes (where 1 byte equals 8 bits, with each bit representing either 0 or 1). The specific sizes of data types also depend on the computer architecture you are using. For instance, on most 64-bit Linux machines, you'll find the following typical sizes for common data types: char = 1 byte int = 4 bytes float = 4 bytes double = 8 bytes These sizes define how much memory each data type occupies and are crucial for memory management and efficient data representation in computer systems.

You can use the sizeof operator to determine the size of data types on your computer. example:

In this example: sizeof(char) returns the size of the char data type in bytes. sizeof(int) returns the size of the int data type in bytes. sizeof(float) returns the size of the float data type in bytes. sizeof(double) returns the size of the double data type in bytes. When you run this code, it will print the sizes of these data types on your specific computer, allowing you to see the actual sizes used by your system.

When you declare a variable, the computer allocates a specific amount of memory space corresponding to the chosen data type. For instance, when you declare a variable of type char, the computer reserves 1 byte of memory because the size of the 'char' data type is conventionally 1 byte.

address of char n

In this example, we declare a variable n of type char without assigning it a specific value. The memory address allocated for the n variable is 106 . This address, 106 , is where the computer will store the char variable n, but since we haven't assigned it a value yet, the content of this memory location may initially contain an unpredictable or uninitialized value.

When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n. When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n.

address of cahr n = c

As mentioned earlier, a byte can only store numerical values. When we store the letter 'C' in a byte, the byte actually holds the ASCII code for 'C,' which is 67. In computer memory, characters are represented using their corresponding ASCII codes. So, in memory, the character 'C' is stored as the numerical value 67. Here's how it looks in memory

Ascii code of c

Since integers are typically stored within four bytes of memory, let's consider the same example with an int variable. In this scenario, the memory structure would appear as follows:

add. of int t

In this example, the memory address where the variable t is stored is 121. An int variable like “t” typically uses four consecutive memory addresses, such as 121, 122, 123, and 124. The starting address, in this case, 121, represents the location of the first byte of the int, and the subsequent addresses sequentially represent the following bytes that collectively store the complete int value.

If you want to know the memory address of a variable in a program, you can use the 'address of' unary operator, often denoted as the '&' operator. This operator allows you to access the specific memory location where a variable is stored.

When you run the following program on your computer: It will provide you with specific memory addresses for the variables c and n. However, each time you rerun the program, it might allocate new memory addresses for these variables. It's important to understand that while you can determine the memory address of a variable using the & operator, the exact memory location where a variable is stored is typically managed by the system and the compiler. As a programmer, you cannot directly control or assign a specific memory location for a variable. Instead, memory allocation and management are tasks handled by the system and the compiler.

Storing memory address using pointers

As mentioned earlier, a pointer is a variable that stores the memory address of another variable. This memory address allows us to access the value stored at that location in memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory.

Now, let's begin by declaring and initializing pointers. This step is essential because it sets up the pointer to hold a specific memory address, enabling us to interact with the data stored at that location.

Declaring Pointers: To declare a pointer, you specify the data type it points to, followed by an asterisk (*), and then the pointer's name. For example:

Here, we've declared a pointer named ptr that can point to integers.

Memory of Declaring an integer pointer

The size of pointers on 64-bit systems is usually 8 bytes (64 bits). To determine the pointer size on your system, you can use the sizeof operator:

Initializing Pointers: Once you've declared a pointer, you typically initialize it with the memory address it should point to. Once again, To obtain the memory address of a variable, you can employ the address-of operator (&). For instance:

In this program:

We declare an integer variable x and initialize it with the value 10. This line creates a variable x in memory and assigns the value 10 to it.

ptr

We declare an integer pointer ptr using the int *ptr syntax. This line tells the compiler that ptr will be used to store the memory address of an integer variable.

pointrt to ptr

We initialize the pointer ptr with the memory address of the variable x . This is achieved with the line ptr = &x; . The & operator retrieves the memory address of x, and this address is stored in the pointer ptr .

address of variable x

Dereferencing Pointers: To access the data that a pointer is pointing to, you need to dereference the pointer. Dereferencing a pointer means accessing the value stored at the memory address that the pointer points to. In C, you can think of pointers as variables that store memory addresses rather than actual values. To get the actual value (data) stored at that memory address, you need to dereference the pointer.

Dereferencing is done using the asterisk (*) operator. Here's an example:

It looks like this in the memory: int x = 10; variable 'x' stores the value 10:

var X

int *ptr = &x; Now, the pointer 'ptr' point to the address of 'x':

Pointer to X

int value = *ptr; Dereference 'ptr' to get the value stored at the address it points to:

pointer value is 10

Reading and Modifying Data: Pointers allow you to not only read but also modify data indirectly:

Note: The asterisk is a versatile symbol with different meanings depending on where it's used in your C program, for example: Declaration: When used during variable declaration, the asterisk (*) indicates that a variable is a pointer to a specific data type. For example: int *ptr; declares 'ptr' as a pointer to an integer.

Dereferencing: Inside your code, the asterisk (*) in front of a pointer variable is used to access the value stored at the memory address pointed to by the pointer. For example: int value = *ptr; retrieves the value at the address 'ptr' points to.

Pointer Arithmetic:

Pointer arithmetic is the practice of performing mathematical operations on pointers in C. This allows you to navigate through arrays, structures, and dynamically allocated memory. You can increment or decrement pointers, add or subtract integers from them, and compare them. It's a powerful tool for efficient data manipulation, but it should be used carefully to avoid memory-related issues.

Incrementing a Pointer:

Now, this program is how it looks in the memory: int arr[4] = {10, 20, 30, 40};

int arr

This behavior is a key aspect of pointer arithmetic. When you add an integer to a pointer, it moves to the memory location of the element at the specified index, allowing you to efficiently access and manipulate elements within the array. It's worth noting that you can use pointer arithmetic to access elements in any position within the array, making it a powerful technique for working with arrays of data. Now, let's print the memory addresses of the elements in the array from our previous program.

If you observe the last two digits of the first address is 40, and the second one is 44. You might be wondering why it's not 40 and 41. This is because we're working with an integer array, and in most systems, the size of an int data type is 4 bytes. Therefore, the addresses are incremented in steps of 4. The first address shows 40, the second 44, and the third one 48

Decrementing a Pointer Decrement (--) a pointer variable, which makes it point to the previous element in an array. For example, ptr-- moves it to the previous one. For example:

Explanation:

We have an integer array arr with 5 elements, and we initialize a pointer ptr to point to the fourth element (value 40) using &arr[3].

Then, we decrement the pointer ptr by one with the statement ptr--. This moves the pointer to the previous memory location, which now points to the third element (value 30).

Finally, we print the value pointed to by the decremented pointer using *ptr, which gives us the value 30.

In this program, we demonstrate how decrementing a pointer moves it to the previous memory location in the array, allowing you to access and manipulate the previous element.

Pointer to pointer

Pointers to pointers, or double pointers, are variables that store the address of another pointer. In essence, they add another level of indirection. These are commonly used when you need to modify the pointer itself or work with multi-dimensional arrays.

To declare and initialize a pointer to a pointer, you need to add an extra asterisk (*) compared to a regular pointer. Let's go through an example:

In this example, ptr2 is a pointer to a pointer. It points to the memory location where the address of x is stored (which is ptr1 ).

pointer to poiter

The below program will show you how to print the value of x through pointer to pointer

In this program, we first explain that it prints the value of x using a regular variable, a pointer, and a pointer to a pointer. We then print the memory addresses of x , ptr1 , and ptr2 .

Passing Pointers as Function Arguments:

In C, you can pass pointers as function arguments. This allows you to manipulate the original data directly, as opposed to working with a copy of the data, as you would with regular variables. Here's how it works:

How to Declare and Define Functions that Take Pointer Arguments: In your function declaration and definition, you specify that you're passing a pointer by using the * operator after the data type. For example:

In the above function, we declare ptr as a pointer to an integer. This means it can store the memory address of an integer variable.

Why Would You Pass Pointers to Functions?

Passing pointers to functions allows you to:

  • Modify the original data directly within the function.
  • Avoid making a copy of the data, which can be more memory-efficient.
  • Share data between different parts of your program efficiently.

This concept is especially important when working with large data structures or when you need to return multiple values from a function.

Call by Value vs. Call by Reference:

Understanding how data is passed to functions is crucial when working with pointers. there are two common ways that data can be passed to functions: call by value and call by reference.

Call by Value:

When you pass data by value, a copy of the original data is created inside the function. Any modifications to this copy do not affect the original data outside of the function. This is the default behavior for most data types when you don't use pointers.

Call by Reference (Using Pointers):

When you pass data by reference, you're actually passing a pointer to the original data's memory location. This means any changes made within the function will directly affect the original data outside the function. This is achieved by passing pointers as function arguments, making it call by reference. Using pointers as function arguments allows you to achieve call by reference behavior, which is particularly useful when you want to modify the original data inside a function and have those changes reflected outside the function.

Let's dive into some code examples to illustrate how pointers work as function arguments. We'll start with a simple example to demonstrate passing a pointer to a function and modifying the original data.

Consider this example:

In this code, we define a function modifyValue that takes a pointer to an integer. We pass the address of the variable num to this function, and it doubles the value stored in num directly.

This is a simple demonstration of passing a pointer to modify a variable's value. Pointers allow you to work with the original data efficiently.

An array of pointers is essentially an array where each element is a pointer. These pointers can point to different data types (int, char, etc.), providing flexibility and efficiency in managing memory.

How to Declare an Array of Pointers? To declare an array of pointers, you specify the type of data the pointers will point to, followed by square brackets to indicate it's an array, and then the variable name. For example:

Initializing an Array of Pointers You can initialize an array of pointers to each element to point to a specific value, For example:

How to Access Elements Through an Array of Pointers? To access elements through an array of pointers, you can use the pointer notation. For example:

This program demonstrates how to access and print the values pointed to by the pointers in the array.

A NULL pointer is a pointer that lacks a reference to a valid memory location. It's typically used to indicate that a pointer doesn't have a specific memory address assigned, often serving as a placeholder or default value for pointers.

Here's a code example that demonstrates the use of a NULL pointer:

In this example, we declare a pointer ptr and explicitly initialize it with the value NULL. We then use an if statement to check if the pointer is NULL. Since it is, the program will print "The pointer is NULL." This illustrates how NULL pointers are commonly used to check if a pointer has been initialized or assigned a valid memory address.

conclusion:

You've embarked on a comprehensive journey through the intricacies of C pointers. You've learned how pointers store memory addresses, enable data access, facilitate pointer arithmetic, and how they can be used with arrays and functions. Additionally, you've explored the significance of NULL pointers.

By completing this tutorial, you've equipped yourself with a robust understanding of pointers in C. You can now confidently navigate memory, manipulate data efficiently, and harness the power of pointers in your programming projects. These skills will be invaluable as you advance in your coding endeavors. Congratulations on your accomplishment, and keep coding with confidence!

Reference: C - Pointers - Tutorials Point

Pointers in C: A One-Stop Solution for Using C Pointers - simplilearn

Top comments (4)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

imperiald profile image

  • Joined Jan 7, 2024

Love your way to write articles, could you add an article for, .o files, .h files, lists and makefile? Thank you in advance!

raed_abdullah_ae4b30d82db profile image

  • Joined Aug 13, 2024

This tutorial covers the fundamentals of C pointers, providing a clear understanding of their role in memory management and data manipulation. By the end, you should be comfortable with basic pointer concepts and their applications. Are you looking to enhance your cybersecurity skills? Check out the Ethical Hacking Training in Bangalore offered by Indian Cyber Security Solutions .

cocomelonjuice profile image

  • Joined Nov 4, 2023

Great post. Thank you so much for this.

koderkareem profile image

Thank you for your kind words! I'm thrilled to hear that you enjoyed the article. Your feedback means a lot to me. If you have any questions or if there's a specific topic you'd like to see in future posts, feel free to let me know. Thanks again for your support

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

mohammed_kareem profile image

.Env Files For Tech Noobs

Mohammad Kareem - Aug 14

kartik_chinda_682309be748 profile image

Start with Stellar: The only tutorial you need to build a full stack dApp from scratch.

Kartik Chinda - Aug 14

clare_codes profile image

How to Install and Set Up Tailwind CSS from Scratch

Clare Codes - Aug 14

uicraft_by_pratik profile image

🙅‍♂️Introducing Animata: New Tool for Effortless Animations in React & Tailwind

Pratik Tamhane - Aug 18

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

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

Everything you need to know about pointers in C

Version 1.3.1.

Copyright 2005–2023 Peter Hosey.

Creative Commons License

This document comes with a companion example program, available as one file or as multiple files (zipped) .

Style used in this document

This is regular text. This is a variable , some code , and some sample output .

This is a line of code. This is a comment. This is also a comment.
This is output you'd see on your screen.
  • Table of contents

Definition of a pointer

Starting off, interlude: declaration syntax, assignment and pointers, dereferencing, interlude: arrays, pointer arithmetic (or: why 1 == 4), interlude: structures and unions, multiple indirection, pointers and const, function pointers, strings (and why there is no such thing).

A pointer is a memory address.

(Mmm, short paragraphs.)

Say you declare a variable named foo .

This variable occupies some memory. On current mainstream Intel processors, it occupies four bytes of memory (because an int is four bytes wide).

Now let's declare another variable.

int * foo_ptr = &foo;

foo_ptr is declared as a pointer to int . We have initialized it to point to foo .

As I said, foo occupies some memory. Its location in memory is called its address. &foo is the address of foo (which is why & is called the “address-of operator”).

Think of every variable as a box. foo is a box that is sizeof(int) bytes in size. The location of this box is its address. When you access the address, you actually access the contents of the box it points to.

This is true of all variables, regardless of type. In fact, grammatically speaking, there is no such thing as a “pointer variable”: all variables are the same. There are, however, variables with different types. foo 's type is int . foo_ptr 's type is int * . (Thus, “pointer variable” really means “variable of a pointer type”.)

The point of that is that the pointer is not the variable ! The pointer to foo is the contents of foo_ptr . You could put a different pointer in the foo_ptr box, and the box would still be foo_ptr . But it would no longer point to foo .

The box named foo_ptr (an int *) is a pointer to a box named foo (an int).

The pointer has a type, too, by the way. Its type is int . Thus it is an “ int pointer” (a pointer to int ). An int ** 's type is int * (it points to a pointer to int ). The use of pointers to pointers is called multiple indirection . More on that in a bit.

The obvious way to declare two pointer variables in a single declaration is:

int* ptr_a , ptr_b ;
  • If the type of a variable containing a pointer to int is int * ,
  • and a single declaration can declare multiple variables of the same type by simply providing a comma-separated list ( ptr_a, ptr_b ),
  • then you can declare multiple int -pointer variables by simply giving the int -pointer type ( int * ) followed by a comma-separated list of names to use for the variables ( ptr_a, ptr_b ).

Given this, what is the type of ptr_b ? int * , right?

* bzzt * Wrong!

The type of ptr_b is int . It is not a pointer.

C's declaration syntax ignores the pointer asterisks when carrying a type over to multiple declarations. If you split the declaration of ptr_a and ptr_b into multiple declarations, you get this:

int *ptr_a; int ptr_b;

Think of it as assigning each variable a base type ( int ), plus a level of indirection, indicated by the number of asterisks ( ptr_b 's is zero; ptr_a 's is one).

It's possible to do the single-line declaration in a clear way. This is the immediate improvement:

int *ptr_a, ptr_b;

Notice that the asterisk has moved. It is now right next to the word ptr_a . A subtle implication of association.

It's even clearer to put the non-pointer variables first:

int ptr_b, *ptr_a;

The absolute clearest is to keep every declaration on its own line, but that can take up a lot of vertical space. Just use your own judgment.

Finally, I should point out that you can do this just fine:

int *ptr_a, *ptr_b;

There's nothing wrong with it.

Incidentally, C allows zero or more levels of parentheses around the variable name and asterisk:

int ((not_a_pointer)), (*ptr_a), (((*ptr_b)));

This is not useful for anything, except to declare function pointers (described later).

Further reading: The right-left rule for reading C declarations .

Now, how do you assign an int to this pointer? This solution might be obvious:

foo_ptr = 42;

It is also wrong.

Any direct assignment to a pointer variable will change the address in the variable, not the value at that address. In this example, the new value of foo_ptr (that is, the new “pointer” in that variable) is 42. But we don't know that this points to anything, so it probably doesn't. Trying to access this address will probably result in a segmentation violation (read: crash).

(Incidentally, compilers usually warn when you try to assign an int to a pointer variable. gcc will say “ warning: initialization makes pointer from integer without a cast ”.)

So how do you access the value at a pointer? You must dereference it.

int bar = *foo_ptr;

In this declaration, the dereference operator (prefix * , not to be confused with the multiplication operator) looks up the value that exists at an address. (This is called a “load” operation.)

It's also possible to write to a dereference expression (the C way of saying this: a dereference expression is an lvalue , meaning that it can appear on the left side of an assignment):

*foo_ptr = 42; Sets foo to 42

(This is called a “store” operation.)

Here's a declaration of a three- int array:

int array[] = { 45, 67, 89 };

Note that we use the [] notation because we are declaring an array. int *array would be illegal here; the compiler would not accept us assigning the { 45, 67, 89 } initializer to it.

This variable, array , is an extra-big box: three int s' worth of storage.

One neat feature of C is that, in most places, when you use the name array again, you will actually be using a pointer to its first element (in C terms, &array[0] ). This is called “ decaying ”: the array “decays” to a pointer. Most usages of array are equivalent to if array had been declared as a pointer.

There are, of course, cases that aren't equivalent. One is assigning to the name array by itself ( array = … )—that's illegal.

Another is passing it to the sizeof operator. The result will be the total size of the array, not the size of a pointer (for example, sizeof(array) using the array above would evaluate to ( sizeof(int) = 4) × 3 = 12 on a current Mac OS X system). This illustrates that you are really handling an array and not merely a pointer.

In most uses, however, array expressions work just the same as pointer expressions.

So, for example, let's say you want to pass an array to printf . You can't: When you pass an array as an argument to a function, you really pass a pointer to the array's first element, because the array decays to a pointer. You can only give printf the pointer, not the whole array. (This is why printf has no way to print an array: It would need you to tell it the type of what's in the array and how many elements there are, and both the format string and the list of arguments would quickly get confusing.)

Decaying is an implicit & ; array == &array == &array[0] . In English, these expressions read “ array ”, “pointer to array ”, and “pointer to the first element of array ” (the subscript operator, [] , has higher precedence than the address-of operator). But in C, all three expressions mean the same thing.

(They would not all mean the same thing if “ array ” were actually a pointer variable, since the address of a pointer variable is different from the address inside it—thus, the middle expression, &array , would not be equal to the other two expressions. The three expressions are all equal only when array really is an array.)

Say we want to print out all three elements of array .

int * array_ptr = array; printf(" first element: %i\n", *(array_ptr++)); printf("second element: %i\n", *(array_ptr++)); printf(" third element: %i\n", *array_ptr);
first element: 45 second element: 67 third element: 89

In case you're not familiar with the ++ operator: it adds 1 to a variable, the same as variable += 1 (remember that because we used the postfix expression array_ptr++ , rather than the prefix expression ++array_ptr , the expression evaluated to the value of array_ptr from before it was incremented rather than after).

But what did we do with it here?

Well, the type of a pointer matters. The type of the pointer here is int . When you add to or subtract from a pointer, the amount by which you do that is multiplied by the size of the type of the pointer. In the case of our three increments, each 1 that you added was multiplied by sizeof(int) .

By the way, though sizeof(void) is illegal, void pointers are incremented or decremented by 1 byte.

In case you're wondering about 1 == 4 : Remember that earlier, I mentioned that int s are four bytes on current Intel processors. So, on a machine with such a processor, adding 1 to or subtracting 1 from an int pointer changes it by four bytes. Hence, 1 == 4 . (Programmer humor.)

printf("%i\n", array[0]);

OK… what just happened?

This happened:

Well, you probably figured that. But what does this have to do with pointers?

This is another one of those secrets of C. The subscript operator (the [] in array[0] ) has nothing to do with arrays .

Oh, sure, that's its most common usage. But remember that, in most contexts, arrays decay to pointers. This is one of them: That's a pointer you passed to that operator, not an array.

As evidence, I submit:

int array[] = { 45, 67, 89 }; int *array_ptr = &array[1]; printf("%i\n", array_ptr[1]);

That one might bend the brain a little. Here's a diagram:

The second element of array_ptr is the third element of array.

array points to the first element of the array; array_ptr is set to &array[1] , so it points to the second element of the array. So array_ptr[1] is equivalent to array[2] ( array_ptr starts at the second element of the array, so the second element of array_ptr is the third element of the array).

Also, you might notice that because the first element is sizeof(int) bytes wide (being an int ), the second element is sizeof(int) bytes forward of the start of the array. You are correct: array[1] is equivalent to *(array + 1) . (Remember that the number added to or subtracted from a pointer is multiplied by the size of the pointer's type, so that “ 1 ” adds sizeof(int) bytes to the pointer value.)

Two of the more interesting kinds of types in C are structures and unions. You create a structure type with the struct keyword, and a union type with the union keyword.

The exact definitions of these types are beyond the scope of this article. Suffice to say that a declaration of a struct or union looks like this:

struct foo { size_t size; char name[64]; int answer_to_ultimate_question; unsigned shoe_size; };

Each of those declarations inside the block is called a member. Unions have members too, but they're used differently. Accessing a member looks like this:

struct foo my_foo; my_foo.size = sizeof(struct foo);

The expression my_foo.size accesses the member size of my_foo .

So what do you do if you have a pointer to a structure?

One way to do it (*foo_ptr).size = new_size;

But there is a better way, specifically for this purpose: the pointer-to-member operator .

Yummy foo_ptr->size = new_size;

Unfortunately, it doesn't look as good with multiple indirection.

Icky (*foo_ptr_ptr)->size = new_size; One way (**foo_ptr_ptr).size = new_size; or another

Rant: Pascal does this much better. Its dereference operator is a postfix ^ :

Yummy foo_ptr_ptr^^.size := new_size;

(But putting aside this complaint, C is a much better language.)

I want to explain multiple indirection a bit further.

Consider the following code:

int a = 3; int *b = &a; int **c = &b; int ***d = &c;

Here are how the values of these pointers equate to each other:

  • *d == c; Dereferencing an (int ***) once gets you an (int **) (3 - 1 = 2)
  • **d == *c == b; Dereferencing an (int ***) twice, or an (int **) once, gets you an (int *) (3 - 2 = 1; 2 - 1 = 1)
  • ***d == **c == *b == a == 3; Dereferencing an (int ***) thrice, or an (int **) twice, or an (int *) once, gets you an int (3 - 3 = 0; 2 - 2 = 0; 1 - 1 = 0)

Thus, the & operator can be thought of as adding asterisks (increasing pointer level, as I call it), and the * , -> , and [] operators as removing asterisks (decreasing pointer level).

The const keyword is used a bit differently when pointers are involved. These two declarations are equivalent:

const int *ptr_a; int const *ptr_a;

These two, however, are not equivalent:

int const *ptr_a; int *const ptr_b;

In the first example, the int (i.e. *ptr_a ) is const ; you cannot do *ptr_a = 42 . In the second example, the pointer itself is const ; you can change *ptr_b just fine, but you cannot change (using pointer arithmetic, e.g. ptr_b++ ) the pointer itself.

Note: The syntax for all of this seems a bit exotic. It is. It confuses a lot of people, even C wizards. Bear with me.

It's possible to take the address of a function, too. And, similarly to arrays, functions decay to pointers when their names are used. So if you wanted the address of, say, strcpy , you could say either strcpy or &strcpy . ( &strcpy[0] won't work for obvious reasons.)

When you call a function, you use an operator called the function call operator . The function call operator takes a function pointer on its left side.

In this example, we pass dst and src as the arguments on the interior, and strcpy as the function (that is, the function pointer) to be called:

enum { str_length = 18U }; Remember the NUL terminator! char src [str_length] = "This is a string.", dst [str_length]; strcpy(dst, src); The function call operator in action (notice the function pointer on the left side).

There's a special syntax for declaring variables whose type is a function pointer.

char *strcpy(char *dst, const char *src); An ordinary function declaration, for reference char *(*strcpy_ptr)(char *dst, const char *src); Pointer to strcpy-like function strcpy_ptr = strcpy; strcpy_ptr = &strcpy; This works too strcpy_ptr = &strcpy[0]; But not this

Note the parentheses around *strcpy_ptr in the above declaration. These separate the asterisk indicating return type ( char * ) from the asterisk indicating the pointer level of the variable ( *strcpy_ptr — one level, pointer to function).

Also, just like in a regular function declaration, the parameter names are optional:

char *(*strcpy_ptr_noparams)(char *, const char *) = strcpy_ptr; Parameter names removed — still the same type

The type of the pointer to strcpy is char *(*)(char *, const char *) ; you may notice that this is the declaration from above, minus the variable name. You would use this in a cast. For example:

strcpy_ptr = (char *(*)(char *dst, const char *src))my_strcpy;

As you might expect, a pointer to a pointer to a function has two asterisks inside of the parentheses:

char *(**strcpy_ptr_ptr)(char *, const char *) = &strcpy_ptr;

We can have an array of function-pointers:

char *(*strcpies[3])(char *, const char *) = { strcpy, strcpy, strcpy }; char *(*strcpies[])(char *, const char *) = { strcpy, strcpy, strcpy }; Array size is optional, same as ever strcpies[0](dst, src);

Here's a pathological declaration, taken from the C99 standard. “[This declaration] declares a function f with no parameters returning an int , a function fip with no parameter specification returning a pointer to an int , and a pointer pfi to a function with no parameter specification returning an int .” (6.7.5.3[16])

int f(void), *fip(), (*pfi)();

In other words, the above is equivalent to the following three declarations:

int f(void); int *fip(); Function returning int pointer int (*pfi)(); Pointer to function returning int

But if you thought that was mind-bending, brace yourself…

A function pointer can even be the return value of a function. This part is really mind-bending, so stretch your brain a bit so as not to risk injury.

In order to explain this, I'm going to summarize all the declaration syntax you've learned so far. First, declaring a pointer variable:

This declaration tells us the pointer type ( char ), pointer level ( * ), and variable name ( ptr ). And the latter two can go into parentheses:

char (*ptr);

What happens if we replace the variable name in the first declaration with a name followed by a set of parameters?

char *strcpy(char *dst, const char *src);

Huh. A function declaration.

But we also removed the * indicating pointer level — remember that the * in this function declaration is part of the return type of the function. So if we add the pointer-level asterisk back (using the parentheses):

char *(*strcpy_ptr)(char *dst, const char *src);

A function pointer variable!

But wait a minute. If this is a variable, and the first declaration was also a variable, can we not replace the variable name in THIS declaration with a name and a set of parameters?

YES WE CAN! And the result is the declaration of a function that returns a function pointer:

char *(*get_strcpy_ptr(void))(char *dst, const char *src);

Remember that the type of a pointer to a function taking no arguments and returning int is int (*)(void) . So the type returned by this function is char *(*)(char *, const char *) (with, again, the inner * indicating a pointer, and the outer * being part of the return type of the pointed-to function). You may remember that that is also the type of strcpy_ptr .

So this function, which is called with no parameters, returns a pointer to a strcpy -like function:

strcpy_ptr = get_strcpy_ptr();

Because function pointer syntax is so mind-bending, most developers use typedef s to abstract them:

typedef char *(*strcpy_funcptr)(char *, const char *); strcpy_funcptr strcpy_ptr = strcpy; strcpy_funcptr get_strcpy_ptr(void);

There is no string type in C.

Now you have two questions:

  • Why do I keep seeing references to “C strings” everywhere if there is no string type?
  • What does this have to do with pointers?

The truth is, the concept of a “C string” is imaginary (except for string literals). There is no string type. C strings are really just arrays of characters:

char str[] = "I am the Walrus";

This array is 16 bytes in length: 15 characters for "I am the Walrus", plus a NUL (byte value 0) terminator. In other words, str[15] (the last element) is 0. This is how the end of the “string” is signaled.

This idiom is the extent to which C has a string type. But that's all it is: an idiom. Except that it is supported by:

  • the aforementioned string literal syntax
  • the string library

The functions in string.h are for string manipulation. But how can that be, if there is no string type?

Why, they work on pointers.

Here's one possible implementation of the simple function strlen , which returns the length of a string (not including the NUL terminator):

size_t strlen(const char *str) { Note the pointer syntax here size_t len = 0U; while(*(str++)) ++len; return len; }

Note the use of pointer arithmetic and dereferencing. That's because, despite the function's name, there is no “string” here; there is merely a pointer to at least one character, the last one being 0.

Here's another possible implementation:

size_t strlen(const char *str) { size_t i; for(i = 0U; str[i]; ++i); When the loop exits, i is the length of the string return i; }

That one uses indexing. Which, as we found out earlier, uses a pointer (not an array, and definitely not a string).

Version history

  • Replaced hotlinked Creative Commons bug with my own high-resolution redraw of it.
  • Upgraded various links to HTTPS, and replaced dead links with corrected ones or Wayback Machine links.
  • Switched character set to UTF-8.
  • Fixed explanation of the relationship between Pointers and const .
  • Added -> as one of the dereference operators in Multiple indirection .
  • Changed improper use of ‘’’ as apostrophe to use proper apostrophes instead. Most fonts still render the apostrophe (‘'’) as a straight single quote, but that's not my problem.
  • Corrected discussion of decaying, especially of arrays. Arrays are not pointers.
  • Added two links to the right-left rule for reading C declarations .
  • Corrected the name of the subscript operator (which I previously referred to as the index operator).
  • Replaced references to the PowerPC with references to Intel processors. (Fortunately, no factual changes were necessary.)
  • Fixed a couple of compilation errors and a few warnings in the sample code (in addition to the aforementioned array-decaying discussion).
  • Fixed link to the Pointer arithmetic section from the 1.1 section below.
  • Changed the hyphen to an en dash in the year range in the copyright notice (reference: Chicago Manual of Style ).
  • Changed byline from “Mac-arena the Bored Zo” to my real name.
  • Added Function pointers section.
  • Added Pointers and const section.
  • Added note about parentheses in declarators in Declaration syntax .
  • Added that array == &array == &array[0] (i.e. decay is an implicit & ) in Arrays .
  • Smart quotes.
  • Reworded parenthetical about ++x vs x++ , at Colin Barrett's suggestion.
  • Assignment section (describing the action of foo_ptr = 42 )
  • Declaration syntax section
  • Multiple indirection section
  • C strings section
  • Changed sentences to begin with a capital letter, on feedback that it should be clearer to read that way.
  • Clarified 1 == 4 expression in title, and use of ++ , in “ Pointer arithmetic ”.
  • Shinier CSS, especially for comments.
  • Added winged-comments ( example ) style.
  • Added diagram in Starting off .
  • Explained array declaration syntax (as opposed to pointer declaration syntax) in Arrays .

This document is also available in zip format. The previous versions ( 1.2.1 , 1.2 , 1.1 , and 1.0 ) are also available.

cppreference.com

Pointer declaration.

(C++20)
(C++20)
(C++11)
(C++20)
(C++17)
(C++11)
(C++11)
General topics
(C++11)
-
-expression
block


/
(C++11)
(C++11)
(C++11)
(C++20)
(C++20)
(C++11)

expression
pointer
specifier

specifier (C++11)
specifier (C++11)
(C++11)

(C++11)
(C++11)
(C++11)
Specifiers
function specifier
function specifier
(C++20)
/struct
volatile
(C++26)    
(C++11)
Declarators
Block declarations
(C++17)
(C++11)
declaration
directive
declaration (C++11)
declaration
(C++11)
Other declarations
(C++11)
(C++11)

Declares a variable of a pointer or pointer-to-member type.

Syntax Pointers Pointers to objects Pointers to void Pointers to functions Pointers to members Pointers to data members Pointers to member functions Null pointers Invalid pointers Constness Composite pointer type Defect reports See also

[ edit ] Syntax

A pointer declaration is any simple declaration whose declarator has the form

attr (optional) cv (optional) declarator (1)
nested-name-specifier attr (optional) cv (optional) declarator (2)
nested-name-specifier - a
attr - (since C++11) a list of
cv - const/volatile qualification which apply to the pointer that is being declared (not to the pointed-to type, whose qualifications are part of declaration specifier sequence)
declarator - any other than a reference declarator (there are no pointers to references). It can be another pointer declarator (pointer to pointers are allowed)

There are no pointers to references and there are no pointers to bit-fields . Typically, mentions of "pointers" without elaboration do not include pointers to (non-static) members.

[ edit ] Pointers

Every value of pointer type is one of the following:

  • a pointer to an object or function (in which case the pointer is said to point to the object or function), or
  • a pointer past the end of an object , or
  • the null pointer value for that type, or
  • an invalid pointer value .

A pointer that points to an object represents the address of the first byte in memory occupied by the object. A pointer past the end of an object represents the address of the first byte in memory after the end of the storage occupied by the object.

Note that two pointers that represent the same address may nonetheless have different values.

Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior. Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault.

[ edit ] Pointers to objects

A pointer to object can be initialized with the return value of the address-of operator applied to any expression of object type, including another pointer type:

Pointers may appear as operands to the built-in indirection operator (unary operator * ), which returns the lvalue expression identifying the pointed-to object:

Pointers to class objects may also appear as the left-hand operands of the member access operators operator-> and operator->* .

Because of the array-to-pointer implicit conversion, pointer to the first element of an array can be initialized with an expression of array type:

Because of the derived-to-base implicit conversion for pointers, pointer to a base class can be initialized with the address of a derived class:

If Derived is polymorphic , such a pointer may be used to make virtual function calls .

Certain addition, subtraction , increment, and decrement operators are defined for pointers to elements of arrays: such pointers satisfy the LegacyRandomAccessIterator requirements and allow the C++ library algorithms to work with raw arrays.

Comparison operators are defined for pointers to objects in some situations: two pointers that represent the same address compare equal, two null pointer values compare equal, pointers to elements of the same array compare the same as the array indices of those elements, and pointers to non-static data members with the same member access compare in order of declaration of those members.

Many implementations also provide strict total ordering of pointers of random origin, e.g. if they are implemented as addresses within continuous virtual address space. Those implementations that do not (e.g. where not all bits of the pointer are part of a memory address and have to be ignored for comparison, or an additional calculation is required or otherwise pointer and integer is not a 1 to 1 relationship), provide a specialization of std::less for pointers that has that guarantee. This makes it possible to use all pointers of random origin as keys in standard associative containers such as std::set or std::map .

[ edit ] Pointers to void

Pointer to object of any type can be implicitly converted to pointer to (possibly cv-qualified ) void ; the pointer value is unchanged. The reverse conversion, which requires static_cast or explicit cast , yields the original pointer value:

If the original pointer is pointing to a base class subobject within an object of some polymorphic type, dynamic_cast may be used to obtain a void * that is pointing at the complete object of the most derived type.

Pointers to void have the same size, representation and alignment as pointers to char .

Pointers to void are used to pass objects of unknown type, which is common in C interfaces: std::malloc returns void * , std::qsort expects a user-provided callback that accepts two const void * arguments. pthread_create expects a user-provided callback that accepts and returns void * . In all cases, it is the caller's responsibility to cast the pointer to the correct type before use.

[ edit ] Pointers to functions

A pointer to function can be initialized with an address of a non-member function or a static member function. Because of the function-to-pointer implicit conversion, the address-of operator is optional:

Unlike functions or references to functions, pointers to functions are objects and thus can be stored in arrays, copied, assigned, etc.

Note: declarations involving pointers to functions can often be simplified with type aliases:

A pointer to function can be used as the left-hand operand of the function call operator , this invokes the pointed-to function:

Dereferencing a function pointer yields the lvalue identifying the pointed-to function:

A pointer to function may be initialized from an overload set which may include functions, function template specializations, and function templates, if only one overload matches the type of the pointer (see address of an overloaded function for more detail):

Equality comparison operators are defined for pointers to functions (they compare equal if pointing to the same function).

[ edit ] Pointers to members

[ edit ] pointers to data members.

A pointer to non-static member object m which is a member of class C can be initialized with the expression & C :: m exactly. Expressions such as & ( C :: m ) or & m inside C 's member function do not form pointers to members.

Such a pointer may be used as the right-hand operand of the pointer-to-member access operators operator. * and operator - > * :

Pointer to data member of an accessible unambiguous non-virtual base class can be implicitly converted to pointer to the same data member of a derived class:

Conversion in the opposite direction, from a pointer to data member of a derived class to a pointer to data member of an unambiguous non-virtual base class, is allowed with static_cast and explicit cast , even if the base class does not have that member (but the most-derived class does, when the pointer is used for access):

The pointed-to type of a pointer-to-member may be a pointer-to-member itself: pointers to members can be multilevel, and can be cv-qualified differently at every level. Mixed multi-level combinations of pointers and pointers-to-members are also allowed:

[ edit ] Pointers to member functions

A pointer to non-static member function f which is a member of class C can be initialized with the expression & C :: f exactly. Expressions such as & ( C :: f ) or & f inside C 's member function do not form pointers to member functions.

Such a pointer may be used as the right-hand operand of the pointer-to-member access operators operator. * and operator - > * . The resulting expression can be used only as the left-hand operand of a function-call operator:

Pointer to member function of a base class can be implicitly converted to pointer to the same member function of a derived class:

Conversion in the opposite direction, from a pointer to member function of a derived class to a pointer to member function of an unambiguous non-virtual base class, is allowed with static_cast and explicit cast , even if the base class does not have that member function (but the most-derived class does, when the pointer is used for access):

Pointers to member functions may be used as callbacks or as function objects, often after applying std::mem_fn or std::bind :

[ edit ] Null pointers

Pointers of every type have a special value known as null pointer value of that type. A pointer whose value is null does not point to an object or a function (the behavior of dereferencing a null pointer is undefined), and compares equal to all pointers of the same type whose value is also null .

A null pointer constant can be used to initialize a pointer to null or to assign the null value to an existing pointer, it is one of the following values:

  • An integer literal with value zero.
(usually nullptr). (since C++11)

The macro NULL can also be used, it expands to an implementation-defined null pointer constant.

Zero-initialization and value-initialization also initialize pointers to their null values.

Null pointers can be used to indicate the absence of an object (e.g. std::function::target() ), or as other error condition indicators (e.g. dynamic_cast ). In general, a function that receives a pointer argument almost always needs to check if the value is null and handle that case differently (for example, the delete expression does nothing when a null pointer is passed).

[ edit ] Invalid pointers

A pointer value p is valid in the context of an evaluation e if one of the following condition is satisfied:

  • p is a null pointer value.
  • p it is a pointer to or past the end of an object o , and e is in the duration of the region of storage for o .

If a pointer value p is used in an evaluation e , and p is not valid in the context of e , then:

  • If e is an indirection or an invocation of a deallocation function , the behavior is undefined.
  • Otherwise, the behavior is implementation-defined.

[ edit ] Constness

  • If cv appears before * in the pointer declaration, it is part of the declaration specifier sequence and applies to the pointed-to object.
  • If cv appears after * in the pointer declaration, it is part of the declarator and applies to the pointer that's being declared.
Syntax meaning
const T* pointer to constant object
T const* pointer to constant object
T* const constant pointer to object
const T* const constant pointer to constant object
T const* const constant pointer to constant object

In general, implicit conversion from one multi-level pointer to another follows the rules described in qualification conversions .

[ edit ] Composite pointer type

When an operand of a comparison operator or any of the second and third operands of a conditional operator is a pointer or pointer-to-member, a composite pointer type is determined to be the common type of these operands.

Given two operands p1 and p2 having types T1 and T2 , respectively, p1 and p2 can only have a composite pointer type if any of the following conditions are satisfied:

and p2 are both pointers. and p2 is a pointer and the other operand is a null pointer constant.
and p2 are both null pointer constants, and at least one of and is a non-integral type. (since C++11)
  • At least one of T1 and T2 is a pointer type, pointer-to-member type or std::nullptr_t .

The composite pointer type C of p1 and p2 is determined as follows:

is a , is . is a null pointer constant, is . (until C++11)
and p2 are both , is . is a null pointer constant, is . is a null pointer constant, is . (since C++11)
  • Otherwise, if all following conditions are satisfied:
  • T1 or T2 is “pointer to cv1 void ”.
  • The other type is “pointer to cv2 T ”, where T is an object type or void .
or is “pointer to function type ”. ”. and are the same except noexcept. is “pointer to ”. (since C++17)
  • T1 is “pointer to C1 ”.
  • T2 is “pointer to C2 ”.
  • One of C1 and C2 is reference-related to the other.
  • the qualification-combined type of T1 and T2 , if C1 is reference-related to C2 , or
  • the qualification-combined type of T2 and T1 , if C2 is reference-related to C1 .
or is “pointer to member of of function type ”. of noexcept function type ”. and is reference-related to the other. and are the same except noexcept. is of type ”, if is reference-related to , or of type ”, if is reference-related to . (since C++17)
  • T1 is “pointer to member of C1 of non-function type M1 ”.
  • T2 is “pointer to member of C2 of non-function type M2 ”
  • M1 and M2 are the same except top-level cv-qualifications.
  • the qualification-combined type of T2 and T1 , if C1 is reference-related to C2 , or
  • the qualification-combined type of T1 and T2 , if C2 is reference-related to C1 .
  • Otherwise, if T1 and T2 are similar types , C is the qualification-combined type of T1 and T2 .
  • Otherwise, p1 and p2 do not have a composite pointer type, a program that necessitates the determination of C such a type is ill-formed.

[ edit ] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
C++98 a pointer to an object never compares equal
to a pointer to one past the end of an array
for non-null and non-function pointers,
compare the addresses they represent
C++98 any integral constant expression that
evaluates to 0 was a null pointer constant
limited to integer
literals with value 0
C++98 the behavior of using an invalid pointer
value in any way was undefined
behaviors other than indirection and
passing to deallocation functions
are implementation-defined

( )
C++98 the rule of composite pointer type was incomplete, and thus
did not allow comparison between int** and const int**
made complete
C++98 a pointer to void and a pointer to
function had a composite pointer type
they do not have such a type
C++17 function pointer conversions were not allowed
when determining the composite pointer type
allowed
C++98 reaching the end of the duration of a region
of storage could invalidate pointer values
pointer validity is based
on the evaluation context

[ edit ] See also

for Pointer declaration
  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 13 June 2024, at 02:53.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

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.
  • C++ Language
  • Ascii Codes
  • Boolean Operations
  • Numerical Bases

Introduction

Basics of c++.

  • Structure of a program
  • Variables and types
  • Basic Input/Output

Program structure

  • Statements and flow control
  • Overloads and templates
  • Name visibility

Compound data types

  • Character sequences
  • Dynamic memory
  • Data structures
  • Other data types
  • Classes (I)
  • Classes (II)
  • Special members
  • Friendship and inheritance
  • Polymorphism

Other language features

  • Type conversions
  • Preprocessor directives

Standard library

  • Input/output with files

Address-of operator (&)

pointer for assignment

Dereference operator (*)

pointer for assignment

baz = *foo;
  • & is the address-of operator , and can be read simply as "address of"
  • * is the dereference operator , and can be read as "value pointed to by"

Declaring pointers

* number; * character; * decimals;
std; main () { firstvalue, secondvalue; * mypointer; mypointer = &firstvalue; *mypointer = 10; mypointer = &secondvalue; *mypointer = 20; cout << << firstvalue << ; cout << << secondvalue << ; 0; }
std; main () { firstvalue = 5, secondvalue = 15; * p1, * p2; p1 = &firstvalue; p2 = &secondvalue; *p1 = 10; *p2 = *p1; p1 = p2; *p1 = 20; cout << << firstvalue << ; cout << << secondvalue << ; 0; }
* p1, * p2;
* p1, p2;

Pointers and arrays

myarray [20]; * mypointer;
std; main () { numbers[5]; * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; ( n=0; n<5; n++) cout << numbers[n] << ; 0; }
*(a+5) = 0;

Pointer initialization

myvar; * myptr = &myvar;
myvar; * myptr; myptr = &myvar;
myvar; * myptr; *myptr = &myvar;
myvar; *foo = &myvar; *bar = foo;

Pointer arithmetics

*mychar; *myshort; *mylong;

pointer for assignment

*++p ++*p (*p)++

Pointers and const

x; y = 10; * p = &y; x = *p; *p = x;
std; increment_all ( * start, * stop) { * current = start; (current != stop) { ++(*current); ++current; } } print_all ( * start, * stop) { * current = start; (current != stop) { cout << *current << ; ++current; } } main () { numbers[] = {10,20,30}; increment_all (numbers,numbers+3); print_all (numbers,numbers+3); 0; }
x; * p1 = &x; * p2 = &x; * p3 = &x; * p4 = &x;
* p2a = &x; * p2b = &x;

Pointers and string literals

* foo = ;

pointer for assignment

Pointers to pointers

a; * b; ** c; a = ; b = &a; c = &b;

pointer for assignment

  • c is of type char** and a value of 8092
  • *c is of type char* and a value of 7230
  • **c is of type char and a value of 'z'

void pointers

std; increase ( * data, psize) { ( psize == ( ) ) { * pchar; pchar=( *)data; ++(*pchar); } (psize == ( ) ) { * pint; pint=( *)data; ++(*pint); } } main () { a = ; b = 1602; increase (&a, (a)); increase (&b, (b)); cout << a << << b << ; 0; }

Invalid pointers and null pointers

* p; myarray[10]; * q = myarray+20;
* p = 0; * q = ;
* r = NULL;

Pointers to functions

std; addition ( a, b) { (a+b); } subtraction ( a, b) { (a-b); } operation ( x, y, (*functocall)( , )) { g; g = (*functocall)(x,y); (g); } main () { m,n; (*minus)( , ) = subtraction; m = operation (7, 5, addition); n = operation (20, m, minus); cout <<n; 0; }
(* minus)( , ) = subtraction;
  • Skip to main content
  • Skip to primary sidebar
  • Skip to secondary sidebar
  • Skip to footer

Computer Notes

  • Computer Fundamental
  • Computer Memory
  • DBMS Tutorial
  • Operating System
  • Computer Networking
  • C Programming
  • C++ Programming
  • Java Programming
  • C# Programming
  • SQL Tutorial
  • Management Tutorial
  • Computer Graphics
  • Compiler Design
  • Style Sheet
  • JavaScript Tutorial
  • Html Tutorial
  • Wordpress Tutorial
  • Python Tutorial
  • PHP Tutorial
  • JSP Tutorial
  • AngularJS Tutorial
  • Data Structures
  • E Commerce Tutorial
  • Visual Basic
  • Structs2 Tutorial
  • Digital Electronics
  • Internet Terms
  • Servlet Tutorial
  • Software Engineering
  • Interviews Questions
  • Basic Terms
  • Troubleshooting

Header Right

How to pointer assignment and initialization in c.

By Dinesh Thakur

When we declare a pointer, it does not point to any specific variable. We must initialize it to point to the desired variable. This is achieved by assigning the address of that variable to the pointer variable, as shown below.

int a = 10;

pa = &a; /* pointer variable pa now points to variable a */

In this example, the first line declares an int variable named a and initializes it to 10. The second line declares a pointer pa of type pointer to int. Finally, the address of variable a is assigned to pa.Now pa is said to point to variable a.

We can also initialize a pointer when it is declared using the format given below.

type * ptr_var = init_expr ;

where init_expr is an expression that specifies the address of a previously defined variable of appropriate type or it can be NULL, a constant defined in the <stdio.h> header file.

Consider the example given below.

float x = 0.5;

float *px = &x;

int *p = NULL;

The second line declares a pointer variable px of type float * and initializes it with the address of variable x declared in the first line. Thus, pointer px now points to variable x. The third line declares pointer variable p of type int * and initializes it to NULL. Thus, pointer p does not point to any variable and it is an error to dereference such a pointer.

Note that a character pointer can be initialized using a character string constant as in

char *msg = “Hello, world!”;

Here, the C compiler allocates the required memory for the string constant (14 characters, in the above example, including the null terminator), stores the string constant in this memory and then assigns the initial address of this memory to pointer msg,as iliustrated in Fig.

pointer variable pointing to a string constant

The C language also permits initialization of more that one pointer variable in a single statement using the format shown below.

type *ptr_var1 = init_expr1, *ptr_var2 = init_expr2, … ;

It is also possible to mix the declaration and initialization of ordinary variables and pointers. However, we should avoid it to maintain program readability.

Example of Pointer Assignment and Initialization

char a= ‘A’;

char *pa = &a;

printf(“The address of character variable a: %p\n”, pa);

printf(“The address of pointer variable pa : %p\n”, &pa);

printf(“The value pointed by pointer variable pa: %c\n”, *pa);

Here, pa is a character pointer variable that is initialized with the address of character variable a defined in the first line. Thus, pa points to variable a. The first two printf statements print the address of variables a and pa using the %p (p for pointer) conversion. The last printf statement prints the value of a using the pointer variable pa. When the program containing this code is executed in Code::Blocks, the output is displayed as shown below. ·

The address of character variable a: 0022FF1F

The address of pointer variable pa : 0022FF18

The value pointed by pointer variable pa: A

Note that the addresses displayed in the output will usually be different depending on other variables declared in the program and the compiler/IDE used.

Another example is given below in which pointers are initialized with the addresses of variables of incompatible type.

char c = ‘Z’;

int i = 10;

float f = 1.1;

char *pcl = &i, *pc2 = &f;

int *pil = &c, *pi2 = &f;

float *pfl = &c, *pf2 = &i;

printf(“Character: %c %c\n”, *pcl, *pc2);

printf(“Integer : %d %d\n”, *pil, *pi2);

printf (“Float : %f %f\n”, =pfl, *pf2);

Note that the character pointer variables pcl and pc2 are initialized with the addresses of the int and float variables, respectively. Similarly, the int and float pointer variables are also initialized with addresses of variables of incompatible type. When the program containing this code is compiled in Code::Blocks, the compiler reports six warning messages (initialization from incompatible pointer type), one for each incompatible pointer initialization.

It is not a good idea to ignore such warnings associated with pointers. Although, the program executes in the presence of these warnings, it displays wrong results as shown below.

Integer : 90 1066192077

Float : 0.000000 0.000000

You’ll also like:

  • Write A C++ Program To Signify Importance Of Assignment (=) And Shorthand Assignment (+=) Operator.
  • Write C++ Example to illustrate two dimensional array implemented as pointer to a pointer.
  • Two-Dimensional Arrays Using a Pointer to Pointer
  • Declaration and Initialization of Pointers in C
  • Initialization of Two Dimensional Arrays Java

Dinesh Thakur

Dinesh Thakur is a Freelance Writer who helps different clients from all over the globe. Dinesh has written over 500+ blogs, 30+ eBooks, and 10000+ Posts for all types of clients.

For any type of query or something that you think is missing, please feel free to Contact us .

Basic Course

  • Database System
  • Management System
  • Electronic Commerce

Programming

  • Structured Query (SQL)
  • Java Servlet

World Wide Web

  • Java Script
  • HTML Language
  • Cascading Style Sheet
  • Java Server Pages

C++ Tutorial

C++ functions, c++ classes, c++ data s tructures, c++ reference, c++ examples, c++ pointers, creating pointers.

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

A pointer however, is a variable that stores the memory address as its value .

A pointer variable points to a data type (like int or string ) of the same type, and is created with the * operator. The address of the variable you're working with is assigned to the pointer:

Example explained

Create a pointer variable with the name ptr , that points to a string variable, by using the asterisk sign * ( string* ptr ). Note that the type of the pointer has to match the type of the variable you're working with.

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

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

Tip: There are three ways to declare pointer variables, but the first way is preferred:

C++ Exercises

Test yourself with exercises.

Create a pointer variable with the name ptr , that should point to a string variable named food :

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.

  • Gregg Doyel
  • Boilermakers
  • Motor Sports
  • Fighting Irish
  • High Schools
  • SportsbookWire

'The ball just kept going in.' With family courtside, Fever's Lexie Hull steals the show.

INDIANAPOLIS — Caitlin Clark is a certified fan of Lexie Hull . Just minutes after Indiana's 92-75 win over the Seattle Storm on Sunday, Clark, who has become close with Hull since she joined the team, posted on X: "This is now a Lexie Hull fan account."

"My whole account will be about Lexie," Clark joked postgame. "I'm going to change my bio to Lexie Hull Fan Page."

Her declaration was following a trend — a lot of Fever fans likely became fans of Lexie Hull, too, after her career night gave the Fever their first win of the season over the Storm.

Fever match last year's wins total... with 12 games left in 2024 season.

More: Why Caitlin Clark wants to thank ref for giving her technical foul

So far, Hull has had an up-and-down season. She was a full-time starter for the Fever in 2023, starting nearly every game and playing through a broken nose before she suffered a shoulder injury in August, keeping her out of the final month of the season.

This year, with the Fever adding Clark and wing Katie Lou Samuelson to the starting lineup, Hull transitioned to come off the bench this season. She struggled with confidence in her shot, especially coming off a shoulder injury, and sat on the bench for full games with multiple that were a DNP-Coach's Decision. Before Sunday's game, she was shooting 17-of-62 (27%) on the season.

But it was only a matter of time before she found her shot again. She worked her way back into the rotation with her defensive prowess, always taking the most difficult defensive assignment.

On Sunday, it all clicked.

Hull came off the bench and made an immediate impact, catching a ball from Clark in transition and laying it in for an easy basket. The duo did it again four minutes of game time later, giving Clark her second assist of the game — and the WNBA rookie assist record .

another angle of the record breaking assist by Caitlin Clark 😮‍💨 https://t.co/vzSuTza9Y5 pic.twitter.com/LnPE8ALkiJ — Indiana Fever (@IndianaFever) August 18, 2024

Hull's game didn't stop there — she hadn't even made a 3-pointer yet. Her two 3s in the first half marked just the fifth time in her 77-game career she had two or more treys in a game.

Then, she came alive in the fourth quarter. She made 3s on consecutive possessions with eight minutes left in the game, and the sold out Gainbridge Fieldhouse crowd got rowdier each time. Four minutes later, she made two more 3s in quick succession — achieving a new career high of 22 points on 8-of-10 shooting (6-of-7 from 3), putting the Fever up by 12, and getting fans on their feet.

"We had just really good ball movement," Hull said. "Found the open person, got to our open spots, and knocked down shots ... the ball just kept going in. So, I mean, we feed off of that, feed off of each other, and was just a fun end of that game."

She was wide open for most of those shots, too. The Storm focused on the Fever's usual best 3-point shooters, Kelsey Mitchell (who went 5-of-8 from 3-point range) and Caitlin Clark (3-of-10), giving Hull ample space to catch fire.

"She had everybody fired up," coach Christie Sides said. "Everybody. I mean, Lexie Hull puts in the work, you know, she just needed to see the ball go in the hole. And once she found that, and she caught fire. And then we started looking for her. And, you know, we've got players out there that just draw so much attention. I mean, she was shooting some wide open 3s, and she put it in for us. So proud of her."

It was even more special for Hull as some of her loved ones, including her twin sister and grandma, traveled to see Hull play Sunday. Hull and her sister, Lacie, both played at Stanford from 2018-22, but Lacie didn't pursue a basketball career beyond her collegiate years.

More: Indiana Fever even surprised Lexie Hull by drafting her. She's out to prove them right.

special moments with the fam ❤️ Lexie Hull's family was courtside to witness her career-high performance. pic.twitter.com/pNPI7TFDhx — Indiana Fever (@IndianaFever) August 18, 2024

Now, Lacie lives in Austin, Texas, while their grandmother still lives in their hometown of Spokane, Wash. To have a game like that, with family sitting courtside, made Hull's career game a magical experience.

"First of all, to get a win in front of anyone, it's great," Hull said. "To win in front of my grandma, who came all the way here from Spokane..."

"Shout out Cheryl," Clark interjected.

"Shout out Cheryl," Hull agreed, laughing. "And my sister came from Austin, it's amazing. To have them courtside was super cool, too, so really good, really good feeling tonight."

Maybe, for superstitious reasons, they'll need to sit courtside for the rest of the season."

"We might have to," Hull joked. "... We'll work on that."

Follow IndyStar Fever Insider Chloe Peterson on X at @chloepeterson67.

  • C Data Types
  • C Operators
  • C Input and Output
  • C Control Flow
  • C Functions
  • C Preprocessors
  • C File Handling
  • C Cheatsheet
  • C Interview Questions

C – Pointer to Pointer (Double Pointer)

Prerequisite: Pointers in 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 pointers or create a variable-sized 2-D array. A double pointer occupies the same amount of space in the memory stack as a normal pointer.

double pointer in c

Declaration of Pointer to a Pointer in C

Declaring Pointer to Pointer is similar to declaring a pointer in C. The difference is we have to place an additional ‘*’ before the name of the pointer.

The above diagram shows the memory representation of a pointer to a pointer. The first pointer ptr1 stores the address of the variable and the second pointer ptr2 stores the address of the first pointer.  

Example of Double Pointer in C

How Double Pointer Works?

how double pointer works in C

The working of the double-pointer can be explained using the above image:

  • The double pointer is declared using the syntax shown above.
  • After that, we store the address of another pointer as the value of this new double pointer.
  • Now, if we want to manipulate or dereference to any of its levels, we have to use Asterisk ( * ) operator the number of times down the level we want to go.

Size of Pointer to Pointer in C

In the C programming language, a double pointer behaves similarly to a normal pointer in C. So, the size of the double-pointer variable is always equal to the normal pointers. We can verify this using the below C Program.

Example 1: C Program to find the size of a pointer to a pointer.

Note: The output of the above code also depends on the type of machine which is being used. The size of a pointer is not fixed in the C programming language and it depends on other factors like CPU architecture and OS used. Usually, for a 64-bit Operating System, the size will be 8 bytes and for a 32-bit Operating system, the size will be 4 bytes.

Application of Double Pointers in C

Following are the main uses of pointer to pointers in C:

  • They are used in the dynamic memory allocation of multidimensional arrays.
  • They can be used to store multilevel data such as the text document paragraph, sentences, and word semantics.
  • They are used in data structures to directly manipulate the address of the nodes without copying.
  • They can be used as function arguments to manipulate the address stored in the local pointer.

Multilevel Pointers in C

Double Pointers are not the only multilevel pointers supported by the C language. What if we want to change the value of a double pointer?

In this case, we can use a triple pointer, which will be a pointer to a pointer to a pointer i.e, int ***t_ptr.

Syntax of Triple Pointer

Similarly, to change the value of a triple pointer we can use a pointer to a pointer to a pointer to a pointer (Four level Pointer). In other words, we can say that to change the value of a ” level – x ” variable we can use a ” level – x+1 ” pointer. And this concept can be extended further.

Note : We can use any level pointer in C. There is no restriction about it but it makes the program very complex and vulnerable to errors.

Must Read – Function Pointer in C

Please Login to comment...

Similar reads, 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.

Correctly overload assignment operator for classes with pointer members

Correct me if I'm wrong:

I understand that when having a class with members that are pointers, a copy of a class object will result in that the pointers representing the same memory address. This can result in changes done to one class object to affect all copies of this object.

A solution to this can be to overload the = operator. Given the example below, with an attempt to create a dynamic array class, why does making changes to MyArray1 change MyArray2 :

Array Class:

Example output:

As seen above, changes made to MyArray1, changes MyArray2. I assume the overloading of = is wrong, but how would I write it correctly?

Thanks to Chris Dodd in the comments, I realized it's just to implement a copy constructor like this in my class:

  • overloading

juanchopanza's user avatar

  • You've violated the rule of three –  Chris Dodd Commented Sep 8, 2016 at 6:33
  • Yes, I was realising that, that's why I deleted my comment same time as you anwered! Thank you, I will give it a shot:) –  remi Commented Sep 8, 2016 at 6:43

3 Answers 3

There is more than one issue with your code. Most importantly, as pointed out in the comment to to the question, except for writing your own assignment operator, you need to write your copy constructor as well (and implement a destructor).

Second thing is, that your assignment operator takes argument by value instead of by reference, which causes default copy constructor to create a copy of your MyArray1 before it's passed to assignment operator. This is where the direct source of your problem lays.

Another thing is that your assignment operator behaves like a move assignment instead of copy assignment, meaning it replaces the original item's values with its current (default) value.

Lastly, you really want to implement the destructor, so that it deletes your array instead of just leaking it.

Summing up, you want something like this (edit: copy assignment checks inspired by Timothy's answer):

slawekwin's user avatar

  • I noticed by changing my assignement operator to take a reference, and reruning the code, MyArray1 "loses" all it's information after doing: MyArray2 = MyArray1 –  remi Commented Sep 8, 2016 at 6:55
  • 1 "Second thing is, that your assignment operator takes argument by value instead of by reference" It is the copy any swap idiom. –  juanchopanza Commented Sep 8, 2016 at 7:20
  • @juanchopanza yes, you are obviously right, I doubt OP understood how it worked, though (because of not implementing copy constructor) –  slawekwin Commented Sep 8, 2016 at 7:51
  • can u please explain why compiler says error: this ‘if’ clause does not guard... [-Werror=misleading-indentation] 31 | if (this == &arr2) –  user786 Commented Aug 17, 2021 at 10:05

So, I see three issues.

You should really have a copy constructor. You never know what optimizations your compiler might make (changing assignment to copy-constructor, etc...).

you should check for self-assignment when assigning. When doing the assignment you want to get rid of your old data and replace it with the new. If you do self assignment, you'll run into errors (aka delete your data before you reassign to yourself) plus it's extra work you don't need to do.

you don't handle your dynamically allocated data when you call the destructor. This will cause a memory-leak and for long running programs becomes a large problem.

Code Updates:

Timothy Murphy's user avatar

  • Re. point 2, OP is using the copy and swap idiom. That would be robust against self-assignment. But it is broken because of the copy constructor. –  juanchopanza Commented Sep 8, 2016 at 7:19
  • Fair enough. Although for large arrays that causes a lot of extra work for self assignment. –  Timothy Murphy Commented Sep 8, 2016 at 8:01
  • 2 You should use delete [] for array deletion. –  DigviJay Patil Commented Sep 23, 2019 at 10:01

you can avoid all of these if you want to make = only but not Array MyArray1=MyArray2 because it also needs a copy constructor you can do this

passing by reference solve the problem but if you want to do

you need a copy constructor

and if you want selfassignment you must check

Saman Salehi'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 overloading or ask your own question .

  • The Overflow Blog
  • Battling ticket bots and untangling taxes at the frontiers of e-commerce
  • Ryan Dahl explains why Deno had to evolve with version 2.0
  • 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

  • Did the French janitor at the University of Hanoi receive a higher base pay than a Vietnamese professor?
  • Rearrange these numbers and symbols to make a true equation
  • Absolute positioning of tikz markings
  • Is the Garmin Edge 530 still a good choice for a beginner in 2024?
  • If a body in free fall, according to general relativity is weightless, that is, not experiencing force, how does the object gain kinetic energy?
  • Has any spacecraft ever been severely damaged by a micrometeriote?
  • A possibly Varley short fiction about a clone, his sister-progenitor and a complicated family history
  • Are there any well-known political considerations for having a friend on the job market come for a visit and talk?
  • Can data be preprocessed when using EdDSA with SHAKE?
  • LoginForm submission which sends sign in link to email and then sets value in localStorage
  • White to play and mate in 3 moves..what are the moves?
  • Regression with a constant sharing a coefficient with an independent variable
  • How to make outhouses less icky?
  • How to stop Windows from changing date modified when copying files from network?
  • Using 尊敬語 and 謙譲語 without 丁寧語?
  • Why would an incumbent politician or party need to be re-elected to fulfill a campaign promise?
  • Momentary solo circuit
  • VerificationTest leaks message?
  • Creating a deadly "minimum altitude limit" in an airship setting
  • What to do if sample size obtained is much larger than indicated in the power analysis?
  • Is there a good explanation for the existence of the C19 globular cluster with its very low metallicity?
  • What do all branches of Mathematics have in common to be considered "Mathematics", or parts of the same field?
  • Can there be clouds of free electrons in space?
  • No Kippa while in a car

pointer for assignment

IMAGES

  1. Amazon.com : Retractable Pointer Finger,3 Pcs Telescopic Teachers

    pointer for assignment

  2. PPT

    pointer for assignment

  3. Solved Pointer arithmetic and expressions Pointer assignment

    pointer for assignment

  4. Pointer Expressions in C with Examples

    pointer for assignment

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

    pointer for assignment

  6. Pointer Assignment in C

    pointer for assignment

COMMENTS

  1. Directly assigning values to C Pointers

    You need to create an int variable somewhere in memory for the int * variable to point at. Your second example does this, but it does other things that aren't relevant here. Here's the simplest thing you need to do: int main(){. int variable; int *ptr = &variable; *ptr = 20; printf("%d", *ptr); return 0;

  2. C++ pointer assignment

    Now we have two variables x and y: int *p = &x; int *q = &y; There are declared another two variables, pointer p which points to variable x and contains its address and pointer q which points to variable y and contains its address: x = 35; y = 46; Here you assign values to the variables, this is clear: p = q;

  3. 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:

  4. 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.

  5. C Pointers

    Pointers are one of the core components of the C programming language. A pointer can be used to store the memory address of other variables, functions, or even other pointers. The use of pointers allows low-level memory access, dynamic memory allocation, and many other functionality in C. ... Assignment of pointers of the same type. C

  6. 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.

  7. How C-Pointers Works: A Step-by-Step Beginner's Tutorial

    Declaring Pointers: To declare a pointer, you specify the data type it points to, followed by an asterisk (*), and then the pointer's name. For example: int * ptr; // Declaring an integer pointer. Here, we've declared a pointer named ptr that can point to integers. The size of pointers on 64-bit systems is usually 8 bytes (64 bits). ...

  8. Pointers in C Explained

    4. Strings. 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).

  9. Pointer declaration

    Certain addition, subtraction, compound assignment, increment, and decrement operators are defined for pointers to elements of arrays.. Comparison operators are defined for pointers to objects in some situations: two pointers that represent the same address compare equal, two null pointer values compare equal, pointers to elements of the same array compare the same as the array indices of ...

  10. Pointer Expressions in C with Examples

    C supports a rich set of built-in operations like arithmetic, relational, assignment, conditional, etc. which can be performed on identifiers. Just like any other variable, these operations can be also performed on pointer variables. Arithmetic Operators. We can perform arithmetic operations to pointer variables using arithmetic operators.

  11. Everything you need to know about pointers in C

    Assignment and pointers. Now, how do you assign an int to this pointer? This solution might be obvious: foo_ptr = 42; It is also wrong. Any direct assignment to a pointer variable will change the address in the variable, not the value at that address. In this example, the new value of foo_ptr (that is, the new "pointer" in that variable) is 42. But we don't know that this points to ...

  12. Pointer declaration

    Null pointers. Pointers of every type have a special value known as null pointer value of that type. A pointer whose value is null does not point to an object or a function (the behavior of dereferencing a null pointer is undefined), and compares equal to all pointers of the same type whose value is also null.. A null pointer constant can be used to initialize a pointer to null or to assign ...

  13. 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.

  14. Pointers

    This is a standard assignment operation, as already done many times in earlier chapters. The main difference between the second and third statements is the appearance of the address-of operator (&). The variable that stores the address of another variable (like foo in the previous example) is what in C++ is called a pointer. Pointers are a very ...

  15. 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 ...

  16. How to Pointer Assignment and Initialization in C

    This is achieved by assigning the address of that variable to the pointer variable, as shown below. int a = 10; int *pa; pa = &a; /* pointer variable pa now points to variable a */. In this example, the first line declares an int variable named a and initializes it to 10. The second line declares a pointer pa of type pointer to int.

  17. C++ Pointers

    Example explained. Create a pointer variable with the name ptr, that points to a string variable, by using the asterisk sign * ( string* ptr ). Note that the type of the pointer has to match the type of the variable you're working with. Use the & operator to store the memory address of the variable called food, and assign it to the pointer.

  18. Lexie Hull's career game leads Indiana Fever past Seattle Storm

    Hull's game didn't stop there — she hadn't even made a 3-pointer yet. Her two 3s in the first half marked just the fifth time in her 77-game career she had two or more treys in a game. Then, she ...

  19. c

    2. A pointer points to an address where a value is stored. int *ptr; int x = 2; ptr = &x; Here, ptr is an int pointer and x is an int (obviously). If we want ptr to "keep track" of the value of x then we assign ptr the address of x. So when we dereference ptr we get the value stored at the address that ptr points to.

  20. 'He's doing all the right things': How Davante Adams' mentorship has

    This gave Tucker more than enough time to slip past his assignment on a go-route and come away with a 48-yard gain. The playmaking didn't end in the first quarter.

  21. 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 ...

  22. C++ Assign Pointer to Pointer

    In both examples, you are dereferencing an uninitialized pointer, which is undefined behaviour. For the pointer assignment question, you can directly assign: int *ptr2 = ptr2; in your second example, provided you make sure ptr1 points at a valid location. For example, int x; int *ptr1 = &x; /* ptr1 now points to the address of x */. *ptr1 = 7;

  23. Will Devin Booker's 'unsung' effort in Paris earn the Suns guard more

    Stephen Curry buried a 3-pointer from the key. The Phoenix Suns guard had made plays like this throughout the Olympics. An extra pass. ... He not only accepted the assignment, he volunteered for it.

  24. c++

    4. Correct me if I'm wrong: I understand that when having a class with members that are pointers, a copy of a class object will result in that the pointers representing the same memory address. This can result in changes done to one class object to affect all copies of this object. A solution to this can be to overload the = operator.