Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
#1

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

07.06.2013, 22:56. Просмотров 503. Ответов 12
Метки нет (Все метки)

Мне надо написать функцию которая меняет значение 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;
}

В чем ошибка?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2013, 22:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос "Ругается" на оперетор побитового исключения (C++):

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года &quot;весна&quot;, &quot;лето&quot;, &quot;осень&quot;, &quot;зима&quot; определить погоду &quot;тепло&quot;, &quot;жарко&quot;, &quot;холодно&quot;, &quot;очень холодно&quot;. Я так...

Реализовать классы "Воин", "Пехотинец", "Винтовка", "Матрос", "Кортик" (наследование) - C++
Разработать программу с использованием наследования классов, реализующую классы: − воин; − пехотинец(винтовка); − матрос(кортик). ...

Создать класс "Книга" с полями "название книги", "количество страниц", "год издания" - C++
Создать класс Книга поля: название книги,количество страниц,год издания методы: вычислить сколько лет книге и количество дней прошедших...

Создать абстрактный класс "Издание" и производные классы "Книга", "Статья", "Электронный ресурс" - C++
1. Создать абстрактный класс Издание с методами, позволяющими вывести на экран информацию об издании, а также определить является ли данное...

Создать класс "Вентилятор" содержащий в себе классы: "Двигатель", "Контроллер", "Пульт управления" - C++
Помогите с кодом написания задачи, не понимаю как написать классы в классе. Нужно создать класс &quot;вентилятор&quot; содержащий в себе классы:...

В методе Гаусса ругается на system("chcp 1251") и на abs() - C++
Реализуется решения СЛАУ методом Гаусса #include &lt;iostream&gt; using namespace std; // Вывод системы уравнений void sysout(double **a,...

12
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 **"
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.06.2013, 23:09 #3
В том, что вы берёте адреса аргументов. В том, что такой способ медленнее временной переменной. В том, что его несколько геморройно заставить работать для чего-то кроме чисел.
1
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;
Адресс - это же тоже по своей сути число, так почему мы не можем такие же операции как с числами провести?

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

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

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

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

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

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

Мне надо поменять их значения.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.06.2013, 23:33 #7
Цитата Сообщение от Harutyunyan Посмотреть сообщение
если мы возьмем адресс переменной &str1 то получим адресс на первый элемент и со сторой так же, на сколько я понял.
Плохо вы поняли. char* — это не "строковой тип". Это тип "указатель на char". Указатель. Адрес. Просто строки в Си представляются как указатели на первый символ. Это уже адреса. Их и надо менять местами. Значения, которые уже адреса. Без всяких &.
1
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'; 
}
а я совсем не понял что происходит))
0
l2ded
80 / 68 / 11
Регистрация: 10.05.2011
Сообщений: 284
07.06.2013, 23:45 #9
Цитата Сообщение от Harutyunyan Посмотреть сообщение
C++
1
template<typename>
C++
1
template<typename T>
0
Kastaneda
Jesus loves me
Эксперт С++
4703 / 2907 / 239
Регистрация: 12.12.2009
Сообщений: 7,405
Записей в блоге: 2
Завершенные тесты: 1
08.06.2013, 10:04 #10
Я своими глазами видел, как компилятор из кода
C++
1
2
3
int tmp = a;
a = b;
b = tmp;
сделал одну (!!!) ассемблерную инструкцию, которая меняет местами значения своих аргументов. Т.е. компилятор понял, что происходит в этом коде и предложил свой лучший вариант (даже лучше ксоров).
Поэтому в век оптимизирующих компиляторов об этом можно не думать. Если только вы не пишите под какую-нибудь специфичную железяку, используя какой-нибудь специфичный самописный компилятор.
2
Harutyunyan
1 / 1 / 0
Регистрация: 28.09.2012
Сообщений: 91
08.06.2013, 10:24  [ТС] #11
Спасибо, я понемаю что компилятор включает какой то оптимизитор.
Мне просто на собесодовании среди задач попалась и такая, надо поменять значение 2-х переменных не используя дополнительной.

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

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

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

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

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

экспрес ругается на #include "stdafx.h". Что делать? - C++
запуская программу в ВС Экспресс 2008. выдает вот такую ошибку: что делать,расскажите пожалуйста) Добавлено через 4 минуты ...

Антивирус ругается на компилятор. "Suspicious Object" - C++
Всем доброго вечера. С недавнего времени (раньше было всё нормально) антивирус (eset smart security 9) начал сообщать об &quot;угрозе&quot; когда я...

Определить тип данных "Запись", имеющий поля "Фамилия", "Пол", "Зарплата" - C++
определить тип данных запись имеющий поля фамилия пол зарплата. определить массив из 10 записей. в программе ввести в массив данные и...

Реализовать структуру "Анкета" с полями "Фамилия", "Пол" и "Адрес" - C++
Здравствуйте. Проходим тему Структуры, не могу понять, как определить количество, само задание: #include &lt;iostream&gt; #include...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.