Типы определяют семантику того, как вы взаимодействуете с данными, вам никогда не следует назначать указатель на int напрямую, например, на указатель на указатель на int.Однако вам может быть интересно использовать вариант использования типа **.
Например, посмотрите на этот код, который я написал:
#include <stdio.h>
#include <stdlib.h>
typedef struct fooStruct
{
int a;
int b;
} FOO_STRUCT;
void multiReturns(int *a, FOO_STRUCT **b) {
*a = 42;
//b is a pointer that points to a FOO_STRUCT pointer
if(*b) {
free(*b);
printf("Proof that we deleted memory.\n");
}
//This changes what b points to in main.
*b = (FOO_STRUCT *)malloc(sizeof(FOO_STRUCT));
printf("The new value of *b, this may or maynot be the same as before: %p\n", *b);
//Parens for clarity, We dereferenced the pointer to the
//FOO_STRUCT pointer. Then, we derefrence the FOO_STRUCT
//pointer to access its members.
(*(*b)).a = 59;
(*(*b)).b = 42;
return;
}
int main(int argc, char **argv)
{
int a = 0;
FOO_STRUCT *b = (FOO_STRUCT *)malloc(sizeof(FOO_STRUCT));
(*b).a = 1;
(*b).b = 2;
printf("BEFORE a = %d\n", a);
printf("BEFORE b = %p\n", b);
printf("BEFORE *b.a = %d\n", (*b).a);
printf("BEFORE *b.b = %d\n", (*b).b);
multiReturns(&a, &b);
printf("AFTER a = %d\n", a);
//The value AFTER b might have changed, depends on allocation factors..
printf("AFTER b = %p\n", b);
printf("AFTER *b.a = %d\n", (*b).a);
printf("AFTER *b.b = %d\n", (*b).b);
free(b);
return 0;
}
Вывод на моем компьютере:
[hart@katamari tests]$ gcc pointers.c -o ptr
[hart@katamari tests]$ ./ptr
BEFORE a = 0
BEFORE b = 0x19b41010
BEFORE *b.a = 1
BEFORE *b.b = 2
Proof that we deleted memory.
The new value of *b, this may or maynot be the same as before: 0x19b41010
AFTER a = 42
AFTER b = 0x19b41010
AFTER *b.a = 59
AFTER *b.b = 42
Существуют функции и стандартная библиотека, и в других местах, которые принимают указатель на указатель типа.Пока параметр ** не является константным, он указывает, что значение может быть изменено, и может указывать или не указывать на одну и ту же выделенную память.В моем примере я удалил старый указатель, но это специфическая функция, за которой нужно следить.Кроме того, если вызывающая сторона ответственна за удаление любой новой возвращенной памяти, она также может зависеть от конкретной функции, поэтому прочитайте документацию по любым функциям, которые, как вы видите, их используют, и убедитесь, что вы документируете все, что пишете хорошо.