Array M. УЭИТ - Язык Си - руководство для начинающих
- Название:Язык Си - руководство для начинающих
- Автор:
- Жанр:
- Издательство:Мир
- Год:1988
- Город:Москва
- ISBN:5-03-001309-1 /русск./
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Array M. УЭИТ - Язык Си - руководство для начинающих краткое содержание
Язык Си — руководство для начинающих
Язык Си - руководство для начинающих - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
ИЗМЕНЕНИЕ ПЕРЕМЕННЫХ В ВЫЗЫВАЮЩЕЙ ПРОГРАММЕ
Иногда требуется, чтобы одна функция могла изменять переменные, относящиеся к другой. Например, в задачах сортировки часто бывает необходимо осуществлять обмен значениями между двумя переменными. Предположим, у нас есть две переменные хи уи мы хотим, чтобы они обменялись своими значениями. Простая последовательность операторов
х = у;
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( )строкой
return(u);
и изменить форму вызова в функции main( )следующим образом:
х = interchange(x, у);
В результате такого обращения к функции переменная хполучит новое значение, но упри этом не изменится.
С помощью оператора return в вызывающую программу можно передать только одну величину . Но нам нужно передать две величины. Это оказывается вполне осуществимым! Для этого нужно лишь воспользоваться " указателями ".
Указатели: первое знакомство
Указатели? Что это такое? Вообще говоря, указатель - некоторое символическое представление адреса. Например, ранее мы воспользовались операцией получения адреса для нахождения адреса переменной pooh. В данном случае &poohозначает "указатель на переменную pooh". Фактический адрес - это число (в нашем случае 56002), а символическое представление адреса &poohявляется константой типа указатель. После всего сказанного выше становится очевидным, что адрес ячейки, отводимой переменной pooh, в процессе выполнения программы не меняется.
В языке Си имеются и переменные типа указатель. Точно так же как значением переменной типа charявляется символ, а значением переменной типа int- целое число, значением переменной типа указатель служит адрес некоторой величины. Если мы дадим указателю имя ptr, то сможем написать, например, такой оператор
ptr = &pooh; /* присваивает адрес pooh переменной ptr */
Мы говорим в этом случае, что ptr"указывает на" pooh. Различие между двумя формами записи: ptrи &pooh, заключается в том, что ptr- это переменная, в то время как &pooh- константа. В случае необходимости мы можем сделать так, чтобы переменная ptrуказывала на какой-нибудь другой объект:
ptr = &bah; /* ptr указывает на bah, а не на pooh */
Теперь значением переменной ptrявляется адрес переменной bah.
Операция косвенной адресации: *
Предположим, мы знаем, что в переменной ptrсодержится ссылка на переменную bah. Тогда для доступа к значению этой переменной можно воспользоваться операцией "косвенной адресации" ( *). (Не путайте эту унарнуюоперацию косвенной адресации с бинарнойоперацией умножения *).
val = *ptr; /* определение значения, на которое указывает ptr */
Последние два оператора, взятые вместе, эквивалентны следующему:
val = bah;
Использование операций получения адреса и косвенной адресации оказывается далеко не прямым путем к результату; отсюда и появление слова "косвенная" в названии операции.
Резюме: операции, связанные с указателями
I. Операция получения адреса &
Когда за этим знаком следует имя переменной, результатом операции является адрес указанной переменной.
Пример:
& nurse дает адрес переменной nurse.
II. Операция косвенной адресации
* Когда за этим таком следует указатель на переменную, результатом операции является величнна, помещенная и ячейку с указанным адресом.
Пример:
nurse = 22;pir = &nurse; /* указатель на nurse */ val = *ptr;
Результатом выполнения этого фрагмента является присваивание значения 22 переменной val.
Описание указателей
Мы знаем, как описывать переменные типа intи других типов. Но как описать переменную типа "указатель"? На первый взгляд это можно сделать так:
pointer ptr; /* неправильный способ описания указателя */
Почему нельзя использовать такую запись? Потому что недостаточно сказать, что некоторая переменная является указателем. Кроме этого, необходимо сообщить еще, на переменную какого типа ссылается данный указатель! Причина заключается в том, что переменные разных типов занимают различное число ячеек, в то время как для некоторых операций, связанных с указателями, требуется знать объем отведенной памяти. Ниже приводятся примеры правильного описания указателей:
Читать дальшеИнтервал:
Закладка: