Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/65: Рейтинг темы: голосов - 65, средняя оценка - 4.52
0 / 1 / 4
Регистрация: 20.10.2013
Сообщений: 270

Написать функцию swap

26.03.2014, 14:26. Показов 15292. Ответов 73
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
был вот такой код:
C++
1
2
3
4
5
6
7
8
9
10
for(i = 0; i < n - 1; i++)
    {
        for(j = i + 1; j < n; j++)
        {
            if(p[i].pro < p[j].pro)
            {
            swap (p[i], p[j]);
            }
        }
    }
нужно теперь написать функцию swap, вот мои наброски, но почему то ничего не получается, помогите:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
for(i = 0; i < n - 1; i++)
    {
        for(j = i + 1; j < n; j++)
        {
            if(p[i].pro < p[j].pro)
            {
                void swap (p[i].pro, p[j].pro);
                int t = p[i].pro;
                p[i].pro = p[j].pro;
                p[j].pro = t;
            }
        }
    }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.03.2014, 14:26
Ответы с готовыми решениями:

Заменить функцию swap
У меня есть программа. Я задаю массив, потом мне выводится массив, в котором удаляются все повторяющиеся элементы. Как можно заменить...

Чем можно заменить функцию swap?
Чем можно заменить функцию swap? Она на моем компиляторе не работает. Библиотеку iostream включал.

