2009-12-01 2 views
4

Как можно обменивать указательные адреса внутри функции с помощью подписи?Обмен адресами указателей в C++

Скажем:

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

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

+0

У меня вопрос не возникает. Какие адреса вы хотите поменять местами? – sharptooth

+4

Вы можете поменять значения веса и высоты, но не их адреса –

ответ

14

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

#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); 

Ваш вопрос не выглядит очень четким.

+0

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

+0

Это неправильная практика и код для пропусков. 1) Неоправданно сложный. 2) Миксы Указатели и ссылки (Плохая практика). Я бы отказался от такого кода от каждого программиста, который его обрабатывал. –

+0

Я не могу согласиться (но я все еще новичок в C++, поэтому я могу ошибаться). 1) Почему это плохая практика? Разве мы не используем пропущенные объекты по ссылкам в целом? И указатель - это объект, поэтому он имеет право на то, чтобы с ним обращались как с одним.) Что сложного в этом я не могу сказать. 3) Я не вижу этого в качестве указателей смешивания и ссылочной ссылки - я просто вижу это как прохождение объект через ссылку, которая является довольно регулярной моей практикой.4) Плохая практика? Ну, в книге Б.С. Язык программирования на С ++ - это примеры ссылок на указатели, и они не отмечены как плохая практика, поэтому я думаю, что если это делается Б.С., я тоже могу это сделать –

8

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

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

Старый ответ: это был ответ, когда вопрос все еще подразумевается замена значений 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; 
} 

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

+1

Thats C, а не C++ и - если я могу прокомментировать это - последний подход менее интуитивно понятен. –

+0

redsoft: он отметил вопрос как c, так и C++ – Toad

+0

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

8

В C++ можно написать

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

или скорее просто использовать:

std::swap(a, b); 
+0

это только C++. Его вопрос также отмечен как c – Toad

+0

Да, но это совершенно другой язык. Поскольку он, очевидно, новичок, давайте помогаем ему учиться C++ и не путать его с толку. [Retagged]. – MSalters

+0

Заголовок этого сообщения: «... в C++», а не в «c» –

6

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

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

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

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

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

У вас есть другая функция обмена, видимо. Он принимает два указателя на целые числа, что означает, что он хочет адреса двух целых чисел. В этом случае их легко обеспечить. 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 
} 
+0

Хорошее объяснение; +1 – user9876

+0

+1 замена жены lol – 2009-12-01 14:07:53

1

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

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

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