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.

Our premium learning platform, created with over a decade of experience and thousands of feedbacks .

Learn and improve your coding skills like never before.

  • Interactive Courses
  • Certificates
  • 2000+ Challenges

Related Tutorials

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
  • 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;

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.

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.

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

be11amer profile image

Understanding Arrays and Collections in Java: Managing Groups of Data

Bellamer - Aug 22

razielrodrigues profile image

Stop letting your data unprotected!

Raziel Rodrigues - Aug 21

uicraft_by_pratik profile image

Part 1 : Capturing Attention with Motion UI CSS Animations ✨- : Fade In/Out, Slide In/Out, and Scale Up Effects 🫠

Pratik Tamhane - Aug 22

madgan95 profile image

Sorting Algorithms (DSA - 4)

Madhav Ganesan - Aug 12

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

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 = &num; 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.
  • 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 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.

  • How to Get a Free SSL Certificate
  • Best SSL Certificates Provider in India
  • Elon Musk's xAI releases Grok-2 AI assistant
  • What is OpenAI SearchGPT? How it works and How to Get it?
  • Content Improvement League 2024: From Good To A Great Article

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

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

Collectives™ on Stack Overflow

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

Q&A for work

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

Get early access and see previews of new features.

Pointer dereference in an assignment

I was watching a lecture and got confused at a point when professor said that ptr=&x denotes a variable ptr assigned the address of the variable x . And for y=*ptr+1 he said *ptr denotes the value stored at x (or the value of x ). I became slightly confused here as *ptr should be pointing towards the address of x right, not the value stored at x ? Can someone please elaborate it a bit more?

  • variable-assignment

Gilles 'SO- stop being evil''s user avatar

  • 2 *ptr refers to the entry stored at ptr . See here for an explanation en.wikipedia.org/wiki/… –  A.Schulz Commented May 17, 2013 at 17:01
  • 4 ptr refers to the address of the variable x . *ptr refers to the value in memory at the address of x . *ptr = *(&x) = x . –  Patrick87 Commented May 17, 2013 at 17:23
  • This is a question about a the behavior concrete piece of C code, not about the semantics of the C language. It is a programming question and not a computer science question, so I am migrating it to Stack Overflow . –  Gilles 'SO- stop being evil' Commented May 17, 2013 at 18:38
  • 1 You must see this –  Suvarna Pattayil Commented May 17, 2013 at 18:44

5 Answers 5

Now, in memory we have something like

Now, consider a pointer variable of type int

This looks like,

a is a label to the memory location and ap is the address. To get the value at that address you use * . This is called dereferencing the pointer.

This gives you 10

Read some good tutorial on pointer.

Suvarna Pattayil's user avatar

It is ptr that points to x , not *ptr . *ptr is not even a pointer (assuming x isn't one).

The variable ptr contains a pointer to the variable x , i.e. the address of the variable x . The value of the expression ptr is a pointer to x . The value of the expression *ptr is the value at the location that ptr points to: that's what the dereference operator * means. Since ptr points to x , the value of *ptr is the value of x .

A pointer points to an address where a value is stored.

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. So if we want to change the value that ptr "stores" then we dereference it.

This changes the value at the address ptr points to from 2 to 5.

thaweatherman's user avatar

x is an integer object (of type int ), and ptr is a pointer object (of type int* or pointer-to- int ).

Unary & is the address operator. Applying it to an object of type FOO gives you the address of that object (or, equivalently, a pointer to that object); that address/pointer value is of type FOO* , or pointer-to- FOO . The operand of unary & must be the name of an object, not just a value; &42 is illegal nonsense. (The symbol & is also used for the binary bitwise and operator, which is completely unrelated to the address operator.)

Unary * is the dereference operator, the inverse of & . Its operand must be value of some pointer type. *ptr refers to the object to which ptr points.

Given the above declarations, and assuming the value of ptr hasn't been changed, the expressions x and *ptr mean the same thing; they both refer to the same int object (whose value happens to be 42). Similarly, the expressions &x and ptr mean the same thing; they both yield the address of x , an address that has been stored in the pointer object ptr .

It's important to note that *ptr doesn't just refer to the current value of x , it refers to the object x itself -- just like the name x does. If you use *ptr in a value context, this doesn't matter; you'll just get the value of x . But if you use it on the left side of an assignment, for example, it doesn't evaluate to 42 . It evaluates to the object x itself, and lets you modify that object. (The distinction here is whether *ptr is used as an lvalue .)

Keith Thompson's user avatar

  • 1 Is there a mistake in the first excerpt –  Antti Haapala -- Слава Україні Commented Jan 5, 2020 at 12:30
  • @AnttiHaapala: Not anymore. Thanks! –  Keith Thompson Commented Jan 6, 2020 at 0:25

The variable ptr stores the address of x . To retrieve the value stored at x , we dereference ptr with the unary * operator; hence, the expression *ptr evaluates to the value of x .

Put another way, if

John Bode'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 variable-assignment or ask your own question .

  • The Overflow Blog
  • From PHP to JavaScript to Kubernetes: how one backend engineer evolved over time
  • Where does Postgres fit in a world of GenAI and vector databases?
  • 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...
  • What does a new user need in a homepage experience on Stack Overflow?
  • Staging Ground Reviewer Motivation

Hot Network Questions

  • Help, I planted Marigolds and they look like they are dying
  • What are the limits of Terms of Service as a legal shield for a company?
  • Is く in 驚く here not just devoiced but completely removed?
  • Order of connection using digital multimeter wall outlet
  • Need strftime() output in the buffer
  • Did US troops insist on segregation in British pubs?
  • What is the spiritual difference between hungering and thirsting? (Matthew 5:6)
  • What can I do when someone else is literally duplicating my PhD work?
  • で as です or condition?
  • Are there different conventions for 'rounding to even'?
  • Repeating zsh brace expansion values in zsh to download multiple files using wget2
  • Validity of ticket when using alternative train from a different station
  • Completely introduce your friends
  • Why does Russia strike electric power in Ukraine?
  • Can I use "historically" to mean "for a long time" in "Historically, the Japanese were almost vegetarian"?
  • Why do I get two values for the following limit using two different methods with the same identity?
  • What does "garb" mean in this passage?
  • Why do National Geographic and Discovery Channel broadcast fake or pseudoscientific programs?
  • Trying to find an old book (fantasy or scifi?) in which the protagonist and their romantic partner live in opposite directions in time
  • Inconsistent “unzip -l … | grep -q …” results with pipefail
  • How can I draw water level in a cylinder like this?
  • Does a MySQL replication slave need to be as powerful as the master?
  • default-valued optional (boolean) parameter for a new command in tikz
  • How do I safely remove a mystery cast iron pipe in my basement?

pointer for assignment

Rewiring the classroom: How the COVID-19 pandemic transformed K-12 education

Subscribe to the brown center on education policy newsletter, brian a. jacob and brian a. jacob walter h. annenberg professor of education policy; professor of economics, and professor of education - university of michigan, former brookings expert cristina stanojevich cs cristina stanojevich doctoral student - michigan state university.

August 26, 2024

  • The pandemic changed K-12 classrooms through new technologies, instructional practices, and parent-teacher communications, along with an emphasis on social-emotional learning.
  • Less tangibly, COVID-19 might have shifted perceptions of the value and purposes of K-12 schooling.
  • The durability and effects of these changes remain unclear and will depend on how educational leaders and policymakers manage them.

In March 2020, virtually all public school districts in the U.S. shut their doors. For the next 18 months, schooling looked like it never had before. Homes became makeshift classrooms; parents became de facto teachers. But by fall 2022, many aspects of K-12 education had returned to “normal.” Schools resumed in-person classes, extracurricular activities flourished, and mask mandates faded.

But did schools really return to what they were before the COVID-19 pandemic? Our research suggests not. We interviewed teachers, school leaders, and district administrators across 12 districts in two states, and then we surveyed a nationally representative set of veteran educators in May 2023. We found that the COVID-19 pandemic transformed K-12 education in fundamental ways.

Below, we describe how the pandemic reshaped the educational landscape in these ways and we consider the opportunities and challenges these changes present for students, educators, and policymakers.

Accelerated adoption of technology

One of the most immediate and visible changes brought about by the pandemic was the rapid integration of technology into the classroom. Before COVID-19, many schools were easing into the digital age. The switch to remote learning in March 2020 forced schools to fully embrace Learning Management Systems (LMS), Zoom, and educational software almost overnight.

When students returned to in-person classrooms, the reliance on these digital tools persisted. Over 70% of teachers in our survey report that students are now assigned their own personal device (over 80% for secondary schools). LMS platforms like Google Classroom and Schoology remain essential in many schools. An assistant superintendent of a middle-income district remarked, “Google Classroom has become a mainstay for many teachers, especially middle school [and] high school.”

The platforms serve as hubs for posting assignments, accessing educational content, and enabling communication between teachers, students, and parents. They have become popular among parents as well. One teacher, who has school-age children herself, noted :

“Whereas pre-COVID…you’re hoping and praying your kids bring home information…[now] I can go on Google classroom and be like, ‘Oh, it says you worked on Mesopotamia today. What was that lesson about?’”

Transformed instructional practices

The pandemic’s impact on student learning was profound. Reading and math scores dropped precipitously, and the gap widened between more and less advantaged students. Many schools responded by adjusting their schedules or adopting new programs. Several mentioned adopting “What I need” (WIN) or “Power” blocks to accommodate diverse learning needs. During these blocks, teachers provide individualized support to students while others work on independent practice or extension activities.

Teachers report placing greater emphasis on small-group instruction and personalized learning. They spend less time on whole-class lecture and rely more on educational software (e.g., Lexia for reading and Zearn for math) to tailor instruction to individual student needs. A third-grade teacher in a low-income district explained:

“The kids are in so many different places, Lexia is very prescriptive and diagnostic, so it will give the kids specifically what level and what skills they need. [I] have a student who’s working on Greek and Latin roots, and then I have another kid who’s working on short vowel sounds. [It’s] much easier for them to get it through Lexia than me trying to get, you know, 18 different reading lessons.”

Teachers aren’t just using technology to personalize instruction. Having spent months gaining expertise with educational software, more teachers find it natural to integrate those programs into their classrooms today. Those teachers who used ed tech before report doing so even more now. They describe using software like Flowcabulary and Prodigy to make learning more engaging, and games such as Kahoot to give students practice with various skills. Products like Nearpod let them create presentations that integrate instruction with formative assessment. Other products, like Edpuzzle, help teachers monitor student progress.

Some teachers discovered how to use digital tools to save time and improve their communications to students. One elementary teacher, for example, explains even when her students complete an assignment by hand, she has them take a picture of it and upload it to her LMS:

“I can sort them, and I can comment on them really fast. So it’s made feedback better. [I have] essentially a portfolio of all their math, rather than like a hard copy that they could lose…We can give verbal feedback. I could just hit the mic and say, ‘Hey, double check number 6, your fraction is in fifths, it needs to be in tenths.’”

Increased emphasis on social-emotional learning

The pandemic also revealed and exacerbated the social-emotional challenges that students face. In our survey, nearly 40% of teachers report many more students struggling with depression and anxiety than before the COVID-19 pandemic; over 80% report having at least a few more students struggling.

These student challenges have changed teachers’ work. When comparing how they spend class time now versus before the pandemic, most teachers report spending more time on activities relating to students’ social-emotional well-being (73%), more time addressing behavioral issues (70%), and more time getting students caught up and reviewing routines and procedures (60%).

In response, schools have invested in social-emotional learning (SEL) programs and hired additional counselors and social workers. Some districts turned to online platforms such as Class Catalyst and CloseGap that allow students to anonymously report their emotional state on a daily basis, which helps school staff track students’ mental health.

Teachers also have been adapting their expectations of students. Many report assigning less homework and providing students more flexibility to turn in assignments late and retake exams.

Facilitated virtual communication between parents and teachers

The pandemic also radically reshaped parent-teacher communications. Mirroring trends across society, videoconferencing has become a go-to option. Schools use videoconferencing for regular parent-teacher conferences, along with meetings to discuss special education placements and disciplinary incidents. In our national survey, roughly one-half of teachers indicate that they conduct a substantial fraction of parent-teacher conferences online; nearly a quarter of teachers report that most of their interactions with parents are virtual.

In our interviews, teachers and parents gushed about the convenience afforded by videoconferencing, and some administrators believe it has increased overall parent participation. (One administrator observed, “Our attendance rates [at parent-teacher conferences] and interaction with parents went through the roof.”)

An administrator from a low-income district shared the benefits of virtual Individualized Education Plan (IEP) meetings:

“It’s rare that we have a face-to-face meeting…everything is Docusigned now. Parents love it because I can have a parent that’s working—a single mom that’s working full time—that can step out during her lunch break…[and] still interact with everybody.”

During the pandemic, many districts purchased a technology called Remind that allows teachers to use their personal smartphones to text with parents while blocking their actual phone number. We heard that teachers continue to text with parents, citing the benefits for quick check-ins or questions. Remind and many LMS also have translation capabilities that makes it easier for teachers and parents to overcome language barriers.

Moving forward

The changes described above have the potential to improve student learning and increase educational equity. They also carry risks. On the one hand, the growing use of digital tools to differentiate instruction may close achievement gaps, and the ubiquity of video conferencing could allow working parents to better engage with school staff. On the other hand, the overreliance on digital tools could harm students’ fine motor skills (one teacher remarked, “[T]heir handwriting sucks compared to how it used to be”) and undermine student engagement. Some new research suggests that relying on digital platforms might impede learning relative to the old-fashioned “paper and pencil” approach. And regarding virtual conferences, the superintendent of a small, rural district told us, “There’s a disconnect when we do that…No, I want the parents back in our buildings, I want people back. We’re [the school] a community center.”

Of course, some of the changes we observed may not persist. For example, fewer teachers may rely on digital tools to tailor instruction once the “COVID cohorts” have aged out of the system. As the emotional scars of the pandemic fade, schools may choose to devote fewer resources to SEL programming. It’s important to note, too, that many of the changes we found come from the adoption of new technology, and the technology available to educators will continue to evolve (e.g., with the integration of new AI technologies into personalized tutoring systems). That being said, now that educators have access to more instructional technology and—perhaps more importantly—greater familiarity with using such tools, they might continue to rely on them.

The changes brought about by the COVID-19 pandemic provide a unique opportunity to rethink and improve the structure of K-12 education. While the integration of technology and the focus on social-emotional learning offer promising avenues for enhancing student outcomes, they also require continuous evaluation. Indeed, these changes raise some questions beyond simple cost-benefit calculations. For example, the heightened role of ed tech raises questions about the proper role of the private sector in public education. As teachers increasingly “outsource” the job of instruction to software products, what might be lost?

Educational leaders and policymakers must ensure that these pandemic-inspired changes positively impact learning and address the evolving needs of students and teachers. As we navigate this new educational landscape, the lessons learned from this unprecedented time can serve as a guide for building a more resilient, equitable, and effective educational system for the future.

Beyond technological changes, COVID-19 shifted perspectives about K-12 schooling. A middle-school principal described a new mentality among teachers in her district, “I think we have all become more readily able to adapt…we’ve all learned to assess what we have in front of us and make the adjustments we need to ensure that students are successful.” And a district administrator emphasized how the pandemic highlighted the vital role played by schools:

“…we saw that when students were not in school. From a micro and macro level, the environment that a school creates to support you growing up…we realized how needed this network is…both academically and socially, in growing our citizens up to be productive in the world. And we are happy to have everyone back.”

At the end of the day, this realization may be one of the pandemic’s most enduring legacies.

Related Content

Monica Bhatt, Jonathan Guryan, Jens Ludwig

June 3, 2024

Douglas N. Harris

August 29, 2023

September 27, 2017

Education Access & Equity Education Policy Education Technology K-12 Education

Governance Studies

U.S. States and Territories

Brown Center on Education Policy

Spelman College, Atlanta Georgia

7:00 pm - 12:30 pm EDT

Nicol Turner Lee

August 8, 2024

Online Only

10:00 am - 12:30 pm EDT

cppreference.com

Std:: shared_ptr.

(C++20)
(C++20)
(C++11)
(C++20)
(C++17)
(C++11)
(C++11)
(basic types, RTTI)
(C++20)
(C++20)
three_way_comparable_with (C++20)
   
is_ltis_lteq (C++20)(C++20)
is_gtis_gteq (C++20)(C++20)
General utilities
(C++20)
(deprecated in C++20)
rel_ops::operator>
rel_ops::operator>=
cmp_lesscmp_less_than (C++20)(C++20)   
cmp_greatercmp_greater_than (C++20)(C++20)


  
  
(until C++23)
(until C++23)
(until C++23)
(until C++23)
(until C++23)
(until C++23)



)
)
)
start_lifetime_as_array (C++23)

)

Member functions
Modifiers
Observers
shared_ptr::operator->
)
Non-member functions
make_shared_for_overwrite (C++20)
allocate_shared_for_overwrite (C++20)
dynamic_pointer_castconst_pointer_castreinterpret_pointer_cast (C++17)
operator!=operator<operator<=operator>operator>=operator<=> (until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20)
)
Helper classes
(C++17)
< class T > class shared_ptr; (since C++11)

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer. Several shared_ptr objects may own the same object. The object is destroyed and its memory deallocated when either of the following happens:

  • the last remaining shared_ptr owning the object is destroyed;
  • the last remaining shared_ptr owning the object is assigned another pointer via operator= or reset() .

The object is destroyed using delete-expression or a custom deleter that is supplied to shared_ptr during construction.

A shared_ptr can share ownership of an object while storing a pointer to another object. This feature can be used to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get() , the dereference and the comparison operators. The managed pointer is the one passed to the deleter when use count reaches zero.

A shared_ptr may also own no objects, in which case it is called empty (an empty shared_ptr may have a non-null stored pointer if the aliasing constructor was used to create it).

All specializations of shared_ptr meet the requirements of CopyConstructible , CopyAssignable , and LessThanComparable and are contextually convertible to bool .

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different shared_ptr objects without additional synchronization even if these objects are copies and share ownership of the same object. If multiple threads of execution access the same shared_ptr object without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the std::atomic<shared_ptr> can be used to prevent the data race.

Member types Member functions Modifiers Observers Non-member functions Helper classes Deduction guides (since C++17) Notes Implementation notes Example Example See also

[ edit ] Member types

Member type Definition
T (until C++17)
<T> (since C++17)

[ edit ] Member functions

constructs new
(public member function)
destructs the owned object if no more s link to it
(public member function)
assigns the
(public member function)
replaces the managed object
(public member function)
swaps the managed objects
(public member function)
returns the stored pointer
(public member function)
operator-> dereferences the stored pointer
(public member function)
provides indexed access to the stored array
(public member function)
returns the number of objects referring to the same managed object
(public member function)
checks whether the managed object is managed only by the current object
(public member function)
checks if the stored pointer is not null
(public member function)
provides owner-based ordering of shared pointers
(public member function)
provides owner-based hashing of shared pointers
(public member function)
provides owner-based equal comparison of shared pointers
(public member function)

[ edit ] Non-member functions

make_shared_for_overwrite (C++20) creates a shared pointer that manages a new object
(function template)
allocate_shared_for_overwrite (C++20) creates a shared pointer that manages a new object allocated using an allocator
(function template)
dynamic_pointer_castconst_pointer_castreinterpret_pointer_cast (C++17) applies , , , or to the stored pointer
(function template)
returns the deleter of specified type, if owned
(function template)
operator!=operator<operator<=operator>operator>=operator<=> (removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) compares with another or with nullptr
(function template)
outputs the value of the stored pointer to an output stream
(function template)
specializes the algorithm
(function template)
std::atomic_load(std::shared_ptr)std::atomic_load_explicit(std::shared_ptr)std::atomic_store(std::shared_ptr)std::atomic_store_explicit(std::shared_ptr)std::atomic_exchange(std::shared_ptr)std::atomic_exchange_explicit(std::shared_ptr)std::atomic_compare_exchange_weak(std::shared_ptr)std::atomic_compare_exchange_strong(std::shared_ptr)std::atomic_compare_exchange_weak_explicit(std::shared_ptr)std::atomic_compare_exchange_strong_explicit(std::shared_ptr) (removed in C++26) specializes atomic operations for
(function template)

[ edit ] Helper classes

atomic shared pointer
(class template specialization)
hash support for
(class template specialization)

[ edit ] Deduction guides (since C++17)

[ edit ] notes.

The ownership of an object can only be shared with another shared_ptr by copy constructing or copy assigning its value to another shared_ptr . Constructing a new shared_ptr using the raw underlying pointer owned by another shared_ptr leads to undefined behavior.

std::shared_ptr may be used with an incomplete type T . However, the constructor from a raw pointer ( template < class Y > shared_ptr ( Y * ) ) and the template < class Y > void reset ( Y * ) member function may only be called with a pointer to a complete type (note that std::unique_ptr may be constructed from a raw pointer to an incomplete type).

The T in std :: shared_ptr < T > may be a function type: in this case it manages a pointer to function, rather than an object pointer. This is sometimes used to keep a dynamic library or a plugin loaded as long as any of its functions are referenced:

[ edit ] Implementation notes

In a typical implementation, shared_ptr holds only two pointers:

  • the stored pointer (one returned by get() );
  • a pointer to control block .

The control block is a dynamically-allocated object that holds:

  • either a pointer to the managed object or the managed object itself;
  • the deleter (type-erased);
  • the allocator (type-erased);
  • the number of shared_ptr s that own the managed object;
  • the number of weak_ptr s that refer to the managed object.

