Разработка и Конфигурация · 11 мин
Как поменять переменные местами без третьей переменной в 1С
Как поменять значения двух переменных местами в 1С без третьей переменной: арифметический способ, XOR, множественное присваивание. Примеры кода, ограничения и ошибки.
Задача обмена значений двух переменных без использования третьей — классическое упражнение, которое часто встречается на собеседованиях и в учебных задачах по программированию. В 1С она тоже решаема, хотя встроенного языка имеет свои особенности: строгая типизация при арифметических операциях, отсутствие некоторых привычных операторов и специфика работы с числами.
Сразу важная оговорка: в реальном прикладном коде конфигураций обмен через третью (временную) переменную — это нормальная и предпочтительная практика. Он читаем, безопасен и работает с любыми типами данных: строками, датами, ссылками на объекты. Способы «без третьей переменной» применимы в основном к числам и нужны скорее для понимания языка, решения олимпиадных задач или прохождения технических интервью.
Ниже разобраны рабочие варианты обмена значениями во встроенном языке 1С, их ограничения, типичные ошибки и способы проверки результата.
Классический обмен через третью переменную как точка отсчета
Прежде чем отказываться от временной переменной, полезно зафиксировать эталонный вариант. Он выглядит так:
Временная = А;
А = Б;
Б = Временная;
Этот код работает с любым типом данных: числами, строками, датами, ссылками на элементы справочников и документов, массивами. Он не зависит от значений переменных, не переполняется и очевиден для любого разработчика, который будет читать код после вас. Именно поэтому в прикладных решениях — обработках проведения документов, сортировках, перестановках строк табличных частей — используется именно он.
Понимание эталона важно еще и для проверки: любой альтернативный способ должен давать ровно тот же результат на тех же входных данных. Если после «хитрого» обмена значения отличаются от результата классического варианта — способ применен неверно или не подходит для этих данных.
Арифметический способ через сложение и вычитание
Самый известный способ обмена чисел без третьей переменной — арифметический. Идея проста: сначала в одну переменную записывается сумма обоих значений, затем из нее последовательно «извлекаются» исходные значения.
А = А + Б; // теперь А хранит сумму
Б = А - Б; // Б получает исходное значение А
А = А - Б; // А получает исходное значение Б
Разберем на примере. Пусть А = 5, Б = 12. После первой строки А = 17, Б = 12. После второй: Б = 17 - 12 = 5. После третьей: А = 17 - 5 = 12. Значения поменялись местами.
Способ работает и с отрицательными числами, и с дробными, поскольку сложение и вычитание в 1С корректно обрабатывают и те и другие. Однако есть ограничение: при очень больших значениях сумма может выйти за пределы допустимой разрядности числа. Встроенный язык 1С работает с числами ограниченной точности (как правило, до 38 знаков с учетом настроек), и переполнение приведет либо к ошибке, либо к потере точности — и обмен даст неверный результат.
А = А + Б;
Б = А - Б;
А = А - Б;Вариант через умножение и деление
Аналогичная схема строится на умножении и делении:
А = А * Б;
Б = А / Б;
А = А / Б;
Этот вариант заметно капризнее. Он ломается, если одна из переменных равна нулю: деление на ноль вызовет ошибку выполнения. Дробные значения тоже дают погрешности из-за округления. Поэтому вариант с умножением стоит рассматривать только как теоретическое упражнение, а в любых практических проверках использовать сложение и вычитание.
Обмен через XOR и почему в 1С это неудобно
В низкоуровневых языках популярен обмен через побитовое исключающее ИЛИ (XOR):
А = А XOR Б;
Б = А XOR Б;
А = А XOR Б;
Метод не требует дополнительной памяти и не страдает от переполнения, поскольку не выполняет арифметики. Проблема в том, что во встроенном языке 1С нет привычного оператора XOR для чисел как единой конструкции обмена. Побитовые операции доступны через внешние компоненты или специализированные объекты, и для прикладной задачи обмена значений это явный перебор.
Если на собеседовании вас просят показать XOR-обмен, корректный ответ для 1С — объяснить принцип на псевдокоде и указать, что в типовой разработке на платформе применяют арифметический способ или временную переменную. Это демонстрирует и знание теории, и понимание инструмента.
Сравнение вариантов
Универсально, читаемо, работает с любыми типами. Ограничений нет — стандарт для прикладного кода.
Только числа. Риск переполнения при очень больших значениях, подходит для учебных задач.
Только ненулевые числа. Погрешности на дробях, ошибка при нуле — практически не применяется.
Нет переполнения, но в 1С нет прямого оператора — требует обходных решений, неудобен.
Работает с любыми типами, но формально использует промежуточное хранилище — спорно для строгой формулировки задачи.
Обмен через массив или структуру
Если формулировка задачи допускает отказ именно от третьей переменной, но не от промежуточного хранилища вообще, можно использовать коллекции. Например, массив:
Массив = Новый Массив;
Массив.Добавить(А);
Массив.Добавить(Б);
А = Массив[1];
Б = Массив[0];
Такой подход работает с любым типом данных, включая строки и ссылки, и не боится переполнения. Формально третья переменная в классическом смысле не объявляется — вместо нее создается объект коллекции. На практике это тот же временный буфер, только дороже: создание массива требует больше ресурсов, чем одна переменная.
Аналогично можно использовать структуру с двумя ключами или даже список значений. Смысл один: промежуточное хранилище всё равно существует, просто оформлено иначе. Если задача поставлена строго («никаких дополнительных данных»), этот способ не засчитывается, и остается только арифметический вариант для чисел.
- 1Убедитесь, что обе переменные имеют числовой тип и не равны Неопределено
- 2Оцените порядок значений: сумма не должна выходить за разумную разрядность
- 3Выполните А = А + Б
- 4Выполните Б = А - Б
- 5Выполните А = А - Б
- 6Проверьте результат выводом обоих значений через Сообщить() или отладчик
Проверка результата и контрольные точки
Проверить корректность обмена проще всего в отладчике конфигуратора или через вывод значений. Минимальный тестовый фрагмент:
А = 5;
Б = 12;
А = А + Б;
Б = А - Б;
А = А - Б;
Сообщить("А = " + А + ", Б = " + Б);
Ожидаемый результат: А = 12, Б = 5. Проверяйте не один набор значений, а несколько: положительные числа, отрицательные, ноль, одинаковые значения в обеих переменных, дробные числа. Особое внимание — случаю А = Б: корректный алгоритм должен оставить значения на месте, а не обнулить их.
Дополнительный прием — сравнение с эталоном: выполните обмен новым способом и параллельно классическим на копиях данных, затем сравните пары значений. Любое расхождение означает, что способ неприменим к данному набору входных данных.
Как проверить результат
А содержит исходное Б, Б содержит исходное А
Одно из значений потеряно или продублировано
Значения остались прежними
Появился ноль или искаженное число
Ноль корректно переместился
Ошибка деления на ноль (способ с умножением)
Результат точный
Потеря разрядов, округление, ошибка переполнения
Типичные ошибки и ограничения
Первая и самая частая ошибка — попытка применить арифметический обмен к нечисловым данным. Операция «строка + строка» в 1С выполняет конкатенацию, а вычитание строк вызовет ошибку. Ссылки на объекты, даты, булевы значения арифметике не поддаются вовсе. Перед обменом без третьей переменной убедитесь, что оба значения — числа, например через ТипЗнч().
Вторая ошибка — игнорирование переполнения. Если переменные хранят, например, крупные суммы или идентификаторы, их сумма может превысить допустимую разрядность. Симптом — ошибка выполнения или «тихая» потеря точности, после которой обмен возвращает искаженные значения.
Третья группа ошибок связана с невнимательностью: перепутанный порядок строк (например, А = А - Б вместо Б = А - Б на втором шаге), использование уже измененного значения там, где нужно исходное, применение способа с делением при нулевом значении. Каждая такая опечатка дает результат, который выглядит «почти правильно» и потому трудно отлавливается без тестов.
Когда какой способ выбирать
Правило выбора простое. Если вы пишете прикладной код конфигурации — обработку, модуль документа, процедуру перестановки строк табличной части — всегда используйте временную переменную. Это дешевле по ресурсам, чем создание массива, и не накладывает ограничений на типы данных.
Если задача учебная или собеседование требует обмена без третьей переменной — берите арифметический способ через сложение и вычитание, предварительно оговорив, что он работает только для чисел и уязвим к переполнению. Такой ответ показывает и знание приема, и понимание его границ.
Если строгая формулировка запрещает любое промежуточное хранилище, а данные нечисловые — честный ответ: задача во встроенном языке 1С в общем случае не решается. Это не недостаток знаний, а корректная оценка ограничений платформы.
Как выбрать действие
Частые вопросы
Можно ли поменять местами две строки без третьей переменной в 1С?
Строго без промежуточного хранилища — нет. Арифметические операции к строкам неприменимы: сложение строк выполняет конкатенацию, а вычитание вызовет ошибку. Вариант с массивом или структурой формально обходится без третьей переменной, но использует объект как буфер.
Работает ли арифметический способ с дробными числами?
Да, сложение и вычитание корректно работают с дробными значениями. Однако при большом количестве знаков после запятой возможны погрешности представления чисел, поэтому для финансовых расчетов такой прием лучше не использовать.
Что будет, если обе переменные равны?
Арифметический способ через сложение и вычитание отработает корректно: значения останутся на месте. А вот способ через умножение и деление при равных значениях тоже сработает, но при нулевых — вызовет ошибку деления на ноль.
Есть ли в 1С встроенная функция для обмена значений?
Нет, во встроенном языке платформы нет стандартной процедуры Swap. Обмен всегда реализуется вручную — через временную переменную или один из описанных приемов.
Можно ли поменять местами значения двух реквизитов объекта?
Да, логика та же: реквизиты объекта — это переменные со своими типами. Для числовых реквизитов технически возможен арифметический обмен, но в прикладном коде корректнее использовать временную переменную, чтобы не нарушать типизацию и не рисковать данными.
Почему на собеседованиях вообще спрашивают про обмен без третьей переменной?
Задача проверяет понимание того, как данные хранятся и изменяются, а не практическую потребность. Хороший ответ включает не только сам прием, но и оговорки: ограничение по типам, риск переполнения и то, что в реальном коде применяют временную переменную.
Что важно запомнить
Обмен без третьей переменной в 1С реализуется арифметически (А=А+Б; Б=А-Б; А=А-Б) только для чисел и с риском переполнения. Способ с умножением ломается на нуле. Для любых типов данных в прикладном коде стандарт — временная переменная; массив годится как компромисс, если запрещена именно третья переменная, а не хранилище.