Двойные указатели также иногда используются для передачи указателей на функции по ссылке - PullRequest
1 голос
/ 08 октября 2010

"Двойные указатели также иногда используются для передачи указателей на функции по ссылке" Может кто-нибудь объяснить мне приведенное выше утверждение, что именно указывает на функцию с помощью ссылки?

Ответы [ 3 ]

5 голосов
/ 08 октября 2010

Полагаю, этот пример проясняет ситуацию:

//Double pointer is taken as argument
void allocate(int** p,  int n)
{
    //Change the value of *p, this modification is available outside the function
    *p = (int*)malloc(sizeof(int) * n);
}

int main()
{

    int* p = NULL;

    //Pass the address of the pointer
    allocate(&p,1);

    //The pointer has been modified to point to proper memory location
    //Hence this statement will work
    *p=10;

    //Free the memory allocated
    free(p);

    return 0;
}
2 голосов
/ 08 октября 2010

Это означает, что у вас есть функция, которая принимает указатель указателя (например, введите int **).Это позволяет вам модифицировать указатель (на какие данные он указывает) во многом путем передачи указателя по ссылке.

void change (int *p) {*p = 7;}
void Really_Change (int **pp) {*pp = null;}

int p = 1;
int *pp = &p;
// now, pp is pointing to p. Let's say it has address 0x10;

 // this makes a copy of the address of p. The value of &p is still 0x10 (points to p).
 // but, it uses that address to change p to 7.
change(&p);
printf("%d\n", p); // prints 7;


// this call gets the address of pp. It can change pp's value
// much like p was changed above.
Really_Change(&pp);

// pp has been set to null, much like p was set to 7.

printf("%d\n", *pp); // error dereference null. Ka-BOOM!!!

Таким же образом, вы можете передать указатель наint и изменив значение, вы можете передать указатель на указатель и изменить его значение (которое меняет то, на что он указывает.)

1 голос
/ 08 октября 2010

Я постараюсь объяснить как с кодом, так и с простым английским :).Объяснение может быть длинным, но оно того стоит.

Предположим, у нас есть программа, выполняющая ее функцию main (), и мы вызываем другую функцию, которая принимает параметр int.

Концептуально, когда вы передаете переменную в качестве параметра функции, вы можете сделать это (грубо говоря) двумя способами: по значению или по ссылке.

«По значению» означает предоставлениефункция копия вашей переменной.Функция получит свое «содержимое» (значение), но не сможет изменить фактическую переменную вне собственного тела кода, потому что ей была дана только копия.

«По ссылке»,с другой стороны, означает предоставление функции фактического адреса памяти нашей переменной.Используя это, функция может узнать значение переменной, но она также может перейти по указанному адресу и изменить содержимое переменной.

В нашей программе на C «по значению» означает передачу копии int (просто принимая int в качестве аргумента), а «по ссылке» означает передачу на него указателя.

Давайте рассмотрим небольшой пример кода:

void foo(int n) {
    n = 10;
    printf("%d\n", n);
}

int main() {
    int n = 5;

    foo(n);
    printf("%d\n", n);

    return 0;
}

Что будет выводомэта программа будет?10 10?Нету.10 5!Поскольку мы передали копию int по значению, а не по ссылке, foo() изменил только номер, сохраненный в ее копии, и не смог получить копию main().

Теперь, если мысделайте это следующим образом:

void foo(int* n) {
    *n = 10;
    printf("%d\n", *n);
}

int main() {
    int n = 5;
    foo(&n);
    printf("%d\n", n);

    return 0;
}

На этот раз мы дали foo() наше целое число по ссылке: это фактический адрес памяти.foo() обладает всеми возможностями для его изменения путем доступа к его положению в памяти, foo() и main() работают с одной и той же копией, и поэтому на выходе будет 10 10.

Как видите,указатель - это ссылка, ... , но также числовая позиция в памяти .Это похоже на int, только число, содержащееся внутри, интерпретируется по-разному.Подумайте об этом так: когда мы передаем наш int по ссылке, мы передаем указатель int по значению! .Таким образом, та же логика по значению / по ссылке может применяться к указателям, даже если они уже являются ссылками.

Если наша действительная переменная была не int, а ссылкой int (указатель), и мы хотели main() и foo(), чтобы поделиться той же копией этой ссылки, чтобы foo() мог ее изменить, что бы мы делали?Почему, конечно, нам нужна ссылка на нашу ссылку!Указатель на указатель.То есть:

int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
            Stores int*'s memory address so we can pass int*s by reference. */

Надеюсь, это было полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...