When shared_ptr is created by calling std::make_shared or std::allocate_shared , the memory for both the control block and the managed object is created with a single allocation. The managed object is constructed in-place in a data member of the control block. When shared_ptr is created via one of the shared_ptr constructors, the managed object and the control block must be allocated separately. In this case, the control block stores a pointer to the managed object.

The pointer held by the shared_ptr directly is the one returned by get() , while the pointer/object held by the control block is the one that will be deleted when the number of shared owners reaches zero. These pointers are not necessarily equal.

The destructor of shared_ptr decrements the number of shared owners of the control block. If that counter reaches zero, the control block calls the destructor of the managed object. The control block does not deallocate itself until the std::weak_ptr counter reaches zero as well.

In existing implementations, the number of weak pointers is incremented ( [1] , [2] ) if there is a shared pointer to the same control block.

To satisfy thread safety requirements, the reference counters are typically incremented using an equivalent of std::atomic::fetch_add with std::memory_order_relaxed (decrementing requires stronger ordering to safely destroy the control block).

[ edit ] Example

Possible output:

[ edit ] See also

smart pointer with unique object ownership semantics
(class template)
weak reference to an object managed by
(class template)
  • 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 12 July 2024, at 06:43.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

IMAGES

  1. PPT

    pointer for assignment

  2. Solved Pointer arithmetic and expressions Pointer assignment

    pointer for assignment

  3. Pointer Expressions in C with Examples

    pointer for assignment

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

    pointer for assignment

  5. Pointer Assignment in C

    pointer for assignment

  6. Pointer Assignment

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

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

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

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

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

  8. 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). ...

  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. How to Use Pointers in C Programming

    How to Declare a Pointer. To declare a pointer variable in C, we use the asterisk * symbol before the variable name. There are two ways to declare pointer variables in C: int *p; int* p; Both of these declarations are equivalent and they declare a pointer variable named "p" that can hold the memory address of an integer.

  11. 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).

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

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

  15. Pointers

    In general, pointer is a type of a variable that stores a link to another object. In C and C++, the link is the address of that object in the program memory. Pointers allow to refer to the same object from multiple locations of the source code without copying the object. Also, the same pointer variable may refer to different objects during its ...

  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++ 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;

  18. c

    C declarations are based on the types of expressions, not objects. If p is a pointer to an int, and we want to refer to the pointed-to value, we use the * operator to dereference it, like so: x = *p; The type of the expression *p is int, so the declaration is written as. int *p; answered May 10, 2016 at 17:27.

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

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

  21. Rewiring the classroom: How the COVID-19 pandemic transformed K-12

    Alyssa Pointer/REUTERS 9 min read; Print. Sections. Contact ... One elementary teacher, for example, explains even when her students complete an assignment by hand, she has them take a picture of ...

  22. std::shared_ptr

    std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer. Several shared_ptr objects may own the same object. The object is destroyed and its memory deallocated when either of the following happens: the last remaining shared_ptr owning the object is destroyed; ; the last remaining shared_ptr owning the object is assigned another pointer via operator= or ...