This is basically just to help me understand pointers better, so if you guys can confirm/deny/explain anything it looks like I don't understand properly I would be most appreciative. The examples of using mailboxes, and aunts, and streets, and all that crap is just confusing.
int a = 5;
int b = &a; // b will be the memory address of 'a'
int *c = a; // c will be the value of 'a' which is 5
int *d = &a; // d will be a pointer to the memory address of 'a'
int &e = a; // what would this be?
void FunctionA()
{
int a = 20;
FunctionB(&a);
// a is now 15?
}
void FunctionB(int *a)
{
a = 15;
}
Thank you guys for any help, I am just trying to improve my understanding beyond all of the crappy metaphor explanations im reading.
I'll take things one by one:
int b = &a; // b will be the memory address of 'a'
No. The compiler (probably) won't allow this. You've defined b to be an int, but &a is the address of an int, so the initialization won't work.
int *c = a;
No -- same problem, but in reverse. You've defined c to be a pointer to an int, but you're trying to initialize it with the value of an int.
int *d = &a;
Yes -- you've defined d to be a pointer to an int, and you're assigning the address of an int to it -- that's fine. The address of an int (or an array of ints) is what a pointer to int holds.
int &e = a;
This defines e to be a reference to an int and initializes it as a reference to a. It's perfectly legitimate, but probably not very useful. Just for Reference, the most common use of a reference is as a function parameter (though there are other purposes, of course).
void FunctionA() { int a = 20; FunctionB(&a); }
void FunctionB(int *a) { a = 15; }
To make this work, you need to change the assignment in FunctionB:
void FunctionB(int *a) { *a = 15; }
As it was, you were trying to assign an int to a pointer, which won't work. You need to assign the int to the int that the pointer points at to change the value in the calling function.
int &e = a; // what would this be?
e is a reference to a. In this case the ampersand is not the 'address of' operator. You treat e as you would a normal (not a pointer) variable, but the value of e and of a will be the same no matter what you do to either (as long as both remain in scope) as essentially e is just an alias.
int a = 5;
So far so good.
int b = &a; // b will be the memory address of 'a'
That's actually a compilation error. You probably mean int *b=&a;. b is a POINTER to an integer.
edit: If you mean to get the address in numerical form, you need to force the cast to an integer: int b=(int)&a;
int *c = a; // c will be the value of 'a' which is 5
This one is more confusing. At its core, a pointer is just a number, sure, but this kind of assignement is inherently not safe (as you can see, you're assigning 5 to a pointer, and trying to dereference that will most likely crash your program). If you really do want c to point at the memory location 5, you have to explicitly tell the compiler you know what you're doing: int *c=(int *)a.
int *d = &a; // d will be a pointer to the memory address of 'a'
This one is right, same as what you probably mean by the second one.
int &e = a; // what would this be?
e is a "reference" to a. Basically internally it's just a pointer to a, but you don't have to manually dereference it, the compiler handles it for you.
void FunctionA() { int a = 20; FunctionB(&a); // a is now 15? }
Yes.
void FunctionB(int *a) { a = 15; }
...assuming you write this as *a=15;. You're overwriting the VALUE pointed to by a, not the pointer itself.
You seem pretty confused by this overall, I recommend reading the book "Thinking in C++", it's really well written!
You've got plenty of good answers here for your specific example, so I'd like to share a general technique that I used to learn how pointers work when I was starting out.
Get a big sheet of graph paper and lay it lengthwise on the table in front of you. This is your computer's memory. Each box represents one byte. Pick a row, and place the number '100' below the box at far left. This is "the lowest address" of memory. (I chose 100 as an arbitrary number that isn't 0, you can choose another.) Number the boxes in ascending order from left to right.
+---+---+---+---+---+--
| | | | | | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
Now, just for the moment, pretend an int is one byte in size. You are an eight-bit computer. Write your int a into one of the boxes. The number below the box is its address. Now choose another box to contain int *b = &a. int *b is also a variable stored somewhere in memory, and it is a pointer that contains &a, which is pronounced "a's address".
int a = 5;
int *b = &a;
a b
+---+---+---+---+---+--
| 5 | |100| | | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
Now you can use this model to visually work through any other combinations of values and pointers that you see. It is a simplification (because as language pedants will say, a pointer isn't necessarily an address, and memory isn't necessarily sequential, and there's stack and heap and registers and so on), but it's a pretty good analogy for 99% of computers and microcontrollers.
You can extend the model for real four-byte ints too...
int a = 5;
char b = 2;
a a a a b
+---+---+---+---+---+--
| 0 | 0 | 0 | 5 | 2 | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
int &e=a; is a reference to "a".
and these are bugs:
int b = &a;
int *c = a;
I think you mean:
int *b = &a;, which makes a pointer called b that points to the value of a (b is a pointer which is the address of a)
int c = *b;, (or just int c = a if you only want c to have a's value) In this case, * dereferences the pointer b
FunctionA() See below, then a will be 15 (you're passing the address of a to FunctionB)
void FunctionB(int *a) {*a = 15;} sets the value to 15 (* dereferences)
Related
What is the difference between int* i and int** i?
Pointer to an integer value
int* i
Pointer to a pointer to an integer value
int** i
(Ie, in the second case you will require two dereferrences to access the integer's value)
int* i : i is a pointer to a object of type int
int** i : i is a pointer to a pointer to a object of type int
int*** i : i is a pointer to a pointer to a pointer to object of type int
int**** i : i is a pointer to a pointer to a pointer to a pointer to object of type int
...
int* pi
pi is a pointer to an integer
int **ppi
ppi is a pointer to a pointer to an integer.
EDIT :
You need to read a good book on pointers. I recommend Pointers on C by Kenneth Reek.
Let's say you're a teacher and have to give notes to one of your students.
int note;
Well ... I meant the whole class
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
Well ... don't forget you have several classes
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
And, you also teach at several institutions
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
etc, etc ...
I don't think this is specific to opencv.
int *i is declaring a pointer to an int. So i stores a memory address, and C is expecting the contents of that memory address to contain an int.
int **i is declaring a pointer to... a pointer. To an int. So i contains an address, and at that memory address, C is expecting to see another pointer. That second memory address, then, is expected to hold an int.
Do note that, while you are declaring a pointer to an int, the actual int is not allocated. So it is valid to say int *i = 23, which is saying "I have a variable and I want it to point to memory address 23 which will contain an int." But if you tried to actually read or write to memory address 23, you would probably segfault, since your program doesn't "own" that chunk of RAM. *i = 100 would segfault. (The solution is to use malloc(). Or you can make it point to an existing variable, as in int j = 5; int *i = &j)
Imagine you have a few friends, one of them has to give you something (a treasure... :-)
Say john has the treasure
int treasure = 10000; // in USD, EUR or even better, in SO rep points
If you ask directly john
int john = treasure;
int you = john;
If you cannot join john, but gill knows how to contact him,
int john = treasure;
int *gill = &john;
int you = *gill;
If you cannot even join gill, but have to contact first jake who can contact gill
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
Etc... Pointers are only indirections.
That was my last story for today before going to bed :-)
I deeply believe that a picture is worth a thousand words. Take the following example
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
So in the above, A points to the first integer in the sequence of N integers. And P points to a pointer that the caller will have the pointer to the found integer stored in.
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P is used to pass the address of P to the function. This address has type int **, because it's the address of a pointer to int.
int* i is the address of a memory location of an integer
int** is the address of a memory location of an address of a memory location of an integer
int* i; // i is a pointer to integer. It can hold the address of a integer variable.
int** i; // i is a pointer to pointer to integer. It can hold address of a integer pointer variable.
Neither is a declaration. Declaration syntax does not allow () around the entire declaration. What are these () doing there? If this is supposed to be a part of function declaration, include the whole function declaration thing in your question, since in general case the actual meaning of a declaration might depend on that. (Not in this one though.)
As for the difference... There is one * in the first and there are two *s in the second. Does it help? Probably not. The first one declares ias a pointer to int. The second one declares i as a pointer to int *. Does this help? Probably not much either. Without a more specific question, it is hard to provide a more meaningful answer.
Provide more context, please. Or, if this is actually as specific as it can get, read your favorite C or C++ book about pointers. Such broad generic questions is not something you ask on the net.
Note that
int *i
is not fully interchangeable with
int i[]
This can be seen in that the following will compile:
int *i = new int[5];
while this will not:
int i[] = new int[5];
For the second, you have to give it a constructor list:
int i[] = {5,2,1,6,3};
You also get some checking with the [] form:
int *i = new int[5];
int *j = &(i[1]);
delete j;
compiles warning free, while:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
will give the warnings:
warning C4156: deletion of an array expression without using the array form of 'delete'; array form substituted
warning C4154: deletion of an array expression; conversion to pointer supplied
Both of these last two examples will crash the application, but the second version (using the [] declaration type) will give a warning that you're shooting yourself in the foot.
(Win32 console C++ project, Visual studio 2010)
Textual substitution is useful here, but beware of using it blindly as it can mislead you (as in the advanced example below).
T var; // var has type T
T* var; // var has type "pointer to T"
This works no matter what T is:
int* var; // pointer to int
char* var; // pointer to char
double* var; // pointer to double
// advanced (and not pure textual substitution):
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints"
// also known as "int[3]"
int3* var; // pointer to "array (of size 3) of ints"
// aka "pointer to int[3]"
int (*var)[3]; // same as above, note how the array type from the typedef
// gets "unwrapped" around the declaration, using parens
// because [] has higher precedence than *
// ("int* var[3];" is an array (size 3) of pointers to int)
This works when T is itself a pointer type:
typedef int* T; // T is a synonym for "pointer to int"
T* var; // pointer to T
// which means pointer to pointer to int
// same as:
int** var;
Can anyone help me with this.
I thought pointer is a object that hold address of a variable. So when i minus a pointer to a pointer. it get this result.
int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = c - d; // = 3
int array[] = { 1, 2, 6, 4, 7, 8, 5, 3 };
int* f = &array[0];
int* g = &array[8];
int h = g - f; // = 8
In your first example, subtracting independent pointers makes no sense. Considering your example :
int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = c - d; // Nonsense
If what you're trying to do is the operation "2 - 7" using pointers, then you first have to dereference your pointers (evaluate the value held by the variable pointed by your pointer) :
int e = (*c) - (*d);
You are right, a pointer holds address of an object in the memory. In C and C++ we can do pointer arithmetic which lets us subtract pointers from each other and more. Substracting pointers gives us the distance between the two addresses in the memory. The unit of the distance is determined by the pointer type. Meaning that subtracting two int*s will give you how many ints are your addresses apart. In your case variable e will be the distance between where a is stored in memory and where b is stored in the memory. Running your code I got e=1. Which I expect because a and b are defined right after each other so its expected that they will occupy two adjacent spaces on the stack but I guess its something that the compiler decides.
for arrays On the other hand, by definition all the elements are stored one after the other therefore the distance between the first and eighth element of any array is always 8. Also take a look at the code below:
int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = d - c; // e=1
//the unit of measurement for pointer subtraction is the type of the pointer
//therefore although first byte of b is stored 4 bytes (sizeof(int)) after the
//first byte of a, we get '1' as the distance. but we cast the pointer to another type
//say char, we get distance based on that type
int f= (char*)d-(char*)c;//f=4 or e*4 since sizeof(int)=4*sizeof(char) (on this particular environment)
I thought a[] and *a are the same thing because they work like pointers. Yet I encountered something unexpected in the following code:
#include <iostream>
using namespace std;
class F {
public:
bool a[];
F();
};
F::F() {
*a = new bool[5];
a[2] = true;
}
int main() {
F obj;
if(obj.a[2])
cout << '?';
return 0;
}
This code prints ?, but I don't understand how it works. When:
*a = new bool[5];
is changed into:
a = new bool[5];
compiler reports:
F:\main.cpp|11|error: incompatible types in assignment of 'bool*' to 'bool [0]'|
I found this behaviour weird, so I was playing around with this code. When I changed the type of a from bool to int compiler always reports an error
F:\main.cpp|11|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
Why does this work the way it does?
I thought a[] and *a are the same thing because they work like pointers.
Let's talk about this piece of declaration:
int a[4] = { 1, 2, 3, 5 };
int *b = NULL;
This is how they land in memory in the executable:
+----+----+----+----+
a: | 1 | 2 | 3 | 5 | <-- 4 integers
+----+----+----+----+
+----------+
b: | NULL | <-- 1 pointer that points to nowhere
+----------+
As you can see, they are not the same thing.
What happens after b = new int[4];?
The new memory layout of b is something like this:
+----------+
b: | 0xacf3de | <-- 1 pointer that points to a block of 4 integers
+----------+
Somewhere else in memory (at address 0xacf3de)...
+----+----+----+----+
0xacf3de: | ? | ? | ? | ? | <-- 4 integers
+----+----+----+----+
But wait, somebody told me that arrays work like pointers...
No, that's not true. The arrays do not work like pointers.
An array name (a, f.e.) can be used as a shortcut for its address in memory (which is, in fact, the address of its first element). The following notations are equivalent:
a
&a
&a[0]
The value of all of them is the address in memory where the first element of a (the 1 in the example above) is stored.
a[0] is an int, &a[0] is an int *. This is the complete form. The other two are shortcuts that the language provides in order to make the code easier to read and understand.
The things are different for pointers.
b is the value stored in the b variable (NULL or 0xacf3de in the example above. It is a value of type int * -- the address in memory where an int is stored. &b is the address in memory where (the value of) b is stored. Its type is int ** -- a pointer to a pointer to an int; or "the address in memory where is stored the address of an int".
But wait, they can be replaced one for another in some contexts
Up to some point, yes, a pointer and an array are interchangeable. As you can see above, there is a common data type involved: int *. It is the type of b (which stores the address of an int) and also the type of &a[0] (which is also the address of an int).
This means that where b can be used, a (a short of &a[0]) can be used instead, and vice-versa.
Also, where *b can be used, *a can be used instead. It is the short for *&a[0] and it means "the value (*) stored at the address (&) of a[0]" and it is, in fact, the same as a[0].
But, where &b can be used, &a cannot be used instead; remember that &a is the same as &a[0] and its type is int * (but the type of &b is int **).
The line:
*a = new bool[5];
is equivalent to:
a[0] = new bool[5];
You are not initialiazing your array, but allocating an array of bool which is then implicitly converted into bool to be assigned to a[0]: the value should be true since the pointer returned by new should be different from 0. This implicit conversion does not apply with ints: that is why you are getting an error when changing the type of a.
Now, considering this line:
a = new bool[5];
Here you are trying to assign your dynamically allocated array to a, in other words assigning a pointer to an array bool* to a static array bool[0]: as the compiler says, the types are incompatible. A static array a[] can be used as a pointer, e.g. in the following code:
int foo(bool* a) { /* ... */ }
bool my_array[5];
foo(my_array);
But pointers can not be converted into static arrays as you are trying to do.
Type of value returned from new Type[x] is Type * i.e pointer of that type
examle:
So Right syntax is
bool a;
*a = new bool[x];
so it is wrong to do like is
a=new bool[x] wrong syntax as it is invalid to assign pointer to a normal varibale
see for more details
I want to do something like this below:
int main() {
int a[10];
int *d = generateArrayOfSize(10) // This generates an array of size 10 on the heap
a = d;
print(a); // Prints the first 10 elements of array.
}
However above code gives compilation error (incompatible types in assignment of ‘int*’ to ‘int [10]’).
What can I do to make the above code to work?
Arrays are non-assignable and non-copyable, so you'd have to copy each element by hand (in a loop), or using std::copy.
If you're using C++, then use C++ arrays rather than C style arrays and pointers. Here's an example
#include <array>
#include <iostream>
template<size_t N>
std::array<int, N> generateArrayOfSize(void)
{
std::array<int, N> a;
for (int n=0; n<N; ++n)
a[n] = n;
return a;
}
template<size_t N>
void print(std::array<int, N> const &a)
{
for (auto num : a)
std::cout << num << " ";
}
int main() {
std::array<int, 10> a;
std::array<int, 10> d = generateArrayOfSize<10>();
a = d;
print(a); // Prints the first 10 elements of array.
}
which outputs 0 1 2 3 4 5 6 7 8 9
Arrays are not pointers.
You can't do :
int a[10];
int *d;
a = d;
Change it to :
int *a;
int *d;
a = d;
Main differences between arrays and pointers in C programming :
Pointer | Array
-------------------------------------------|-------------------------------------------
A pointer is a place in memory that keeps | An array is a single, pre allocated chunk
address of another place inside | of contiguous elements (all of the same
| type), fixed in size and location.
-------------------------------------------|-------------------------------------------
A pointer can point to a dynamically | They are static in nature. Once memory is
allocated memory. In this case, the memory | allocated , it cannot be resized or freed
allocation can be resized or freed later. | dynamically.
-------------------------------------------|-------------------------------------------
You have a quite good explanation here : https://stackoverflow.com/a/7725410/1394283
An array is not a pointer (although a name of an array often decays to a pointer to its first element).
To make the above code to work, you can declare a as a pointer: int *a;. The print function takes an int* (or a decayed array) anyway.
If you really want to have two arrays and copy contents from one array to another, you should copy the data in a loop.
This will print in this way when you assign a string reference to a pointer you have to use *ptr to print the value of a pointer otherwise in your case print(d) that is like cout< in c++ it will only print the location of the d[0].
int ary[5]={1,2,3,4,5};
int *d;
d=ary;
for(int i=0;i<5;i++)
cout<<*(d+i);
Because array names are non-modifiable. So you can't do
a = d;
Declare it as a pointer like this:
int *a;
Little rusty with my C++ but try something like this.
int main() {
int *a;
int *d = generateArrayOfSize(10) // This generates an array of size 10 on the heap
a = d;
print(a); // Prints the first 10 elements of array.
}
In C, it was always true when Thing X[10]; was declared, X was the constant address of the first element(i.e. &X[0]). So you could then say:
Thing *Y = X; // Equivalent to (Thing *Y = &X[0];)
But in C++, the compiler "remembers" that the Thing array X has 10 elements, and some C++ imposed type checking rules break. Imagine we add Thing Z[20]; to the discussion.
Thing *Y = X; and Thing *Y = Z; if both allowed, would imply that a single variable could be set to Thing Arrays of length 10 and 20, which are very different (ahem) "things", as a quick look at a 2D array will reveal. This sort of justifies why the C language assumed equivalent of X and &X[0] is broken in C++.
Well, at least for some versions of C++. So best not to assume it, and use
Thing *Y = &x[0]; and Thing *Y = &Z[0] instead;
This approach has two advantages. It does what is wanted, and it actually compiles. :-)
What is the difference between int* i and int** i?
Pointer to an integer value
int* i
Pointer to a pointer to an integer value
int** i
(Ie, in the second case you will require two dereferrences to access the integer's value)
int* i : i is a pointer to a object of type int
int** i : i is a pointer to a pointer to a object of type int
int*** i : i is a pointer to a pointer to a pointer to object of type int
int**** i : i is a pointer to a pointer to a pointer to a pointer to object of type int
...
int* pi
pi is a pointer to an integer
int **ppi
ppi is a pointer to a pointer to an integer.
EDIT :
You need to read a good book on pointers. I recommend Pointers on C by Kenneth Reek.
Let's say you're a teacher and have to give notes to one of your students.
int note;
Well ... I meant the whole class
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
Well ... don't forget you have several classes
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
And, you also teach at several institutions
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
etc, etc ...
I don't think this is specific to opencv.
int *i is declaring a pointer to an int. So i stores a memory address, and C is expecting the contents of that memory address to contain an int.
int **i is declaring a pointer to... a pointer. To an int. So i contains an address, and at that memory address, C is expecting to see another pointer. That second memory address, then, is expected to hold an int.
Do note that, while you are declaring a pointer to an int, the actual int is not allocated. So it is valid to say int *i = 23, which is saying "I have a variable and I want it to point to memory address 23 which will contain an int." But if you tried to actually read or write to memory address 23, you would probably segfault, since your program doesn't "own" that chunk of RAM. *i = 100 would segfault. (The solution is to use malloc(). Or you can make it point to an existing variable, as in int j = 5; int *i = &j)
Imagine you have a few friends, one of them has to give you something (a treasure... :-)
Say john has the treasure
int treasure = 10000; // in USD, EUR or even better, in SO rep points
If you ask directly john
int john = treasure;
int you = john;
If you cannot join john, but gill knows how to contact him,
int john = treasure;
int *gill = &john;
int you = *gill;
If you cannot even join gill, but have to contact first jake who can contact gill
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
Etc... Pointers are only indirections.
That was my last story for today before going to bed :-)
I deeply believe that a picture is worth a thousand words. Take the following example
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
So in the above, A points to the first integer in the sequence of N integers. And P points to a pointer that the caller will have the pointer to the found integer stored in.
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P is used to pass the address of P to the function. This address has type int **, because it's the address of a pointer to int.
int* i is the address of a memory location of an integer
int** is the address of a memory location of an address of a memory location of an integer
int* i; // i is a pointer to integer. It can hold the address of a integer variable.
int** i; // i is a pointer to pointer to integer. It can hold address of a integer pointer variable.
Neither is a declaration. Declaration syntax does not allow () around the entire declaration. What are these () doing there? If this is supposed to be a part of function declaration, include the whole function declaration thing in your question, since in general case the actual meaning of a declaration might depend on that. (Not in this one though.)
As for the difference... There is one * in the first and there are two *s in the second. Does it help? Probably not. The first one declares ias a pointer to int. The second one declares i as a pointer to int *. Does this help? Probably not much either. Without a more specific question, it is hard to provide a more meaningful answer.
Provide more context, please. Or, if this is actually as specific as it can get, read your favorite C or C++ book about pointers. Such broad generic questions is not something you ask on the net.
Note that
int *i
is not fully interchangeable with
int i[]
This can be seen in that the following will compile:
int *i = new int[5];
while this will not:
int i[] = new int[5];
For the second, you have to give it a constructor list:
int i[] = {5,2,1,6,3};
You also get some checking with the [] form:
int *i = new int[5];
int *j = &(i[1]);
delete j;
compiles warning free, while:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
will give the warnings:
warning C4156: deletion of an array expression without using the array form of 'delete'; array form substituted
warning C4154: deletion of an array expression; conversion to pointer supplied
Both of these last two examples will crash the application, but the second version (using the [] declaration type) will give a warning that you're shooting yourself in the foot.
(Win32 console C++ project, Visual studio 2010)
Textual substitution is useful here, but beware of using it blindly as it can mislead you (as in the advanced example below).
T var; // var has type T
T* var; // var has type "pointer to T"
This works no matter what T is:
int* var; // pointer to int
char* var; // pointer to char
double* var; // pointer to double
// advanced (and not pure textual substitution):
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints"
// also known as "int[3]"
int3* var; // pointer to "array (of size 3) of ints"
// aka "pointer to int[3]"
int (*var)[3]; // same as above, note how the array type from the typedef
// gets "unwrapped" around the declaration, using parens
// because [] has higher precedence than *
// ("int* var[3];" is an array (size 3) of pointers to int)
This works when T is itself a pointer type:
typedef int* T; // T is a synonym for "pointer to int"
T* var; // pointer to T
// which means pointer to pointer to int
// same as:
int** var;