It declares a pointer to a char pointer.

The usage of such a pointer would be to do such things like:

void setCharPointerToX(char ** character) {
   *character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
}
char *y;
setCharPointerToX(&y); //using the address-of (&) operator here
printf("%s", y); //x

Here's another example:

char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome

Use of ** with arrays:

char** array = malloc(sizeof(*array) * 2); //2 elements

(*array) = "Hey"; //equivalent to array[0]
*(array + 1) = "There";  //array[1]

printf("%s", array[1]); //outputs There

The [] operator on arrays does essentially pointer arithmetic on the front pointer, so, the way array[1] would be evaluated is as follows:

array[1] == *(array + 1);

This is one of the reasons why array indices start from 0, because:

array[0] == *(array + 0) == *(array);
Answer from Jacob Relkin on Stack Overflow
Top answer
1 of 5
57

It declares a pointer to a char pointer.

The usage of such a pointer would be to do such things like:

void setCharPointerToX(char ** character) {
   *character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
}
char *y;
setCharPointerToX(&y); //using the address-of (&) operator here
printf("%s", y); //x

Here's another example:

char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome

Use of ** with arrays:

char** array = malloc(sizeof(*array) * 2); //2 elements

(*array) = "Hey"; //equivalent to array[0]
*(array + 1) = "There";  //array[1]

printf("%s", array[1]); //outputs There

The [] operator on arrays does essentially pointer arithmetic on the front pointer, so, the way array[1] would be evaluated is as follows:

array[1] == *(array + 1);

This is one of the reasons why array indices start from 0, because:

array[0] == *(array + 0) == *(array);
2 of 5
51

C and C++ allows the use of pointers that point to pointers (say that five times fast). Take a look at the following code:

char a;
char *b;
char **c;

a = 'Z';
b = &a; // read as "address of a"
c = &b; // read as "address of b"

The variable a holds a character. The variable b points to a location in memory that contains a character. The variable c points to a location in memory that contains a pointer that points to a location in memory that contains a character.

Suppose that the variable a stores its data at address 1000 (BEWARE: example memory locations are totally made up). Suppose that the variable b stores its data at address 2000, and that the variable c stores its data at address 3000. Given all of this, we have the following memory layout:

MEMORY LOCATION 1000 (variable a): 'Z'
MEMORY LOCATION 2000 (variable b): 1000 <--- points to memory location 1000
MEMORY LOCATION 3000 (variable c): 2000 <--- points to memory location 2000
🌐
Quora
quora.com › What-is-the-use-of-double-asterisk-before-an-integer-variable-name-in-C-programming
What is the use of double asterisk (* *) before an integer variable name in C programming? - Quora
Answer (1 of 2): If you define a variable, say p, as int **p, you are not declaring an integer but a pointer to one or more integer pointers. Although you may declare it with or without spaces between the asterisks, it’s easier to understand if you write int* *p instead.
Discussions

pointers - In C, what does double asterisk ** in parameters of a function do - Stack Overflow
I came across a code snippet in linked list but this is the first time I see "**" double asterisk used in parameters. What does it do? // Adding an item to the beginning of the list void ... More on stackoverflow.com
🌐 stackoverflow.com
Could someone explain the use of the asterisk * in C and how it is used?
Is it just that it means different things depending on how it is used Yes. Just like it can also mean multiplication. int* a = malloc(5 * sizeof(*a)); ^ ^ ^ Dereferencing "Pointer to" Multiplication More on reddit.com
🌐 r/C_Programming
18
10
April 26, 2022
history - Why does C use the asterisk for pointers? - Software Engineering Stack Exchange
I'm just now learning about C. I find it odd that the creators chose the asterisk (*) as the symbol for pointers rather than a symbol that actually looks like a pointer (->). Considering how More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
August 1, 2014
Why do we need two asterisks when we wan - C++ Forum
I know that when you want to pass ... So when you want to pass an int or double by reference you put an asterisk after the data type in the function definition void example(int* a) and an ampersand in front of the data when you call the function in main example(&x) ... More on cplusplus.com
🌐 cplusplus.com
🌐
GeeksforGeeks
geeksforgeeks.org › c language › c-pointer-to-pointer-double-pointer
C - Pointer to Pointer (Double Pointer) - GeeksforGeeks
They can be used as function arguments to manipulate the address stored in the local pointer. 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?
Published   October 25, 2025
Top answer
1 of 3
5

If you have a variable like for example

int x = 10;

