Нужен указатель на указатель
Что необходимо для хранения адреса указателя?
int a = 2;
int *p = &a;
int **q = &p;
Любое практическое использование? Приложения в реальном времени.
5 ответов
**
это просто указатель на указатель. Так где *p
содержит адрес p
, p**
содержит адрес p*
который содержит адрес p
объект.
**
используется, когда вы хотите сохранить распределение памяти или назначение даже вне вызова функции.
Также проверьте эту статью.
ПРИМЕР:-
void allocate(int** p)
{
*p = (int*)malloc(sizeof(int));
}
int main()
{
int* p = NULL;
allocate(&p);
*p = 1;
free(p);
}
В C вы можете передать "значение" или "адрес" объекта. Если вы передадите значение в вызове функции, то изменения, внесенные в функцию, не будут отражены в месте вызова. И чтобы отразить изменения, вам нужно передать адрес объекта, например:
void insert(node* head){
head->data = 10; // address(or head) is still same
}
Под объектом я подразумеваю любой тип int, char или struct, например, узел
В приведенном выше примере вы меняете значение по адресу head
указатель и изменение в data
будет отражено.
Но если вы хотите изменить head
сам в вашем списке (например, вставить новый узел в качестве первого узла).
void insert(node* head){
head = malloc(sizeof(head)); // head changed
head->data = 10;
}
Тогда значение не отражается в месте вызова, потому что это head
в функции не совпадает с head
в месте вызова.
У вас есть два варианта, либо return head
или использовать pointer to pointer
(но помните, что только одно значение может быть возвращено).
Использовать указатель на указатель:
void insert(node** head){
(*head) = malloc(sizeof **head);
(*head)->data = 10;
}
Теперь изменения отразятся!
Дело в том, что если адрес - это ваше значение (необходимо обновить адрес), то вам нужно использовать указатель адреса или, я бы сказал, указатель на указатель, чтобы отразить изменения в месте вызова.
Поскольку ваш вопрос заключается в том, зачем нужен указатель на указатели, еще одно место, где указатель на указатель используется в массиве строк, и динамические двумерные массивы, и для такого же использования вам может понадобиться указатель на указатель на указатель, например, динамическая матрица строки или / массив трехмерных символов.
Прочтите также это: Указатели на указатели, которые я только что нашел, чтобы привести пример.
Есть ли
int main (int argc, char** argv) { ... }
Выглядит знакомо?
Если вы хотите разместить указатель N-го порядка в другой функции, вы должны использовать (N+1) -й указатель порядка. Например:
void allocate_matrix(int ***ptr, int x, int y);
Позволяет нам выделить матрицу:
int **matrix:
allocate_matrix(&matrix, 5, 5);
Одним из способов использования этого является изменение значения указателя из функции. Например:
#include <stdio.h>
void swapStrings(const char **strA, const char **strB)
{
const char *tmp = *strB;
*strB = *strA;
*strA = tmp;
}
int main()
{
const char *a;
const char *b;
a = "hello";
b = "world";
swapStrings(&a,&b);
// now b points to "hello" and a points to "world"
printf("%s\n", a);
printf("%s\n", b);
}
Выходы:
world
hello