Язык Си - руководство для начинающих
Шрифт:
printf(" %d %d\n" , pooh, &pooh);
получим
24 12126
Более того, машинный код, соответствующий первому оператору, словами можно выразить приблизительно так: "Поместить число 24 в ячейку с адресом 12126".
Воспользуемся указанной выше операцией для проверки того, в каких ячейках хранятся значения переменных, принадлежащих разным функциям, но имеющих одно и то же имя.
/* контроль адресов */
main
{
int pooh = 2, bah = 5;
printf("
printf('B main, bah = %d и&bah = %u\n>/, bah, &bah);
mikado(pooh);
}
mikado(bah) int bah;
{
int pooh = 10;
printf("B mikado, pooh = %d и&pooh = %u\n, pooh, &pooh);
printf(" Вmikado, bah = %d и&bah = %u\n" , bah, &bah);
}
Мы воспользовались форматом %u (целое без знака) для вывода на печать адресов на тот случай, если их величины превысят максимально возможное значение числа типа int. В нашей вычислительной системе результат работы этой маленькой программы выглядит так:
Вmain, pooh = 2 и&pooh = 56002
B main, bah = 5 и&bah = 56004
B mikado, pooh = 10 и&pooh =55996
В mikado, bah = 2 и &bah = 56000.
О чем это говорит? Во-первых, две переменные pooh имеют различные адреса. То же самое верно и относительно переменных bah. Следовательно, как и было обещано, компьютер рассматривает их как четыре разные переменные. Во-вторых, при вызове mikado(pooh) величина (2) фактического аргумента (pooh из main) передастся формальному аргументу (bah из mikado). Обратите внимание, что было передано только значение переменной. Адреса двух переменных (pooh в main и bah в mikado) остаются различными.
Мы коснулись второго вопроса потому, что этот факт оказывается неверным для всех других языков. В той или иной процедуре Фортрана, например, можно использовать переменные вызывающей программы. Кроме того, в такой процедуре переменные могут иметь различные имена, но адреса их при этом будут совпадать. В языке Си подобные механизмы отсутствуют. Каждая функция использует свои собственные переменные. Это более предпочтительно, потому что "исходные" переменные не будут таинственным образом изменяться из-за того, что вызванная функция обладает побочным эффектом. Но это может также приводить и к некоторым трудностям, о чем и будет рассказано и следующем разделе.
ИЗМЕНЕНИЕ ПЕРЕМЕННЫХ В ВЫЗЫВАЮЩЕЙ ПРОГРАММЕ
Иногда требуется, чтобы одна функция могла изменять переменные, относящиеся к другой. Например, в задачах сортировки часто бывает необходимо осуществлять обмен значениями между двумя переменными. Предположим, у нас есть две переменные х и у и мы хотим, чтобы они обменялись своими значениями. Простая последовательность операторов
х = у;
y = х;
не является решением поставленной задачи, потому что к тому моменту, когда начнет выполняться оператор во второй строке, первоначальное значение переменной x будет потеряно. Чтобы сохранить это первоначальное значение, необходимо дополнить
данный фрагмент еще одной строкой:temp = х;
х = у;
у = temp;
Теперь у нас есть требуемый метод; реализуем его в виде некоторой функции, а также создадим драйвер для eе проверки. Чтобы сделать более ясным, какая переменная принадлежит функции main, а какая - функции interchange, мы будем использовать переменные х и у в первой из них, и u и v– во второй.
/* обмен1 */
main
{
int х = 5, у = 10;
printf(" Вначале х = %d и у = %d.\n" , х, у);
interchange(x, у);
prinlf(" Теперь х = %d и у = %d.\n" , х, у);
}
interchangce(u, v) int u, v;
{
int temp;
temp = u;
u = v;
v = temp;
}
Попробуем выполнить эту программу. Результаты будут выглядеть следующим образом:
Вначале х = 5 и у = 10.
Теперь х = 5 и у = 10.
Не может быть! Значения переменных не поменялись местами! Вставим в программу interchange несколько операторов печати, чтобы понять причину допущенной ошибки.
/* обмен2 */
main
{
int х = 5, у = 10;
printf(" Вначале х = %d и у = %d.\n", х,у);
interchange(x, у);
printf(" Теперь х = %d и у = %d.\n", х, у);
}
interchange(u, v)
int u, v;
{
int temp;
printf(" Вначалеu = %d иv = %d.\n", u, v);
temp = u;u = v;v = temp;
printf(" Теперь u = %d и v = %d.\n", u, v);
}
Результат работы этой программы выглядит так:
Вначале x = 5 и y = 10.
Вначале u = 5 и v = 10.
Вначале u = 10 и v = 5.
Вначале x = 5 и y = 10.
Отсюда видно, что ничего неправильного в работе функции interchange нет; она осуществляет обмен значениями между переменными u и v. Проблема состоит в передаче результатов обратно в функцию main. Как мы уже указывали, функции interchange и main используют различные переменные, поэтому обмен значениями между переменными u и v не оказывает никакого влияния на х и у! А нельзя ли каким-то образом воспользоваться оператором return? Мы могли бы, конечно, завершить тело функции interchange строкой