Основы программирования на С++ для начинающих

Ссылки в C++

В наших предыдущих статьях, мы уже упоминали о том, что параметры можно передавать в функцию по значению или по указателю. Так работали при написании программ на языке C. В C++ появляется возможность передавать параметры в функции по ссылке. Рассмотрев пример из этого урока, вы заметите, что применять ссылки удобнее чем указатели.

Ссылка – это альтернативное имя переменной (её псевдоним, иными словами). Когда функция принимает параметр по ссылке, имя параметра становится псевдонимом переменной, которую мы передаём в функцию. Такой метод передачи данных позволяет функции работать со значениями переменных, которые передаются в неё, а не с копиями этих переменных.

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

Набирайте следующий пример и всё должно стать понятным:

Начнем с функции change(). Вызвав ее в строке 17 исходного кода, передаем в неё переменные по значению. Функция благополучно создаст копии этих переменных, запишет в них данные и, завершая свою “нелегкую” работу, уничтожит эти копии. В итоге никаких изменений с передаваемыми переменными не произойдёт.

Теперь посмотрите на определение функции changeRef(), в которую параметры передаются по ссылке – строки 45 – 49. Как говорилось выше, мы использовали & , чтобы сообщить компилятору о том, что принимаемые параметры – это ссылки. Внутри самой функции мы обращаемся к ссылкам, как к обычным переменным. То есть нам не надо применять операцию разыменования, если надо изменить значение переменной:

ссылки в C++, ссылочные переменные с++

А вызывая эту функцию из главной (строка 21), нам не надо, при передаче переменных, применять операцию взятия адреса (тот же & , но с другим подтекстом), как это необходимо делать при передаче по указателю. Результат работы функции увидим, отобразив значение переменных на экран. Значения переменных успешно изменены.

Напоследок – передача по указателю. Сразу к определению changePtr() – строки 51 – 55. Тут есть то, чего мы не использовали при передаче по ссылке – разыменование указателей для изменения значений переменных:

ссылки в C++, ссылочные переменные с++

Так как функция должна принять переменные по указателю, а указатель хранит адрес, то при вызове (строка 25) передаём в неё адреса переменных:

ссылки в C++, ссылочные переменные с++

Результат работы программы:

ссылки в C++, ссылочные переменные с++

Мне  не совсем хочется нагружать вас какой-то дополнительной информацией о ссылках. Они чаще всего применяются именно для передачи параметров в функцию. В роли параметров могут выступать переменные, массивы (это нам знакомо). Но что более важно – по ссылке в функцию передаются объекты структур и классов. Придет время и мы поговорим об этом.

Единственное, что касается синтаксиса, если вам понадобится объявить ссылку в программе, то ее необходимо сразу инициализировать (показать для какой переменной она создана). Например:

ссылки в C++, ссылочные переменные с++Так в программе мы можем использовать имя ссылки для последующего обращения к данным, которые хранит aaa. Это если например кто-то до вас написал код и дал название переменной aaa. Этот программист знает, что она хранит количество ящиков. А вы, для  своего удобства, дали этой переменной псевдоним amountOfBoxes и используете это новое имя, дописывая какой-то новый код в программу.

Предлагаю посмотреть видео о параметрах функций, где в том числе рассказано и о ссылках.

6 thoughts on “Ссылки в C++

  1. Ссылка – это альтернативное имя переменной, ИМХО больше тут пояснять нечего. Переменная одна, имен несколько. По любому имени с переменной можно как угодно работать. В случае со ссылками в аргументах функций тоже самое, просто альтернативное имя переменной будет видно внутри функции.

    Ну и пару примеров я бы добавил.

    Т.к. указатель – это тоже переменная (просто хранит адрес объекта), то в функцию можно передавать ссылку на указатель например
    void foo(int &*arr);
    Ну типа того.

    И еще пример, есть 2 функции:
    void foo(int *a);
    void bar(int &a);
    Первая принимает ссылку на объект, вторая- указатель.

    Где-то в программе (например в функции main есть объект:
    int var = 123;

    Если надо передать его в первую функцию – то мы должны получить адрес объекта:
    foo(&var);
    Во вторую – можно просто передавать, при этом внутри функции будет использовать альтернативное имя объекта
    bar(var);
    Если нам надо будет определить указатель на объект – то он тоже должен инициализироваться адресом:
    int *p = &var;

    Внутри первой функции с объектом работают как обычно (ведь у нас просто есть альтернативное имя):
    void foo(int &a) { a = 456; }

    Во второй функции мы имеем указатель, поэтому вынуждены разыменовывать его для обращения к объекту:
    void bar(int *a) { *a = 789; }
    // если a – указатель,
    // то (*a) – объект,
    // и (&(*a)) – адрес объекта Скобочки можно убрать, поставил для ясности (они отражают приоритеты).

    1. Перепутаны названия.
      “И еще пример, есть 2 функции:
      void foo(int *a);
      void bar(int &a);
      Первая принимает ссылку на объект, вторая- указатель.”

      Наоборот!

  2. Ссылки – достаточно неприятное для начинающих понятие в C++ (хотя совершенно естественное даже для начинающих в Java или Python).

    Для начинающих можно сказать так (хотя это и не совсем точо):
    – ссылка на переменную – это в точности то же, что и указатель на неё, но к этой ссылке, в отличие от указателя, нельзя применять адресную арифметику (+, -, ++, –).

    Это неточно по смыслу, но сразу позволяет использовать ссылки в своём коде без ошибок.

    1. Олег, отлично что Вы уделяете внимание нашим статьям и делаете важные заметки к изложенному материалу. Спасибо и от админа сайта и, думаю, от посетителей )

    2. Ни один начинающий тебя не понимает. Твои объяснения совсем непонятны, следующая статься твоя и понять ее очень сложно, невозможно. А вот эта статья очень легка к восприятию. Не надо больше статей как Указатели на функции

      1. Что значит “ни один”? Не понимают только самые тупые ;-) … остальные хоть что-то, да понимают.

        Программирование – это вообще очень не простая инженерная дисциплина, и объяснять её “на пальца” невозможно и вредно так же, как, например, матанализ или начертательную геометрию.

        И освоить программирование смогут только те, кто будут много и упорно практиковаться и самостоятельно писать код.

        P.S. А от обучения на уровне объяснений “дважды два, детки, получается иногда четыре, если не возражаете” – никто и ничему не научится, возникнет только иллюзия что “я тоже чему-то там учился”.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *