назначение параметров функции с двумя операторами косвенности (C ++) - PullRequest
1 голос
/ 08 февраля 2020

Для чего нужен параметр функции, имеющий два оператора косвенности?

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


void addrchanger(int**);

int main()
{
    int value1 = 4;
    int* value1ptr = &value1;
    std::cout<<&value1<<std::endl;

    addrchanger(&value1ptr);
    std::cout<<&value1<<std::endl;
    //the address of value1 doesn't change.
}

void addrchanger(int** foo)
{
    //this is an attempt to change the address of value1 to the next slot
    ++**foo;
}

Ответы [ 3 ]

1 голос
/ 08 февраля 2020

Цель - передать указатель на указатель (и) или указатель на массив (ы). Такая практика C подобна историческим функциям, таким как main () char** argv (поэтому вы также хотите arg c, потому что указатель не может определить размер). Он также используется, когда требуется вернуть указатель, поэтому вы передаете указатель на указатель, как во многих функциях Win32.

Например, в StringFromIID

HRESULT StringFromIID(
  REFIID   rclsid,
  LPOLESTR *lplpsz
);

вы должны передать двойной указатель в качестве 2-го параметра (wchar_t**), чтобы получить указатель, который должен быть освобожден, как говорит do c.

Избегайте этого полностью в настоящее время в C ++ и использует std :: vector с любой необходимой глубиной.

0 голосов
/ 08 февраля 2020

Когда p имеет тип int **,

++**p

увеличивает значение типа int, представленного **p.

, чтобы изменить адрес объекта int указывает на то, что вы будете использовать

++*p

При прямом доступе к вашей переменной вы будете использовать на один * меньше для всего:

int *p;
++*p; // increment the int value
++p; // increment the pointer

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

function f(int **p) {
  ++**p; // increment the int value
  ++*p; // increment the pointer
  // you can also increment the argument
  // but you can't know whether it will then
  // still point to another int pointer:
  ++p
}

Кроме того, вы можете использовать & вместо * в C ++, который используется только для объявления переменной в качестве ссылки, а затем работает как секретный, скрытый указатель. Вы снова используете на единицу меньше *, как вначале вне функции.

function f(int *&p) {
  ++*p; // increment the int value
  ++p; // increment the pointer
  // you can also not increment the reference itself,
  // as it is a hidden pointer.
}

Это звучит опасно, потому что кому нужны секретные указатели? Но это очень распространено в C ++, потому что людям нравится печатать меньше * повсюду.

0 голосов
/ 08 февраля 2020

Функция void addrchanger(int** foo) может изменять:

  • значение: (**foo)++ делает int value1 до 5
  • и адрес: (*foo)++ делает value1ptr указанием на следующий пробел после value1

Я полагаю, вы ожидали, что ++**foo переместит value1 на следующую позицию, а это не так.

Указатель на указатель также полезно для объявлений матриц, но большинство библиотек, таких как библиотека GNU scientifi c, BLAS, OpenGL glLoadMatrixf(), предпочитают использовать один указатель.

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