собственная функция swap, почему и как она работает?
Функция свапает значения, было 10 и 20, стало 20 и 10. Функция должна принимать два указателя на тип int, а в итоге принимает две переменные типа int, и еще, непонятно почему, работающее тело функции «a = b; b = a», не понимаю, как это работает?
Отслеживать
задан 18 июн 2018 в 17:07
31 1 1 золотой знак 1 1 серебряный знак 2 2 бронзовых знака
Для начала уберите using namespace std; и убедитесь, что ваша функция на самом деле не используется. Также см. ADL
18 июн 2018 в 17:16
Ваша функция никак не работает. Как правильно заметил VTT, она вообще не используется в вашем коде.
18 июн 2018 в 18:03
Можно не убирать using. , а добавить :: перед swap . Этого будет достаточно, чтоб убедиться в некомпилируемости такого вызова nfrjq функции 🙂
Функция SWAP в языке С: что это и как работает
![]()
Функция SWAP в С — простой способ обменять значения двух переменных, которые содержат одинаковые типы данных. Эта функция доступна из стандартной библиотеки. В основном ее применяют для работы с небольшими данными, потому что она несет в себе конструкцию из копирования значений переменных и обмена этих значений. Такая конструкция задействует определенный объем памяти. А это значит, что , если применить функцию SWAP в Си для работы с большими данными, с низится производительность программы.
Функция SWAP в С
Для простой реализации функции SWAP в Си из стандартной библиотеки можно воспользоваться следующим шаблоном:
#include
using std::swap;
int main()
int x = 8;
int y = 9;
// после выполнения программы результат будет таким: x = 9, y = 8
>
Функция SWAP в С может применяться и в более сложных конструкциях, например:
#include
#include
#include
int main ()
int a=100, b=200; //присваиваем значения переменным: a=100, b=200
std::swap(a,b); // функция swap меняет значения переменных: a=200, b=100
std::vector foo (2,a), bar (3,b) //проводим операции: foo:2×200 bar:3×100
std::swap(foo, bar); //swap меняет значения операций: foo:3×100 bar:2×200
std:: cout < < “ foo содержит: “;
for (std::vector::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout < < ` < < *it;
std::cout < < `\n`;
return 0;
>
После выполнени я э та программ а нам выдаст следующий результат:
foo содержит: 100 100 100
Функция SWAP в С работает не только с числами, но и с другими типами данных, например со строками:
#include
using namespace std;
int main()
string a = “Функция“;
string b = “Программирование“;
cout
cout
swap (a, b);
cout < < “Значение переменной «а» после применения функции SWAP: “
cout
retorn 0;
>
Результат выполнения такой программы будет следующий:
Значение переменной «а» до применения функции SWAP: Функция
Значение переменной «b» до применения функции SWAP: Программирование
Значение переменной «а» после применения функции SWAP: Программирование
Значение переменной «b» после применения функции SWAP: Функция
Заключение
Функция SWAP в С работает с любыми типами данных. Чтобы она сработала, у переменных обязательно должно быть какое-то значение. Она ничего не возвращает, а просто меняет местами значения переменных.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Swap c что это
Когда нужно изменить состояние одного или нескольких объектов, и на любом этапе модификации может возникнуть ошибка, для создания кода, устойчиваого к ошибкам, может применяться идиома копирования и замены ( copy-and-swap idiom ). Суть данной идиомы состоит в следующей последовательности действий:
- Создаем копию объекта(ов)
- Изменяем копию. При этом оригинальные объекты остаются нетронутыми
- Если все изменения прошли успешно, заменяем оригинальный объект измененной копией. Если же при изменении копии на каком-то этапе возникла ошибка, то оригинальный объект не заменяется.
Обычно эта идиома применяется в функциях и частным, хотя и распространенным, случаем ее применения является оператор присваивания. В общем случаем это выглядит так:
// оператор присвоения некоторого класса Copyable Copyable& operator=(const Copyable& obj) < Copyable copy; // создаем копию через конструктор копирования swap(copy); // обмениваем значения копии и оригинального объекта return *this; > // некоторая функция для обмена значениями void swap(Copyable& copy) noexcept;
В функции оператора присваивания сначала создается временная копия присваиваемого объекта. И в случае успешного создания копиии текущий объект (this) и копия обмениваются содержимым через некоторую функцию swap() .
Функция swap может быть реализована как внешняя функция или как функция-член класса (в примере выше предполагается, что она реализована внутри класса). При этом функция swap определяется как не генерирующая исключения (с ключевым словом noexcept ). Поэтому единственной точкой, где может возникнуть исключение, функция копирования (конструктор копирования) объекта. Если копирование не удается, то управление не доходит до выполнения функции swap.
Устойчивость к исключениям заключается в том, что в операторе присваивания нет точки, где генерация исключения могла бы привести к утечке памяти. Приведённая выше реализация также устойчива к присваиваниям объекта самому себе (a=a), однако содержит издержки, связанные с тем, что временная копия в этом случае тоже будет создаваться. Исключить издержки можно дополнительной проверкой:
// оператор присвоения некоторого класса Copyable Copyable& operator=(const Copyable& obj) < Copyable copy; // создаем копию через конструктор копирования if(this != &obj) // если не текущий объект swap(copy); // обмениваем значения копии и оригинального объекта return *this; > // некоторая функция для обмена значениями void swap(Copyable& copy) noexcept;
Рассмотрим реализацию этого принципа. Но сначала посмотрим, какую проблему мы можем решить с помощью подобной идиомы. Пусть у нас есть следуюший класс:
template class Array < public: Array(unsigned size) : data< new T[size] >, size <> // выделяем память ~Array() < delete[] data;>// освобождаем память // оператор присвоения Array& operator=(const Array& array) < if (&array != this) < delete[] data; // освобождаем память size = array.size; data = new T[size]; // выделяем память - может столкнуться с std::bad_alloc // копируем значения for (unsigned i<>; i < size; ++i) data[i] = array.data[i]; // можем столкнуться с исключением в зависимости от типа T >return *this; > // оператор индексирования для доступа к элементам T& operator[](unsigned index) < return data[index]; >unsigned getSize() const private: T* data; // хранимые данные unsigned size; // размер массива >;
Здесь шаблон класса Array в конструкторе получает некоторый размер и использует его для выделения динамической памяти для массива. В деструкторе динамическая память освобождается.
Array(unsigned size) : data< new T[size] >, size <> // выделяем память ~Array() < delete[] data;>// освобождаем память
В функции оператора присваивания нам надо присвоить значения объекта-параметра текущему объекту. Для этого освобождаем ранее выделенную память и выделяем заново память для нового массива. В данном случае кажется, что все нормально, поскольку память удалена. Но посмотрим на выделение памяти:
data = new T[size];
Но надо отметить, что оператор new[] генерирует исключение std::bad_alloc , если по какой-то причине не удалось выделить память. Например, когда надо выделить память под очень большой массив, который не помещается в доступной памяти.
Если оператор new[] не может выделить новую память, указатель data становится так называемым висячим указателем — указателем на освобожденную память. Поэтому даже если мы обработаем исключение bad_alloc, то объект Array будет непригоден для использования. А на этапе вызове деструктора мы столкнемся со сбоем.
Далее в цикле присваиваем значения элементам массива data:
data[i] = array.data[i];
В данном случае элементу типа T присваивается значение типа T. Однако T может представлять любой тип. И этот тип должен поддерживать оператор присвоения. Но в этом операторе присвоения также может быть реализована какая-нибудь логика, которая может генерировать исключения.
Изменим код, применив идиому копирования и замены:
#include template class Array < public: Array(unsigned size) : data< new T[size] >, size <> // выделяем память ~Array() < delete[] data;>// освобождаем память Array(const Array& array) : Array < for (unsigned i <>; i < size; ++i) data[i] = array.data[i]; >// оператор присвоения Array& operator=(const Array& other) < Arraycopy< other >; // вызываем конструктор копирования swap(copy); // обмениваем значениями return *this; > // оператор индексирования для доступа к элементам T& operator[](unsigned index) < return data[index]; >// функция обмена значениями void swap(Array& other) noexcept < std::swap(data, other.data); // обмениваем два указателя std::swap(size, other.size); // обмениваем размеры >unsigned getSize() const private: T* data; // хранимые данные unsigned size; // размер массива >; int main() < const unsigned count ; // количество элементов Array values; // создаем объект // присваиваем элементам values некоторые значения for (unsigned i <>; i < count; ++i) < values[i] = i; >Array numbers; numbers = values; // применение оператора присвоения // выводим элементы из объекта numbers на консоль for (unsigned i <>; i < numbers.getSize(); ++i) < std::cout std::cout
Прежде всего здесь добавлен конструктор копирования, где, чтобы не повторять логику выделения памяти, вызываем обычный конструктор и копируем значения в текущий объект.
Array(const Array& array) : Array < for (unsigned i <>; i
Таким образом, мы получим копию текущего объекта.
Для обмена значениями реализована функция swap:
void swap(Array& other) noexcept < std::swap(data, other.data); // обмениваем два указателя std::swap(size, other.size); // обмениваем размеры >
Для упрощения для обмена значениями применяется стандартная функция std::swap из стандартной библиотеки C++, которая обменивает значения двух параметров, используя их оператор копирования. Фактически здесь обмениваем значениями по отдельности элементы динамического массива и размеры массива.
В функции оператора присваивания применяем конструктор копирования и функцию swap:
Array& operator=(const Array& other) < Arraycopy< other >; // вызываем конструктор копирования swap(copy); // обмениваем значениями return *this; >
Далее в функции main мы можем создать объект Array и присвоить его другому объекту:
Array numbers; numbers = values; // применение оператора присвоения
0 1 2 3 4
Хотя часто подобный способ применяется именно в операторах присвоения, но также он может применяться в других ситуациях, где необходимо выполнить устойчивую к исключениям модификацию объекта. И всегда принцип будет тот же. Сначала копируем объект, который надо изменить. Далее выполняем над объектом-копией изменения. И если все пройдет удачно, обмениваем значениями целевой объект и объект-копию.
Функция swap
Функция swap()
А что выгоднее с точке зрения быстродействия — использование стандартной функции или "ручной" обмен.

Функция swap
Доброго времени суток! Задался вопросом о реализации алгоритмов обмена двух переменных, но кроме.
Двусвязный список. Функция swap
Дописать в класс list функцию: swap – поменять содержимое текущего списка с заданным. #pragma.
Функция swap. error C2106: =: левый операнд должен быть левосторонним значением
Выдает ошибки: error C2106: =: левый операнд должен быть левосторонним значением в чем причина.
683 / 232 / 16
Регистрация: 15.10.2007
Сообщений: 1,247
покажи функцию свап
Регистрация: 16.10.2009
Сообщений: 7
Извиняюсь, я просто с телефона, а эту функцию не реально так набрать
Добавлено через 41 секунду
Это стандартная функция
![]()
4726 / 2547 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
Я специально для Вас разбил чтение переменных и вывод их на экран. swap() меняет значения местами. Вот в таком виде работает.
1 2 3 4 5 6 7 8 9 10 11 12 13
#include using namespace std; int main() { int a,b; cin>>a; cin>>b; swap(a,b); couta; coutb; return(0); }
Регистрация: 16.10.2009
Сообщений: 7
Спасибо огромное, valeriikozlow. Просто в книге был приведен пример с оператором взятия.
Добавлено через 1 минуту
Mecid, тоже спасибо.
Регистрация: 16.10.2009
Сообщений: 7
Продолжаю изучение языка. Сегодня новая ошибка
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include #include using namespace std; int sravn(int a, int b) //процедура выводит возвращает меньшее значение { if (a>b) return(b); else return(a); } int main() { srand(time(0)); int m[10],i; for(i=0; i10; ++i)//запись в масив 10 элементов { m[i]=rand()%50; } for (i=0; i10; ++i) { cout[ i]<' '; }cout; int q=m[0],l; for (l=0; l10; l++); //ЭТОТ ЦИКЛ ВЫПОЛНЯЕТСЯ ОДИН РАЗ. { for (i=0; i10; ++i)//Поиск меньшего { q=sravn(m[i],q); } cout;
swap(m[l],q); } for (i=0; i10; ++i)//вывод результата { cout[ i]<' '; } return(0); }
![]()
4726 / 2547 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
for (l=0; l10; l++); //ЭТОТ ЦИКЛ ВЫПОЛНЯЕТСЯ ОДИН РАЗ.
сразу после условия цикла стоит опреатор «;». Это так называемый пустой оператор, он ничего не выполняет. Сам цикл у тебя выполняется 10 раз (не выполняя ничего), но по окончании цикла у тебя переменная l=10.
Затем строка 36:
swap(m[l],q);
m[10] — за пределами границ массива.
Я думаю что Вы хотели данным кодом провести сортировку массива. Я прав?
Регистрация: 16.10.2009
Сообщений: 7
M128K145, при редактировании моего поста вы удалили часть моего кода.
Добавлено через 2 минуты
valeriikozlov, так точно спасибо, уже исправил.
1980 / 1098 / 693
Регистрация: 25.04.2016
Сообщений: 3,119
В данном случае swap(m[l],q); приведет к тому, что будут заменены значение ячейки массива и значение переменной, т.е. мы получим m[l] = q; В результате все элементы массива будут заменены минимальным элементом массива.
Чтобы сортировка выбором минимума работала, нам нужно сделать хотя бы так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include #include using namespace std; #define N 5 int main (void) { srand(time(NULL)); int i, k, a[N]; for(i = 0; i N; i++) // запись в масив 10 элементов cout ( 4) <(a[i] = rand() %25); cout ; for (i = 0; i N; i++) { // сортировка выбором int min_pos = i; // минимума for (k = i+1; k N; k++) if (a[k] a[min_pos]) min_pos = k; swap(a[i], a[min_pos]); } for (i = 0; i N; i++) // массив на экран cout ( 4) [i]; cout ; return 0; }
Кстати, писать функцию sravn() не имело смысла, поскольку в c++ уже есть min(). Да и не нужна она для поиска минимума, что продемонстрировано в примере выше.
Однако такая сортировка весьма неэффективна, поскольку нам приходится каждый раз проходить по оставшимся элементам массива, даже если они уже отсортированы. Т.е. в массиве 1 2 3 мы трижды пройдем по всем элементам массива.
Сначала мы найдем минимум из 1 2 3 и поменяем местами 1 и 1,
затем проверим 2 и 3, и поменяем местами 2 и 2,
и наконец найдем минимум 3 и заменим 3 на 3.
Т.е. выполним кучу ненужных действий.
И чтобы этого избежать, нам хотя бы нужно проверять значения min_pos и i, чтобы не обменивать число само на себя:
1 2 3 4 5 6 7 8
for (i = 0; i N; i++) { // сортировка выбором int min_pos = i; // минимума for (k = i+1; k N; k++) if (a[k] a[min_pos]) min_pos = k; if (min_pos != i) swap(a[i], a[min_pos]); }
что правда не избавляет от необходимости поиска минимума среди неотсортированных элементов массива, т.е. время выполнения все равно остается n в квадрате.
Как бы то ни было, написание своего алгоритма сортировки сродни изобретению велосипеда и если заниматься этим не хочется, можно сделать гораздо проще, например так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include #include #include #include using namespace std; #define N 5 int main (void) { srand(time(NULL)); vector int> a(N); for (int i = 0; i N; i++) // запись в масив 10 элементов cout ( 4) <(a[i] = rand() %25); cout ; sort(a.begin(), a.end()); // сортировка по возрастанию for (auto x: a) // массив на экран cout ( 4) ; cout ; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include #include #include using namespace std; #define N 5 int main (void) { srand(time(NULL)); int a[N]; for (int i = 0; i N; i++) // запись в масив 10 элементов cout ( 4) <(a[i] = rand() %25); cout ; sort(a, a + N); // сортировка for (auto x: a) // массив на экран cout ( 4) ; cout ; return 0; }
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Функция swap перестановки значений двух переменных для данных разных типов. Используйте template
не могу решить ( честно говоря вообще не понимаю его ) ((((( Напишите функцию swap перестановки.
SWAP
Кто может объяснить как выходит (10 10) #include <iostream> using namespace std; void Swap(int.
swap
max, swap, min входят в <iostream> это стандартные функции?
swap
Ф-ция swap, ее написание/подключение. В общем объясните и расскажите как ее подключить и т.д.