Форум программистов, компьютерный форум CyberForum.ru

"Ругается" на оперетор побитового исключения - C++

Войти
Регистрация
Восстановить пароль
 
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
07.06.2013, 22:56     "Ругается" на оперетор побитового исключения #1
Мне надо написать функцию которая меняет значение 2-х переменных местами, без использования дополнительной переменной.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
using std::cout;
using std::cin;
 
template<typename T>
void swap(T &a, T &b) {
    &a ^= &b ^= &a ^= &b;
}
 
int main() {
    char *str1 = "str1", *str2 = "str2";
    cout << str1 << " : " << str2 << "\n";
    swap<char*>(str1, str2);
    cout << str1 << " : " << str2;
    cin.get();
           return 0;
}

В чем ошибка?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2013, 22:56     "Ругается" на оперетор побитового исключения
Посмотрите здесь:

C++ Ругается на "!="
C++ экспрес ругается на #include "stdafx.h". Что делать?
Определить "Y" с точностью до члена ряда меньшего "e"(допустим: 0.001) C++
C++ Подсчитать, колько раз в произвольном тексте встречается символ "*" и "+"
C++ В заданном двоичном коде заменить все цифры "0" на "1" и наоборот
Перебрать все слова длиной не более n, составленные из букв "а" и "b" C++
Error C2361: пропуск инициализации "Height" из-за метки "default" C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
l2ded
 Аватар для l2ded
80 / 68 / 11
Регистрация: 10.05.2011
Сообщений: 284
07.06.2013, 23:07     "Ругается" на оперетор побитового исключения #2
Цитата Сообщение от Harutyunyan Посмотреть сообщение
Мне надо написать функцию которая меняет значение 2-х переменных местами, без использования дополнительной переменной.

Код
void swap(T &a, T &b) {
	&a ^= &b ^= &a ^= &b;}
^= - недопустимо, правый оператор имеет тип "char **"
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1238 / 987 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.06.2013, 23:09     "Ругается" на оперетор побитового исключения #3
В том, что вы берёте адреса аргументов. В том, что такой способ медленнее временной переменной. В том, что его несколько геморройно заставить работать для чего-то кроме чисел.
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
07.06.2013, 23:15  [ТС]     "Ругается" на оперетор побитового исключения #4
то что такую ошибку выдает я вкурсе, но почему? как ее исправить? что неправильно делаю?

Добавлено через 5 минут
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
В том, что вы берёте адреса аргументов. В том, что такой способ медленнее временной переменной. В том, что его несколько геморройно заставить работать для чего-то кроме чисел.
Смотрите, у нас есть 2 переменные числового типа:

тут все работает.
C++
1
2
3
4
5
int a,b;
...
a = a ^ b; 
b = b ^ a; 
a = a ^ b;
А если у нас строковые переменные:

C++
1
2
3
4
5
char *a,*b;
...
&a = &a ^ &b; 
&b = &b ^ &a; 
&a = &a ^ &b;
Адресс - это же тоже по своей сути число, так почему мы не можем такие же операции как с числами провести?

Если поменяем адреса,то все будут норм.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1238 / 987 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.06.2013, 23:17     "Ругается" на оперетор побитового исключения #5
Цитата Сообщение от Harutyunyan Посмотреть сообщение
то что такую ошибку выдает я вкурсе, но почему? как ее исправить? что неправильно делаю?
Для этого вам придётся ответить на сложный вопрос:
Вы хотите поменять местами значения переменных или их адреса?
А после этого обдумать целесообразность наличия операторов & в вашей реализации обмена.
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
07.06.2013, 23:31  [ТС]     "Ругается" на оперетор побитового исключения #6
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Для этого вам придётся ответить на сложный вопрос:
Вы хотите поменять местами значения переменных или их адреса?
А после этого обдумать целесообразность наличия операторов & в вашей реализации обмена.

Вы меня запутали))

Если у нас есть 2 переменные строкового типа:

char *str1 = "str1", *str2 = "str2";

если мы возьмем адресс переменной &str1 то получим адресс на первый элемент и со сторой так же, на сколько я понял.

Если мы поменяем эти 2-адреса местами, то получиться при обращении к переменной str1 у нас покажет строку которая наченается с адреса второй переменной.

Мне надо поменять их значения.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1238 / 987 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.06.2013, 23:33     "Ругается" на оперетор побитового исключения #7
Цитата Сообщение от Harutyunyan Посмотреть сообщение
если мы возьмем адресс переменной &str1 то получим адресс на первый элемент и со сторой так же, на сколько я понял.
Плохо вы поняли. char* — это не "строковой тип". Это тип "указатель на char". Указатель. Адрес. Просто строки в Си представляются как указатели на первый символ. Это уже адреса. Их и надо менять местами. Значения, которые уже адреса. Без всяких &.
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
07.06.2013, 23:38  [ТС]     "Ругается" на оперетор побитового исключения #8
Спасибо, можно пожалуйста пример?

