C / C ++ - Pointers

3

I have a question about the following code:

``````int main()
{
int *x, *y;
int i;
i = 10;
x = &i;
y = x;
*x = *y +1;
cout << i << endl;
*y = *x + 1;
cout << i << endl;
return 0;
}
``````

Whenever I have to represent pointers that point to other pointers and these to a variable, and then modify it, for example, I imagine a diagram as follows:

However, when I saw the other day notes from the faculty, I noticed that the teacher had arranged it differently:

And what I do not understand is how you can point the two at the same variable if * and point to another pointer.

asked by jqc 06.01.2018 в 16:23
source

4

Pointers are variables that store memory positions instead of storing data. So, if you have this:

``````int *x, *y;
int i = 10;
``````

The program will have something like this:

``````x -> (posición aleatoria)
y -> (posición aleatoria)
i -> 10
``````

If the program is now with this:

``````x = &i;
``````

That it is clear that the intention is to store the memory address of `i` in `x` , the variables will remain as follows:

``````x -> dirección de i
y -> (posición aleatoria)
i -> 10
``````

And when finally executing this:

``````y = x;
``````

What it does is copy in `y` the memory location stored in `x` , the variables remain such that:

``````x -> dirección de i
y -> dirección de i
i -> 10
``````

Think that for a pointer to point to another pointer, this first pointer should be double:

``````int **y;
``````

The only thing that indicates the previous pointer is that it internally stores a memory address ... and that if you go to this position you will find another memory address and finally in this second memory position you will find a whole type of data .

source
0

C ++ pointers are used to point objects, and also to manipulate them. Obviously that you already know hehe And two ways are used:  * as your example: int * x. "the asterisk *" tells us: "object pointed to" and allows us to obtain the value referenced by that address.
& i "the ampersand &" it tells us: "address of" and allows us to obtain the memory address of any variable.

Then to find the memory address of any object we will use the address operator (&) and to manipulate the object pointed by a pointer we will use the indirection operator, which is an asterisk (*)

0

You are representing two different situations, in the first graph you represent a pointer `y` that points to another pointer `x` (which in turn points to an int `i` ); in this case you can say briefly that "y is a pointer to pointer" and some call `y` a "double pointer.

While in the second graphic you represent two pointers ( `x` e `y` ) that both point to the same int `i` . And that's the relationship between x - and - i that is shown in the code of your example.

0

The pointers are simply integers of the size of the microprocessor data bus.

For example, in micro architectures x86 `sizeof(int) == sizeof(void*)` , this means that a pointer is simply an integer (without a sign). In micro architectures x86_64 `sizeof(long long) == sizeof(void*)` (For compiler MSVC)

To make you understand better, let's change the program a bit

``````#include<iostream>
using namespace std;

int main(void)
{
unsigned long long x, y; // x e y son enteros sin signo de 64-bit
int i;
i = 10;
x = (unsigned long long) &i; // x es igual a la dirección en memoria de i
y = x;  // y es igual a x (y por ende a la dirección en memoria de i)
*((int*)x) = *((int*)y) + 1; // se reinterpretan las dirección contenidas por x e y
// como direcciones a enteros, y se desreferencian
cout << i << endl;

*((int*)y) = *((int*)x) + 1; // lo mismo que el comentario de arriba
cout << i << endl;
return 0;
}
``````

In C ++ the type checking is not very flexible compared to the type checking of C, so unfortunately you have to do explicit casting of a type `void*` to `unsigned long long`

The previous program is totally equivalent to the following:

``````#include<iostream>
using namespace std;

int main(void)
{
void *x, *y; // x e y son punteros
int i;
i = 10;
x = &i; // x es igual a la dirección en memoria de i
y = x;  // y es igual a x (y por ende a la dirección en memoria de i)
*((int*)x) = *((int*)y) + 1; // se reinterpretan las dirección contenidas por x e y
// como direcciones a enteros, y se desreferencian
cout << i << endl;

*((int*)y) = *((int*)x) + 1; // lo mismo que el comentario de arriba
cout << i << endl;
return 0;
}
``````

Now the million question is: If x and y are pointers why do I need to cast them to `int*` . Actually the casting is due to the fact that the compiler must go to the memory to which the variable points and extract a certain number of bytes from it.

At the time of wanting to access the memory pointed by a pointer of type `void*` , the size of the area to be extracted must be specified. The compiler is quite intelligent, if you declare a pointer as `int*` it knows that it should go and extract `sizeof(int)` bytes to the address contained in `i` and treat the extracted memory as objects of type `int` . However this has nothing to do with pointers, the pointers are simply integers. Having different types of pointers is simply to help the compiler in his arduous task of transforming source code into machine code.

0

What happens is that you think that when you have for example:

```int *x, *y, i = 45; x = &i; y = x;```
and points to x but it's not like that.

Explanation: A pointer is a variable. As a variable it has its own memory address. That variable pointer is special because it does not receive values in itself, but the physical address of the memory that is using a variable that is not a pointer. Now with the * we get the value of the memory address that has a pointer variable. but what happens if `y = x;` and does not have the address of x , but rather has the address to the pointing x , so both x and and point to the same memory address, now to say that and point to x , and has to be another type of pointer in this case `int**` to point to x , but the assignment should be asi: `y = &x;` where and is `int **y;`

In Summary:
int * points to normal variables,
int ** points to int *,
int *** points to int **,
int **** points to int ** *
and so on until you get bored of putting *, and remember every pointer has its own memory address that can be pointed by another top-level pointer and this can point to lower-level memory.