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

Проходит ли указатель указателя, передается по значению в С++?

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

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

4b9b3361

Ответ 1

Да для обоих.

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

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

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

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

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

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

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

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

Ответ 2

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

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; 
}

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

Ответ 3

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

Ответ 4

Да, это так, как в C.

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

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

void func(type &ref);

Ответ 5

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

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)