мне тут одни добрый человек написал этот код:

C++
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
#include <iostream> 
 
using namespace std; 
 
template<typename> 
void myswap(T &a, T &b) { 
    a ^= b ^= a ^= b; 
} 
 
template<typename> 
void myswap(T *&a, T *&b) { 
    a = (T *)((size_t)a ^ (size_t)b); 
    b = (T *)((size_t)b ^ (size_t)a); 
    a = (T *)((size_t)a ^ (size_t)b); 
} 
 
int main() { 
    int a = 1, b = 2; 
    cout << a << ' ' << b << '\n'; 
    myswap(a, b); 
    cout << a << ' ' << b << '\n'; 
 
    char *c = "asdf", *d = "hjkl"; 
    cout << c << ' ' << d << '\n'; 
    myswap(c, d); 
    cout << c << ' ' << d << '\n'; 
}
а я совсем не понял что происходит))
l2ded
 Аватар для l2ded
80 / 68 / 11
Регистрация: 10.05.2011
Сообщений: 284
07.06.2013, 23:45     "Ругается" на оперетор побитового исключения #9
Цитата Сообщение от Harutyunyan Посмотреть сообщение
C++
1
template<typename>
C++
1
template<typename T>
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
08.06.2013, 10:04     "Ругается" на оперетор побитового исключения #10
Я своими глазами видел, как компилятор из кода
C++
1
2
3
int tmp = a;
a = b;
b = tmp;
сделал одну (!!!) ассемблерную инструкцию, которая меняет местами значения своих аргументов. Т.е. компилятор понял, что происходит в этом коде и предложил свой лучший вариант (даже лучше ксоров).
Поэтому в век оптимизирующих компиляторов об этом можно не думать. Если только вы не пишите под какую-нибудь специфичную железяку, используя какой-нибудь специфичный самописный компилятор.
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
08.06.2013, 10:24  [ТС]     "Ругается" на оперетор побитового исключения #11
Спасибо, я понемаю что компилятор включает какой то оптимизитор.
Мне просто на собесодовании среди задач попалась и такая, надо поменять значение 2-х переменных не используя дополнительной.

Я сделал только для типа int, теперь хотел бы узнать, каким образом можно сделать для любых типов.

Хоть это число, строка или даже объект.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1238 / 987 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
08.06.2013, 10:48     "Ругается" на оперетор побитового исключения #12
Цитата Сообщение от Harutyunyan Посмотреть сообщение
Мне просто на собесодовании среди задач попалась и такая, надо поменять значение 2-х переменных не используя дополнительной.

Я сделал только для типа int, теперь хотел бы узнать, каким образом можно сделать для любых типов.

Хоть это число, строка или даже объект.
В качестве ответа на вопрос из собеседования это окей. Для чисел есть ещё вариант со сложением и вычитанием, например. Для любых типов, боюсь, так просто не получится. В принципе можно написать функцию, которая будет трактовать любой объект как последовательность байтиков определённой длины и обменивать местами байтики. Но это работает только для так называемых POD-типов — фактически, структурок Си. Объекты Си++ могут иметь определённые свойства, которые они возможно хотели бы сохранить, поэтому их нельзя просто так перемещать в памяти. Для этого нужен некоторый контракт. Вы можете или сами потребовать у объектов определять метод swap(), или же воспользоваться контрактами языка: конструкторами копирования, перемещения, операторами присваивания и т. п.

Цитата Сообщение от Kastaneda Посмотреть сообщение
Я своими глазами видел, как компилятор из кода сделал одну (!!!) ассемблерную инструкцию, которая меняет местами значения своих аргументов. Т.е. компилятор понял, что происходит в этом коде и предложил свой лучший вариант (даже лучше ксоров).
А если обе переменные в момет обмена находятся в регистрах, то инструкций не надо вообще: просто дальше считаем, что переменная A в регистре, в котором была переменная B, и наоборот.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2013, 10:53     "Ругается" на оперетор побитового исключения
Еще ссылки по теме:

C++ Сколько существует способов расставить между цифр знаки "+" и "-"
"Красный Тигр" vs. "Желтый Заяц". А каким будет 3005 год? C++
C++ Найти угол одной точки "A" в соотношении к точке "B" в градусах
C++ В методе Гаусса ругается на system("chcp 1251") и на abs()
Антивирус ругается на компилятор. "Suspicious Object" C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
08.06.2013, 10:53  [ТС]     "Ругается" на оперетор побитового исключения #13
Спасибо, с числами я так тоже сделал:

C++
1
2
3
4
5
int a,b;
...
a += b;
b = a - b;
a -= b;
Yandex
Объявления
08.06.2013, 10:53     "Ругается" на оперетор побитового исключения
Ответ Создать тему
Опции темы

Текущее время: 02:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru