В чем разница между func (int & param) и func (int * param)? - PullRequest
12 голосов
/ 10 октября 2008

В следующем коде и 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;
}

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


Смотрите также

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

Ответы [ 8 ]

13 голосов
/ 10 октября 2008

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

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

Так что если вы делаете:

star_swap(NULL, NULL);

Ваше приложение будет аварийно завершено. Тогда как если вы попробуете:

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

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

См. Ссылку: http://www.google.co.uk/search?q=references+vs+pointers

4 голосов
/ 10 октября 2008

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

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

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

swap(ref a, ref b);

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

2 голосов
/ 10 октября 2008

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

C ++ не позволяет вам объявлять «константную ссылку», потому что ссылка по своей сути> const. Другими словами, когда вы связываете ссылку для ссылки на объект, вы не можете повторно привязать ее для ссылки на другой объект. Нет обозначения для повторного связывания ссылки после того, как вы объявили ссылку.

Следующее связывает ри со ссылкой на i.

int &ri = i;

Затем присваивание, такое как:

ri = j;

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

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

2 голосов
/ 10 октября 2008

Это не вопрос обозначений.

Существует 3 способа передачи параметров в функцию:

  1. по значению
  2. по ссылке
  3. по указателю

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

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

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

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

2 голосов
/ 10 октября 2008

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

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

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

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

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

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

1 голос
/ 10 октября 2008

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

0 голосов
/ 10 октября 2008

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

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

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

:)

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