Подтвердить что ты не робот

Какая разница между func (int & param) и func (int * param)?

В следующем коде оба amp_swap() и star_swap(), похоже, делают то же самое. Итак, почему кто-то предпочитает использовать один над другим? Какой из них является предпочтительным обозначением и почему? Или это просто вопрос вкуса?

#include <iostream>

using namespace std;

void amp_swap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

void star_swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a = 10, b = 20;
    cout << "Using amp_swap(): " << endl;
    amp_swap(a, b);
    cout << "a = " << a << ", b = " << b << endl;
    cout << "Using star_swap(): " << endl;
    star_swap(&a, &b);
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

Спасибо за ваше время!


См. также

Разница между переменной указателя и ссылочной переменной в С++

4b9b3361

Ответ 1

Один использует ссылку, один использует указатель.

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

Итак, если вы выполните:

star_swap(NULL, NULL);

Ваше приложение выйдет из строя. Если вы попытаетесь:

amp_swap(NULL, NULL); // This won't compile

Всегда используйте ссылки, если у вас нет причин использовать указатель.

Смотрите эту ссылку: http://www.google.co.uk/search?q=references+vs+pointers

Ответ 2

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

swap(a, b);
swap(&a, &b); // This cries "will modify arguments" loud and clear.

Конечно, в случае функции swap эта точка спорна; все знают, что его аргументы будут изменены. Есть и другие случаи, когда это менее очевидно. С# имеет ключевое слово ref именно по этой причине. В С# приведенное выше должно выглядеть следующим образом:

swap(ref a, ref b);

Конечно, есть другие способы документировать это поведение. Использование указателей - одна из допустимых методик этого.

Ответ 3

Ссылки не могут быть NULL. Таким образом, использование первой версии не позволит вызывающему абоненту передавать NULL в качестве одного из аргументов функции.

Ссылки не могут быть переназначены, чтобы указать на что-то еще. Итак, вы знаете, что в функции amp_swap(), что x и y всегда относятся к одной и той же вещи. В версии указателя вы можете (в более сложной функции) переназначить x и y, чтобы указать на что-то еще, что может сделать логику менее ясной (да, вы могли бы объявить параметры как int *const x, чтобы избежать этого переназначение).

Тело функции для эталонной версии выглядит более чистым, потому что у него не так много звезд.

Ответ 4

Это не относится к обозначениям.

Есть 3 способа передать параметры функции:

  • по значению
  • по ссылке
  • указателем

В amp_swap вы передаете фактические параметры по ссылке. Это введено и действует только на С++.

В star_swap вы передаете параметры с помощью указателей. Это был оригинальный C-образный путь.

В принципе, если вы используете С++, рекомендуется использовать ссылку, поскольку она более читаема для переменных. Если вам нужны указатели, обязательно используйте их.

И не забудьте использовать знак & при объявлении метода со ссылками, потому что в противном случае вы создадите ошибку. Если вы не объявите ссылку в amp_swap, функция ничего не заменит. Потому что таким образом вы используете метод 1 (передайте только значения параметра), и в функции будут созданы две новые автоматические переменные, которые живут только в пределах функции. Таким образом, внешние внешние переменные не будут затронуты.

Ответ 5

Если вы посмотрите здесь, вы можете найти описание Pointer vs Reference, самый полезный бит информации изначально приходит из этой цитаты.

С++ не позволяет вам объявлять "константную ссылку", потому что ссылка по своей сути является константой. Другими словами, как только вы привязываете ссылку на ссылку на объект, вы не можете переустановить ее для обращения к другому объекту. Нет никаких обозначений для перезаписи ссылки после того, как вы указали ссылку.

Следующие привязки ri относятся к i.

int &ri = i;

Тогда назначение, такое как:

ri = j;

не свяжет ri с j. Он присваивает значение в j объекту, на который ссылается ri, а именно: i.

Надеюсь, что это яснее.

Ответ 6

(int *param) - это более старый стиль C, с использованием указателя прямой памяти. (int &param) - это современный стиль С++, используя ссылку (безопасная оболочка обертка вокруг исходного указателя). Если вы используете С++, вы, вероятно, должны использовать ссылку.

Ответ 7

  • Как и указатель, ссылка позволяет изменять данные, переданные в качестве параметра
  • Как и указатель, ссылка позволяет полиморфизм
  • В отличие от указателя ссылка никогда не будет NULL (вы все равно можете добиться этого с помощью какого-то взлома, но это более похоже на саботаж, чем кодирование...)
  • В отличие от указателя ссылка, когда const, активирует продвижение типа (т.е. имеет функцию с параметром std::string, принимающим char *)
  • В отличие от указателя ссылка не может быть повторно назначена: нет способа изменить ее в какой-либо точке кода, тогда как указатель может указывать на A в одной точке, B на другую и NULL на другой снова, И вы не хотите, чтобы ++ применялся к вашему указателю по ошибке...
  • В отличие от указателя эта ссылка делает манипуляции с данными такими же простыми, как и с примитивными типами "int" или "bool", без использования оператора * все время

По этим причинам в С++ ссылочное использование обычно является значением по умолчанию, а указателем является исключение.

Итак, для согласованности между двумя "свопами", которые вы предлагаете, я бы использовал amp_swap и удалил звезду из источников (просто чтобы убедиться, что никто ее не будет использовать и добавит бесполезный код указателя в источниках)...

Ответ 8

Это то же самое для компьютера. Тем не менее, один является ссылкой (&), а другой - указателем (*)

http://www.google.com/search?hl=en&q=pointers+vs+references&btnG=Google+Search&aq=1&oq=pointers+vs

Я считаю, что у них обоих есть свои возможности - как с указателями, вы можете делать более малую работу с низким уровнем памяти, но синтаксис ссылок проще.

:)