Указатель на указатель в качестве аргумента в функции - PullRequest
0 голосов
/ 12 мая 2019

У меня есть следующий код:

void change_adrs(int **q)
{
    int * otheraddess;
    *q = otheraddress; 
}

Я не могу понять это назначение: *q = otheraddress;

Может ли кто-нибудь помочь мне объяснить это. Почему мы не можем использовать другое задание, например:

**q = otheraddress; 
*q = *otheraddress;
q = &otheraddress; 

Ответы [ 3 ]

1 голос
/ 12 мая 2019
void change_ptr(int **q)
{
    *q = malloc(somemem); 
}

void foo()
{
     int *ptr;

     change_ptr(&ptr);
}

в этом примере это изменит значение самого ptr.Когда вы передаете одиночный указатель звезды, вы можете изменить только объект, на который есть ссылка.

1 голос
/ 12 мая 2019

Смотрите на присвоение *q = otheraddress; так же, как вы смотрите на следующее:

int x = 4;
int y = x;

вы берете 2 одинаковых типа и делаете назначение между ними.

В вашем случае вы используете адрес int vairables.int *otheraddress; - это переменная, которая может получить адрес (& оператор) для int vairable, например:

int x = 4;
int *p = &x; //p<=the address of x

и int **q; могут получить адрес, который может получить int-адрес.например, ваше третье назначение (которое должно работать нормально) :

int x = 4;
int *p = &x;//p<=the address of x
int **q = &p;//q<=the address of p

для других присвоений:

**q = otheraddress; вы пытаетесь присвоить int * в int **

*q = *otheraddress; вы пытаетесь присвоить int в int *

1 голос
/ 12 мая 2019

После объявления переменных * разыменовывает их.

Например, после объявления чего-то вроде int **a;, при его использовании мы имеем:

**a значение в значении в местоположениихранится в a (что в конечном итоге является целым)

*a значение в местоположении хранится в a (это другое местоположение)

a местоположение хранится в a

&a местоположение самой a

Давайте посмотрим, почему не работает каждый из ваших примеров:

**q = otheraddress; назначение местоположенияint ×

*q = *otheraddress; назначение int для местоположения ×

Редактировать: Давайте рассмотрим эти два примера:

q = &otheraddress; назначение местоположения дляместоположение ✓

*q = otheraddress; присвоение местоположения местоположению ✓


Давайте посмотрим на это так:

Предположим, у нас есть:

int *a;
int **q;

для предотвращения ошибок сегментации в будущем, давайте сначала назначим некоторый адрес:

int t = 5
a = &t;

Давайте посмотрим на адресапосле q = &a:

//first snippet
0x7fffc3a2b338   // &a
0x5596853c98c0   // a
5                // *a

0x7fffc3a2b340   // &q
0x7fffc3a2b338   // q
0x5596853c98c0   // *q
5                // **q

Как и ожидалось, &a помещается в q, а a содержит &t, поэтому **(&a) и **(q) будут содержать значение5.

Теперь давайте посмотрим на адреса после *q = a:

//second snippet
0x7fffc3a2b338   // &a
0x5596853c98c0   // a
5                // *a

0x7fffc3a2b340   // &q
0x7fffc3a2b345   // q
0x5596853c98c0   // *q
5                // **q

Здесь a помещается в *q, а сам a равен &t,поэтому *(a) и *(*q) с обоими содержат значение 5.

Чтобы понять разницу, мы рассмотрим пример:

int b = 3;
a = &b;

Используя это после первого фрагмента, a присвоен другой адрес, а q был объявлен &a (который не изменился), поэтому **(q) имеет то же значение, что и **(&a), который теперь равен 3.
Это все равно, что сказать:

int a = 3;
int *b = &a;
a = 5; //even though a has changed, b retains its old value of &a, thus *(b) == *(&a) == 5

Однако во втором фрагменте *q уже был объявлен как a до того, как он изменился, поэтому, хотя a теперь имеет новый адрес, адрес внутри *q по-прежнемуне изменилсяТаким образом, попытка доступа к *(*q) будет использовать старый адрес и снова даст нам 5.
Это все равно, что сказать:

int a = 3; 
int b = a; 
a = 5; //even though a has changed, b still retains it's old value of 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...