and want to change it in a function you need to pass it to the function by reference.

In C passing by reference means passing a variable indirectly through a pointer to it. Thus dereferencing the pointer within the function you have a direct access to the original variable and can change it.

Here is a demonstration program.

#include <stdio.h>

void f( int *px )
{
    *px = 20;
}

int main( void )
{
    int x = 10;

    printf( "Before calling f x = %d\n", x );

    f( &x );

    printf( "After  calling f x = %d\n", x );
}

The program output is

Before calling f x = 10
After  calling f x = 20

If a variable has a pointer type like for example

node_t *head = NULL;

then again if you are going to change its value in a function you need to pass it to the function by reference as for example

push( &head, 10 );

So the corresponding function parameter will be declared like

void push(node_t ** head, int val);

And dereferencing the pointer to the original pointer head like

*head = new_node;

you can change the original pointer head defined in main.

If you will not pass the pointer by reference but pass it by value then the function will deal with a copy of the value of the original pointer. Changing the copy does not influence on the original pointer.

Consider the preceding demonstration program where the original variable is passed to the function by value

#include <stdio.h>

void f( int x )
{
    x = 20;
}

int main( void )
{
    int x = 10;

    printf( "Before calling f x = %d\n", x );

    f( x );

    printf( "After  calling f x = %d\n", x );
}

In this case the original variable x will not be changed. It is a copy of its value that was changed within the function. So the program output will be

Before calling f x = 10
After  calling f x = 10
2 of 3
2

In this case, it declares a pointer to a node_t pointer, which is a function parameter.

Here is a simple example using character pointers:

char *charPointer = "This is a text.";
char **pointerToCharPointer = &charPointer;

printf("%s\n", charPointer);
(*pointerToCharPointer) = "This is something new.";
printf("%s\n", charPointer);

Output:

This is a text.
This is something new.
🌐
Codedamn
codedamn.com › news › c programming
What are double pointers in C?
March 10, 2024 - They store the address of a pointer variable, allowing for dynamic and complex data structures like linked lists and trees. A double pointer is declared by using two asterisks (**) before the variable name.
🌐
Reddit
reddit.com › r/c_programming › could someone explain the use of the asterisk * in c and how it is used?
r/C_Programming on Reddit: Could someone explain the use of the asterisk * in C and how it is used?
April 26, 2022 -

I am currently working on an assignment in C where we are required to make a stack by simply using pointers.

I know the line: int *ptr = &val; declares ptr to be a "pointer to"(which is my interpretation of what asterisk * means in C) the "address of" the integer variable val.

When I want to create a double pointer, or a pointer to a pointer, I do so like:

int **ptr_ptr = &ptr; By setting ptr_ptr to a "pointer to" the address of pointer ptr.

When we use the asterisk anywhere other than in a declaration, it is usually referred to as dereferencing that pointer (I think), and grabbing the value that the pointer actually points to. This goes against my intuition that an asterisk means "pointer to".

Could anybody explain the proper meaning of the asterisk in C? Is it just that it means different things depending on how it is used (i.e. in a declaration versus anywhere else)?

Thanks!

🌐
TutorialsPoint
tutorialspoint.com › home › cprogramming › c pointer to pointer
C Pointer to Pointer
June 10, 2012 - int **c = &b; printf("b: %d \nPointer ... b: 6422036 · Here, "c" is a double pointer. The first asterisk in its declaration points to "b" and the second asterisk in turn points to "a"....
Find elsewhere
🌐
Sololearn
sololearn.com › en › Discuss › 1607822 › whats-the-difference-between-qp-and-qp-why-is-there-2-asterisks
What's the difference between *q=&p and **q=&p? Why is there 2 asterisks? | Sololearn: Learn to code for FREE!
December 2, 2018 - EDIT: pls see also Bennett Post ... address stored in the contents of memory address q. Two asterisks mean the variable is a pointer to a pointer....
Top answer
1 of 2
80

Why does C use the asterisk for pointers?

Simply - because B did.

Because memory is a linear array, it is possible to interpret the value in a cell as an index in this array, and BCPL supplies an operator for this purpose. In the original language it was spelled rv, and later !, while B uses the unary *. Thus, if p is a cell containing the index of (or address of), or pointer to) another cell, *p refers to the contents of the pointed-to cell, either as a value in an expression or as the target of an assignment.

From The Development of the C Language

Thats it. At this point, the question is as uninteresting as "why does python 3 use . to call a method? Why not ->?" Well... because Python 2 uses . to call a method.

Rarely does a language exist from nothing. It has influences and is based on something that came before.


So, why didn't B use ! for derefrencing a pointer like its predecessor BCPL did?

Well, BCPL was a bit wordy. Instead of && or || BCPL used logand and logor. This was because most keyboards din't have or keys and not equal was actually the word NEQV (see The BCPL Reference Manual).

B appears to have been partially inspired to tighten up the syntax rather than have long words for all these logical operators that programmers did fairly frequently. And thus ! for dereference became * so that ! could be used for logical negation. Note there's a difference between the unary * operator and the binary * operator (multiplication).


Well, what about other options, like ->?

The -> was taken for syntactic sugar around field derefrences struct_pointer->field which is (*struct_pointer).field

Other options like <- could create ambiguous parsings. For example:

 foo <- bar

Is that to be read as:

(foo) <- (bar)

or

(foo) < (-bar)

Making a unary operator that is composed of a binary operator and another unary operator is quite likely to have problems as the second unary operator may be a prefix for another expression.

Furthermore, it is again important to try to keep the things being typed frequently to a minimum. I would hate to have to write:

int main(int argc, char->-> argv, char->-> envp)

This also becomes difficult to read.

Other characters might have been possible (the @ wasn't used until Objective C appropriated it). Though again, this goes to the core of 'C uses * because B did'. Why didn't B use @? Well, B didn't use all the characters. There was no bpp program (compare cpp) and other characters were available in B (such as # which was later used by cpp).

If I may hazard a guess as to why - its because of where the keys are. From a manual on B:

To facilitate manipulation of addresses when it seems advisable, B provides two unary address operators, * and &. & is the address operator so &x is the address of x, assuming it has one. * is the indirection operator; *x means "use the content of x as an address."

Note that & is shift-7 and * is shift-8. Their proximity to each other may have been a hint to the programmer as to what they do... but that's only a guess. One would have to ask Ken Thompson about why that choice was made.


So, there you have it. C is that way because B was. B is that way because it wanted to change from how BCPL was.

2 of 2
117

I was asked by a student if & and * were chosen because they were next to each other on the keyboard (something I had never noticed before). Much googling led me to B and BCPL documentation, and this thread. However, I couldn't find much at all. It seemed like there were lots of reasons for * in B, but I couldn't find anything for &.

So following @MichaelT's suggestion, I asked Ken Thompson:

From: Ken Thompson < [email protected] >

near on the keyboard: no.
c copied from b so & and * are same there.
b got * from earlier languages - some assembly,
bcpl and i think pl/1.
i think that i used & because the name (ampersand)
sounds like "address." b was designed to be run with
a teletype model 33 teletype. (5 bit baud-o code)
so the use of symbols was restricted.

🌐
Cplusplus
cplusplus.com › forum › beginner › 209581
Why do we need two asterisks when we wan - C++ Forum
I know that when you want to pass something by reference you are basically using pointers to point to the address of the data type. So when you want to pass an int or double by reference you put an asterisk after the data type in the function definition void example(int* a) and an ampersand ...
🌐
Reddit
reddit.com › r/learnprogramming › i don't understand double pointers in c
r/learnprogramming on Reddit: I don't understand double pointers in C
September 9, 2020 -

So I understand pointers. An int * would point to the address of an integer. I understand how you could have a struct pointer and all that. I even sort of understand double pointers. An int ** would be a pointer, pointing to another pointer, which is pointing to an integer. I think that's right but I could be wrong. It's just when I see it in code my brain has a hard time grasping it. I'm looking at a past lab from a course to try to understand it, and I just don't really get it.

So in the lab we were given a struct student, which in itself has two pointer variables among others. We have to read in a file, with the first line containing three integers. The first is the number of courses, C. The next integer is N, which is the number of students per course. In the code, they do fscanf to take in the first few integers. I understand that. Then they allocate memory for courses using calloc.

The line is: student** courses = calloc(*C, sizeof(student*));

This is all inside a function which returns another student**. This is where I get lost. A struct double pointer still is hard for me to grasp. My friend said it's like an array of structs, but I still don't really get it.

Maybe if someone could explain them, or give me a resource that will explain them I would really appreciate it.

Top answer
1 of 3
2
Here's the critical piece of information you need to reason about pointers. A pointer is a variable that holds an address. That's it. That's all you need to know. From there you should be able to reason about anything pointer related. It will still be mind bendy for a time, but always start there. int i = 42; This is a variable that holds an integer. No problem. int *p = &i; This is a variable that holds an address. Specifically an address of an integer, but don't really worry about that. Just remember, it's an address. int **double_p = &p; This is also a variable that holds an address. The only difference is what it holds an address of. It holds the address of the variable p. p holds an address of an int. student** courses = calloc(*C, sizeof(student*)); To help understand this, take a step back for a moment. int *foo = calloc(16, sizeof(int)); foo holds the address of an int. calloc sets aside enough memory for 16 ints, and then returns the address of the "zeroth" element of that dynamically allocated array. foo then holds the address of the start of that array. OK, now back to the confusing line of code. student** courses = calloc(*C, sizeof(student*)); courses holds an address. The type of data at that address? Another pointer, specifically, a pointer to a student struct. So, calloc will set aside enough memory for an array to hold a bunch of memory addresses. calloc is going to return the address of the "zeroth" element of that array. Each element of that array will be able to hold a memory address of a student struct.
2 of 3
1
A pointer can be thought of as a reference to something else by specifying the location of that thing. If you want to deliver a package to my house, you aren’t going to ask me to bring my house to you because that’s silly. Instead, you ask me for the address of my house and then you go to that address and drop off the package. You have to dereference (go to an address) just once to get to the house, so this is a single pointer. A pointer to a pointer is the same thing, just with another reference layer. I don’t want anyone to overhear where my house is, so instead of telling you it’s address directly, I write the address on a piece of paper and I hide it somewhere. I then tell you where to find the piece of paper. To get to my house, you first have to go to the paper’s address, read it, then go to the address that’s written on it. You have to dereference twice in order to get to the house, so this is a double pointer.
🌐
Microsoft Learn
learn.microsoft.com › en-us › answers › questions › 1339316 › why-asterisk-is-used-with-data-type-in-type-conver
Why asterisk is used with data type in type conversion wit a pointer? - Microsoft Q&A
July 31, 2023 - In your call to printf, the parenthetical expression before ab_ptr is called a cast operator. It causes the compiler to generate the code necessary to convert the value of ab_ptr (the address it contains) from one type to another. The asterisk in this expression is also NOT a dereference operator.
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › cpp-pointer-to-pointer-double-pointer
C++ Pointer To Pointer (Double Pointer) - GeeksforGeeks
August 2, 2025 - The below diagram explains the concept of Double Pointers: 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. In the C++ programming language double pointer behave similarly to a normal pointer.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 109639-pointer-double-asterisk.html
pointer with double asterisk - C Board - Cprogramming.com
It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
🌐
Codecademy
codecademy.com › docs › pointers › double pointer
C | Pointers | Double Pointer | Codecademy
May 29, 2025 - Includes 6 CoursesIncludes 6 Courses · With Professional CertificationWith Professional Certification · Beginner Friendly.Beginner Friendly75 hours75 hours · A double pointer is declared using two asterisks (**) before the pointer variable name: ...
🌐
Scaler
scaler.com › home › topics › c – pointer to pointer (double pointer)
C – Pointer to Pointer (Double Pointer) - Scaler Topics
October 10, 2023 - Imagine it as a chain where the double pointer points to another pointer, which in turn points to the actual variable. To declare a double pointer, you utilize two asterisks before the variable name.
🌐
YouTube
youtube.com › logic lambda
Double Pointers in C - YouTube
0:03 - Review of pointers and definition of double pointers0:47 - Relationship of variables, pointers, double pointers2:00 - Variables, pointers, & double po...
Published   October 26, 2021
Views   4K
🌐
TheJat
thejat.in › home › learn › c++ › compound types: references and pointers in c++ › double pointers
Double Pointers - TheJat.in
Declaring a double pointer involves using two asterisks (**) before the variable name. ... int main() { int x = 42; // Create an integer variable int* p = &x; // Create a pointer and assign the address of x to it int** pp = &p; // Create a double ...
🌐
Code with C
codewithc.com › code with c › c tutorials › cracking double pointers in c: unfurling the mysteries
Cracking Double Pointers In C: Unfurling The Mysteries - Code With C
September 26, 2023 - At this point, your mind must be ... declared as int *p;, a double pointer would be int **p;. Yes, the double asterisks are not a typo; they are the star of the show....
🌐
YouTube
youtube.com › watch
What the * (asterisk, splat, star) Means In C Programming - YouTube
The * character (asterisk, star, or splat) is used in different ways in C. This video walks through 3 of those ways0:13 - What do we call the * and what doe...
Published   September 9, 2022