Обмен значений переменных | Язык Паскаль

Обмен значений двух переменных

С клавиатуры вводятся два числа, каждое из которых присваивается своей переменной. После этого программа должна сама выполнять обмен значений переменных, то есть первой присваивать значение второй, а второй - значение первой; в конце выводить значения измененных переменных на экран.

Пример выполнения программы

3
45
x = 3, y = 45
x = 45, y = 3

Проблема обмена значений двух переменных заключается в том, что мы не можем непосредственно присвоить первой переменной значение второй, а потом второй - значение первой. Программа ниже содержит логическую ошибку:

var
    x, y: integer;

begin
    readln(x);
    readln(y);

    writeln('x = ', x, ', y = ', y);

    x := y;
    y := x;

    writeln('x = ', x, ', y = ', y);
end.

Дело в том, что когда выполняется выражение x := y, значение переменной x теряется. Теперь и переменная x, и переменная y связаны с одним и тем же значением. Тем, которое было изначально присвоено y. Поэтому когда выполняется следующее выражение (y := x), значение переменной y по-сути не меняется. Если выполнить программу выше и ввести числа 5 и 19, то получится такой результат:

5
19
x = 5, y = 19
x = 19, y = 19

Отсюда мы приходим к мысли, что необходима третья переменная. В нее мы будем сохранять значение первой переменной, и делать это перед тем, как оно будет утрачено. Вспомогательные переменные, предназначенные для временного хранения значений, принято называть буферными.

Алгоритм обмена значений двух переменных сводится к следующему:

  1. В буферной переменной сохраняется значение первой переменной.
  2. Первой переменной присваивается значение второй.
  3. Второй переменной присваивается значение буферной переменной, это значение равно исходному значению первой переменной.

Если b - это буферная переменная, тогда правильная программа на языке Паскаль может выглядеть так:

var
    x, y, b: integer;

begin
    readln(x);
    readln(y);

    writeln('x = ', x, ', y = ', y);

    b := x;
    x := y;
    y := b;

    writeln('x = ', x, ', y = ', y);
end.

Существует второй вариант решения данной задачи - арифметический. Этот способ позволяет избежать ввода в программу третьей переменной:

  1. Находим сумму значений обоих переменных и присваиваем ее первой переменной. Несмотря на то, что значение первой переменной теряется, оно учтено в сумме.
  2. Если из суммы вычесть значение второй переменной, то получим значение первой. Присвоим это значение второй переменной. Теперь мы теряем значение второй переменной. Однако оно учтено в сумме, которая присвоена первой переменной.
  3. Вычтем из суммы исходное значение первой переменной, которое теперь присвоено второй. Тем самым получим исходное значение второй переменной, которое присвоим первой.
var
    x, y: integer;

begin
    readln(x);
    readln(y);

    writeln('x = ', x, ', y = ', y);

    x := x + y;
    {Теперь в X хранится сумма.}

    y := x - y;
    {Из суммы вычитают значение второй переменной.
     В результате получают исходное значение первой.
     Его присваивают переменной Y.
     Значение переменной Y изменилось.}

    x := x - y;
    {В Y хранится значение первой переменной.
     Его вычитают из суммы, которая хранится в X.
     В результате получают исходное значение второй переменной.
     Его присваивают переменной X.}

    writeln('x = ', x, ', y = ', y);
end.