Массив: Описать функцию swap(A,B), меняющую местами максимальные элементы матриц А и В.
Надо исправить программу чтобы заработала. У самой уже ничего не получается=(( Описать функцию swap(A,B), меняющую местами максимальные...

73
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.03.2015, 15:02
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от MrGluck Посмотреть сообщение
А они, как известно, сохраняют результат вычисления в левом операнде.
ещё известно, что многократное изменение одной и тоже переменной
на протяжении одной точки следования есть undefined behavior.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
15.03.2015, 16:01
Интересный момент...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int main()
{
    int i = 1;
    int a[] = { 3, 5 };
 
    a[0] ^= a[1] ^= a[0] ^= a[1];
 
    i = a[i++];
 
    printf( "%d\n", a[0] );
    printf( "%d\n", a[1] );
    return 0;
}
Компилятор GCC 4.9.2 с опциями -std=c++03 и -std=c++11 выдаёт предупреждение:
Bash
1
2
3
4
main.cpp: In function 'int main()':
main.cpp:9:12: warning: operation on 'i' may be undefined [-Wsequence-point]
  i = a[i++];
            ^
только на 10-ю строку.

Если компилировать этот же код как код языка Си этим же компилятором, то это же предупреждение будет распространяться на две строки - 8 и 10.

Цитата Сообщение от Tulosba Посмотреть сообщение
MrGluck, похоже ты не учел отсутствие точек следования.
раз, два.
Первая ссылка ведёт на вопрос по языку Си, вторая на вопрос по С++, но там какая-то каша в ответах в которую смешали Си и С++.

Лично для меня этот вопрос остаётся открытым.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.03.2015, 23:04
castaway, в c++11 заменили термин "sequence point" на отношения "sequenced before", "sequenced after". В связи с чем произошли некоторые изменения в поведении кода. В частности то, что выражение
C++
1
a[0] ^= a[1] ^= a[0] ^= a[1];
считалось до c++11 как UB, в текущем стандарте, судя по всему, таковым не является (поправьте, если я ошибаюсь).

Вырезка из Стандарта на счет оператора присваивания:
14882:2011 5.17/1
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
Косвенно это подтверждается твоим экспериментом при сборке кода в режимах C и C++11. Как с точки зрения предупреждений компилятора, так и с точки зрения результата выполнения.
У меня например такие результаты:
Bash
1
2
3
4
5
6
7
8
9
10
11
gcc -Wall main.c
main.c: In function ‘main’:
main.c:8:10: warning: operation on ‘a[0]’ may be undefined [-Wsequence-point]
     a[0] ^= a[1] ^= a[0] ^= a[1];
          ^
main.c:10:7: warning: operation on ‘i’ may be undefined [-Wsequence-point]
     i = a[i++];
       ^
./a.out
0
3
Bash
1
2
3
4
5
6
7
8
g++ -Wall main.c
main.c: In function ‘int main()’:
main.c:10:15: warning: operation on ‘i’ may be undefined [-Wsequence-point]
     i = a[i++];
               ^
./a.out
5
3
Хотя clang, что в режиме плюсов, что сей ругался только на
C++
1
i = a[i++];
и результат везде был одинаковым:
Bash
1
2
5
3
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8217 / 5048 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
16.03.2015, 00:03
Цитата Сообщение от Tulosba Посмотреть сообщение
Как с точки зрения предупреждений компилятора, так и с точки зрения результата выполнения.
Корректное поведение - частный случай UB

Я потому сразу и не увидел UB(?) что не заметил возможной неоднозначности. В отличи от кода
C++
1
i = i++ + ++i
здесь всё должно (в теории?) согласно правилу по моей ссылке выше преобразоваться в набор операций с последовательной записью в lhs.
0
 Аватар для Dennis Ritchie
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
16.03.2015, 00:32
Цитата Сообщение от MrGluck Посмотреть сообщение
здесь всё должно (в теории?) согласно правилу по моей ссылке выше преобразоваться в набор операций с последовательной записью в lhs.
Т. е. в C++11 так можно делать?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.03.2015, 16:00
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
Т. е. в C++11 так можно делать?
Однострочный вариант обмена через XOR возможен (не приводит к UB) в С++11.
http://stackoverflow.com/a/11989428/3240681
Ссылаются на тот же пункт из Стандарта, что и я.
2
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
17.03.2015, 19:51
Цитата Сообщение от Tulosba Посмотреть сообщение
C++
1
a[0] ^= a[1] ^= a[0] ^= a[1];
Эквивалентны ли следующие операторы?
C++
1
x = x ^ (y = y ^ (x = (x ^ y)));
C++
1
x ^= y ^= x ^= y;
Если так, то вот возможный результат.

C++
1
2
3
4
5
6
7
8
9
10
11
/* We evaluate left to right, doing both operands before the operation. */
x = 1; y = 2;
x = 1 ^ (y = y ^ (x = (x ^ y))); // left of outer 
x = 1 ^ (y = 2 ^ (x = (x ^ y))); // left of middle 
x = 1 ^ (y = 2 ^ (x = (1 ^ y))); // left of inner
x = 1 ^ (y = 2 ^ (x = (1 ^ 2))); // right of inner
x = 1 ^ (y = 2 ^ (x = 3)); // inner xor (right inner assign)
x = 1 ^ (y = 2 ^ 3); // inner assign (right middle xor)
x = 1 ^ (y = 1); // middle xor (right middle assign)
x = 1 ^ 1; // middle assign (right outer xor)
x = 0; // outer xor (right outer assign)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.03.2015, 22:50
Цитата Сообщение от Alex5 Посмотреть сообщение
Эквивалентны ли следующие операторы?
Эквивалентны.
Цитата Сообщение от Alex5 Посмотреть сообщение
Если так, то вот возможный результат.
Так это уже Java, а не C++.
И как сказано по приведенной тобой ссылке, в жабе в бинарном выражении всегда сначала вычисляется левый операнд.
В плюсах цепочка вычислений будет другая:
C++
1
2
3
4
5
6
7
8
x = 1; y = 2;
x = x ^ (y = y ^ (x = (x ^ y)));
x = x ^ (y = y ^ (x = (1 ^ 2)));
x = x ^ (y = y ^ (x = 3)); // здесь x стал равен трем.
x = x ^ (y = 2 ^ 3);
x = x ^ (y = 1); // здесь y стал равен единице.
x = 3 ^ 1;
x = 2; // здесь x стал равен двум.
В итоге значения обменялись.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8217 / 5048 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.03.2015, 23:24
Цитата Сообщение от Alex5 Посмотреть сообщение
Эквивалентны ли следующие операторы?
Я же выше ссылку проводил про right-to-left associativity и запись результатов в lvalue.
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
20.03.2015, 22:58
Цитата Сообщение от Tulosba Посмотреть сообщение
В плюсах цепочка вычислений будет другая:
Tulosba, что же другие цепочки вычислений в C++ невозможны?

Добавлено через 8 минут
Цитата Сообщение от MrGluck Посмотреть сообщение
Я же выше ссылку проводил про right-to-left associativity и запись результатов в lvalue
MrGluck, там что-нибудь говорится про порядок вычисления операндов? В каком порядке будут вызваны функции?
C++
1
2
3
4
5
6
7
8
int& f(int n)
{
    std::cout << n << std::endl;
    static int x = 0;
    return x;
}
/* Что будет выведено на экран? */
f(1) = f(2) = f(3);
0
 Аватар для Dennis Ritchie
555 / 148 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
21.03.2015, 04:29
Цитата Сообщение от Alex5 Посмотреть сообщение
В каком порядке будут вызваны функции?
Так ведь это неправильный код, даже на UB не тянет (конкретно неправильный код).
Ведь оператор присваивания работать не будет.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
21.03.2015, 10:13
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
#include <iostream>
 
struct A {
    A & operator = ( A & ) { return *this; }
};
 
int & foo( int n ) {
    std::cout << n << ' ';
    static int x;
    return x;
}
 
A & bar( int n ) {
    std::cout << n << ' ';
    static A a;
    return a;
}
 
int main() {
    foo( 1 ) = foo( 2 ) = foo( 3 ); // 1, 2, 3
    std::cout << std::endl;
    bar( 1 ) = bar( 2 ) = bar( 3 ); // 3, 2, 1
    std::cout << std::endl;
}
Кто-нибудь знает почему так происходит?
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
22.03.2015, 15:43
Цитата Сообщение от castaway Посмотреть сообщение
Кто-нибудь знает почему так происходит?
Любопытный момент, надо будет поизучать. А пока замечу, что с дефолтовой версией оператора присваивания порядок снова будет 1,2,3. Пруф.

Добавлено через 19 часов 53 минуты
Цитата Сообщение от Alex5 Посмотреть сообщение
что-нибудь говорится про порядок вычисления операндов?
Нашел например такую цитату:
There is no concept of left-to-right or right-to-left evaluation in C++, which is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time.
Проводя параллели с оператором присваивания можно утверждать, что выражение:
C++
1
f(1) = f(2) = f(3);
будет интерпретировано парсером так же как
C++
1
f(1) = (f(2) = f(3));
Однако, это никоим образом не задает порядок вызова функций f(). Единственное что гарантируется на основании упомянутого ранее пункта 5.17/1, то что f(2) и f(3) должны быть вызваны до правого присваивания, а f(1) до левого присваивания.
Проверим:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
struct A {
    A(int i) : i(i) {}
    A & operator = ( const A & a )
    { 
        std::cout << "op=(" << i << "," << a.i << ") ";
        i = a.i;
        return *this; 
    }
    int i = 0;
};
 
A & bar( int n ) {
    std::cout << "bar(" << n << ") ";
    return *new A(n);
}
 
int main() {
    bar( 1 ) = bar( 2 ) = bar( 3 );
    std::cout << std::endl;
}
Результат:
Code
1
bar(3) bar(2) op=(2,3) bar(1) op=(1,3)
Т.о. на вопрос
Цитата Сообщение от castaway Посмотреть сообщение
Кто-нибудь знает почему так происходит?
скорее всего ответ такой: компилятор сам определяет (implementation defined) порядок вычисления аргументов, для которых выполняется правило unsequenced (1.9/13). Возможно, когда оператор присваивания для пользовательского класса тривиальный (например, когда он явно не задан или задан как = default), компилятору проще вычислить сразу все аргументы, чем чередовать их вычисление с присваиванием.

Хотя вот например clang в любом случае вычисляет все операнды до присваивания. Не важно задан пользовательский оператор= или нет.

Подводя итог можно сказать: не стоит полагаться на порядок вычисления аргументов в цепочке присваиваний. Он может быть совсем не очевиден с первого взгляда.
5
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
27.03.2015, 23:03
Цитата Сообщение от Tulosba Посмотреть сообщение
Однако, это никоим образом не задает порядок вызова функций f().
Верно. И поэтому результат вычисления
C++
1
2
3
x = 1;
y = 2;
x = x ^ (y = y ^ (x = (x ^ y)));
может быть x == 0 (см. сообщение 67) или x == 2 (см. сообщение 68).

Добавлено через 12 минут
C++
1
2
3
4
x = 
    x /* здесь может быть исходное значение  x  или результат выражения  (x = (x ^ y)  */ 
    ^ 
    (y = y ^ (x = (x ^ y)));
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.03.2015, 23:03

Напишите функцию Swap(a, b), аргументами которой могут быть числа любого типа
Напишите функцию Swap(a, b), аргументами которой могут быть числа любого типа. Функция меняет значения своих аргументов и не возвращает...

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

Написать функцию, которая, в зависимости от выбора пользователя вызывает соответствующую функцию
Помогите, что то я не могу понять задачи, даже не знаю с чего начать)))) 5. Написать функцию, которая, в зависимости от выбора...

Написать функцию, которая могла бы передать значение в другую функцию
как сделать функцию которая бы могла передать значеие в другую функцию ну к примеру a=4*b; где b=sin(fi);

не могу разобраться как написать функцию сортировки и исправить функцию добавления в стек
#include &lt;iostream&gt; #include&lt;Windows.h&gt; using namespace std; struct NE{ int x; NE *pnext,*ppor,*cur;}; class SPISOK { NE...


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

Или воспользуйтесь поиском по форуму:
74
Ответ Создать тему
Новые блоги и статьи
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru