Передача аргумента указателя, передача по значению в C ++? - PullRequest
27 голосов
/ 13 декабря 2010

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

В этом случае является ли приемлемой / стандартной процедурой использование указателя на указатель в качестве аргумента функции для изменения значения указателя как такового внутри функции?

Ответы [ 5 ]

33 голосов
/ 13 декабря 2010

Да, обоим.

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

Если вы хотите отразить изменения, внесенные в указатель на внешний указатель (сделать его указателем на что-то другое), вам необходимо два уровня косвенности (указатель на указатель). При вызове функций это делается путем помещения & перед именем указателя. Это стандартный способ работы с Си.

При использовании C ++ использование ссылок предпочтительнее указателя (далее также указатель на указатель).

Для почему ссылки должны быть предпочтительнее указателей, есть несколько причин:

  • ссылки вводят меньше синтаксического шума, чем указатели в теле функции
  • ссылки содержат больше информации, чем указатели, чем может быть полезно для компилятора

Недостатки ссылок в основном:

  • они нарушают простое правило передачи по значению C, что делает понимание поведения функции относительно параметров (будут ли они изменены?) Менее очевидным. Вам также нужен прототип функции, чтобы быть уверенным. Но это на самом деле не хуже, чем несколько уровней указателей, необходимых при использовании C.
  • они не поддерживаются C, что может быть проблемой при написании кода, который должен работать как с программами на C, так и с C ++ (но это не самый обычный случай).

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

8 голосов
/ 13 декабря 2010

Я понимаю путаницу здесь. Понятия «передача по значению» и «передача по ссылке» не столь ясны, даже если они кажутся таковыми. Имейте в виду, что компьютер не знает этих понятий и не ведет себя в соответствии с ним. Компьютер не знает о типах. Следовательно, он не делает различий между указателями и ценностями. Позвольте мне попытаться объяснить и пример:

void func1(int x)
{
   x = 5;
}

void func2(int *x)
{
   int a;
   x = &a;
}

Операция одинакова для машины в обеих функциях: она получает аргумент и изменяет его. Обратите внимание, что во второй функции она не модифицирует * x, она модифицирует x .

Теперь, если мы вызовем эти функции,

int y = 10;

func1(y); //value of y does not change

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

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

Если бы мы написали func2 как

void func2(int *x)
{ 
   *x = 5; 
}

Тогда это будет реальный случай "вызова по ссылке".

0 голосов
/ 23 июня 2019

Передача по значению с использованием указателей Я объясню это на примере:

void f(int *ptr)
{
   cout<<*ptr;
}


int main ()
{
   int a=10;
   int *aptr=&a;
   f(aptr);
   return 0;
} 

Здесь в основной функции a есть целочисленная переменная, содержимое которой10 и адрес 00F8FB04 (предположим).aptr - указатель на целое число, в котором хранится адрес целочисленной переменной a, поэтому содержимое aptr - это адрес целочисленной переменной a, который является 00F8FB04.Когда мы передаем aptr в качестве аргумента функции, только содержимое aptr (то есть адрес) копируется в параметр функции.Итак, ptr получит копию содержимого aptr (то есть адрес 00F8FB04)

0 голосов
/ 13 декабря 2010

Да, как и в C.

В этом случае является ли приемлемой / стандартной процедурой использование указателя на указатель в качестве аргумента функции для изменения значения указателя как такового внутри функции?

В каком случае? Чего ты хочешь? Вы можете использовать реальные ссылки с модификатором &.

void func(type &ref);
0 голосов
/ 13 декабря 2010

Либо указатель на указатель, либо ссылка на указатель - это то, что вы будете использовать, если хотите потенциально изменить сам указатель. На ваш первоначальный вопрос, технически, да, все параметры передаются по значению.

...