Обмен адресами указателей в C ++ - PullRequest
4 голосов
/ 01 декабря 2009

Как можно поменять адреса указателя внутри функции с подписью?

Допустим,

int weight, height;
void swap(int* a, int* b);

Таким образом, после выхода из этой функции адреса реальных параметров (weight и height) будут изменены. Возможно ли это вообще?

Ответы [ 5 ]

16 голосов
/ 01 декабря 2009

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

#include <cassert>
void swap(int*& a, int*& b)
{
    int* c = a;
    a = b;
    b = c;
}

int main()
{
    int a, b;
    int* pa = &a;
    int* pb = &b;

    swap(pa, pb);

    assert(pa == &b);  //pa now stores the address of b
    assert(pb == &a);  //pb now stores the address of a
}

Или вы можете использовать функцию обмена STL и передать ей указатели.

#include <algorithm>

std::swap(pa, pb);

Ваш вопрос, кажется, не очень ясен.

8 голосов
/ 01 декабря 2009

В C ++ вы бы написали

 void swap(int *a, int *b)
 {
    std::swap(*a, *b);
 }

или, скорее, просто используйте:

 std::swap(a, b);
8 голосов
/ 01 декабря 2009

Новый ответ (поскольку вопрос был переформулирован)

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

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

вызов функции:

 int width=10, height=20;
 swap(&width, &height)

реализация:

 void swap(int *a, int *b)
 {
      int temp;
      temp=*a;
      *a = *b;
      *b = temp;
 }

или ... без использования временной переменной:; ^)

 void swap(int *a, int *b)
 {
      *a ^= *b;
      *b ^= *a;
      *a ^= *b;
 }

обратите внимание, что последний метод не работает в этом случае: swap (& a, & a). Очень резко указал user9876 в комментариях.

6 голосов
/ 01 декабря 2009

Похоже, вы немного запутались в терминах.

У объекта обычно есть адрес.Это место в памяти, где находится объект.Некоторые временные объекты не имеют адресов, потому что их не нужно хранить.Таким исключением является временный объект «4» в выражении (2+2)*3

. Указатель - это объект, который хранит адрес другого объекта.Следовательно, для каждого типа есть соответствующий указатель.int имеет int*, std::string имеет std::string* и так далее.

Теперь вы пишете об «адресах указателей».Они существуют.В конце концов, я написал, что указатель - это объект, и поэтому он имеет свой собственный адрес.И вы можете сохранить этот адрес в другом указателе.Например, вы можете сохранить адрес и int* в int* *.Но ты действительно хотел этого?Или вы имели в виду «адрес , на который ссылается через указатель»?

Теперь вы приводите рост и вес в качестве примеров.Стандартный способ поменять их в C ++ - это просто std::swap(width, height).Обратите внимание на std::, который является префиксом для функций стандартной библиотеки C ++.std::swap поменяет почти все.целые, поплавки, жены.(j / k).

Очевидно, у вас есть другая функция подкачки.Он принимает два указателя на целые числа, что означает, что он хочет адреса двух целых чисел.Это легко обеспечить в этом случае.width является целым числом, а &width является его адресом.Это может быть сохранено в аргументе указателя int* a.Точно так же вы можете сохранить адрес &height в аргументе int*b.Собрав все вместе, вы получите звонок swap(&width, &height);

Как это работает?Функция swap(int*a, int*b) имеет два указателя, которые содержат в памяти адрес двух целых чисел.Итак, что он может сделать, это [1] отложить в сторону копию первого целого числа, [2] скопировать второе целое число в памяти, где было первое целое число, и [3] скопировать первое целое число обратно в память, где второецелое число былоВ коде:

 void swap(int *a, int *b)
 {
      int temp = *a; // 1
      *a = *b;       // 2
      *b = temp;     // 3
 }
1 голос
/ 01 декабря 2009

Если вы хотите изменить адрес указателей, вы должны передать указатели этих указателей в качестве параметров:

void swap(int **a, int **b); //as prototype

Эти примеры - просто изменения значений указателей.

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