Аргументы функции по ссылке


Предположим, вы уже знаете указатели и функции, поэтому вы знаете, что аргументы функции передаются по значению, что означает, что они копируются в функции и из них. Но что, если мы передадим указатели на значения вместо самих значений? Это позволит нам предоставить функциям контроль над переменными и структурами родительских функций, а не только их копией, таким образом, непосредственно читая и записывая исходный объект.

Допустим, мы хотим написать функцию, которая увеличивает число на единицу, с именем addone. Так не пойдет:

void addone(int n) {
    // n is local variable which only exists within the function scope
    n++; // therefore incrementing it has no effect
}

int n;
printf("Before: %d\n", n);
addone(n);
printf("After: %d\n", n);

Однако это будет работать:

void addone(int *n) {
    // n is a pointer here which point to a memory-adress outside the function scope
    (*n)++; // this will effectively increment the value of n
}

int n;
printf("Before: %d\n", n);
addone(&n);
printf("After: %d\n", n);

Разница в том, что вторая версия addoneполучает указатель на переменную nв качестве аргумента, а затем может манипулировать им, поскольку знает, где она находится в памяти.

Обратите внимание, что при вызове addoneфункции мы должны передавать ссылку на переменную n, а не на саму переменную - это делается для того, чтобы функция знала адрес переменной и не просто получала копию самой переменной.

Указатели на структуры

Допустим, мы хотим создать функцию , которая перемещает точку вперед в обоих xи yнаправлениях, называется move. Вместо отправки двух указателей теперь мы можем отправить только один указатель на функцию структуры точки:

void move(point * p) {
    (*p).x++;
    (*p).y++;
}

Однако, если мы хотим разыменовать структуру и получить доступ к одному из ее внутренних членов, у нас есть сокращенный синтаксис для этого, потому что эта операция широко используется в структурах данных. Мы можем переписать эту функцию, используя следующий синтаксис:

void move(point * p) {
    p->x++;
    p->y++;
}

Упражнение

Напишите функцию с именем birthday, который добавляет один к ageиз person.