Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
* u = * v;
который, в конечном счете, дает следующий результат:
X = у;
Итак, подведем итоги рассмотренного примера. Пам была нужна функция, которая меняет между собой значения переменных х и у. Передавая в функцию адреса х и у, мы предоставляем interchange() доступ к этим переменным. Используя указатели и операцию *, эта функция может выяснить значения, хранящиеся в этих ячейках, и изменить их.
В прототипе ANSI С имена переменных можно не указывать. Тогда объявление в прототипе будет выглядеть так:
void interchange(int *, int *);
В общем случае в функцию можно передать два вида информации о переменной. Если вызов имеет следующий вид, то в функцию передается значение переменной х:
functionl(х);
Если же вызвать функцию, как показано ниже, в нее передается адрес переменной х:
function2(&х);
Функции 361
Первая форма требует, чтобы определение функции включало формальный аргумент того же типа, что и х:
int functionl (int num)
Во второй форме определение функции должно включать формальный параметр, который является указателем на корректный тип:
int function2(int * ptr)
Применяйте первую форму, если функции необходимо передать значение для какого-то вычисления или действия. Используйте вторую форму, если функция должна изменять значения переменных из вызывающей функции. Все это вы уже делали с функцией scanf(). Когда необходимо прочитать значение для переменной (например, num), вы применяете вызов scanf ("%d", &num). Функция читает значение и затем использует адрес для сохранения значения.
Указатели дают возможность обойти тот факт, что переменные внутри interchange() являются локальными. Они позволяют этой функции изменять то, что хранится в main().
Пользователи, знакомые с языками Pascal и Modula-2, могут заметить, что первая форма аналогична параметру-значению, а вторая форма подобна (но не идентична) параметру-переменной в Pascal. Пользователи C++ узнают переменные указатели и заинтересуются, не имеет ли С подобно языку C++ также и ссылочные переменные. Ответ на этот вопрос отрицателен. Пользователям, работающим с BASIC, все это может показаться несколько нарушающим общий порядок. Если материал данного раздела показался непонятным, будьте уверены, что после небольшой практики применение указателей станет простым, обычным и удобным делом (рис. 9.6).
Рис. 9.6. Имена, адреса и значения в системе байтовой адресации, такой как 1ВМ РС
Переменные: имена, адреса и значения
Предыдущее обсуждение указателей было тесно связано с взаимоотношениями между именами, адресами и значениями переменных. Давайте продолжим обсуждение этих аспектов. При написании программы можно полагать, что переменная имеет два атрибута: имя и значение. (Существуют также и другие атрибуты, в числе которых тип, но это уже другая тема.) После того, как программа скомпилирована и загружена, компьютер также считает, что та же переменная располагает двумя атрибутами: адресом и значением. Адрес является компьютерной версией имени.
Во многих языках адресами занимается компьютер скрыто от программиста. Однако в языке С к адресу можно получить доступ посредством операции &. Например, &barn — это адрес переменной barn.
362 Глава 9
Значение можно получить из имени, для чего нужно просто указать имя. Например, printf ("%d\n", barn) выводит значение переменной barn.
Значение переменной можно также получить из адреса, воспользовавшись операцией *. Например, в операторе pbarn = &barn; конструкция *pbarn — это значение, хранящееся по адресу &barn.
Короче говоря, обычная переменная делает значение главной величиной, а адрес — производной величиной, доступной через операцию &. Переменная типа указателя делает адрес главной величиной, а значение — производной величиной, доступной посредством операции *.
Хотя ради любопытства вы можете выводить адреса, основное назначение операция & состоит не в этом. Гораздо важнее то, что с помощью операций &, * и указателей становится возможным символическое манипулирование адресами и их содержимым, как было продемонстрировано в программе swap3.c (листинг 9.15).
Сводка: функции Форма
Типичное определение функции в стандарте ANSI С имеет следующую форму:
возвращаемый_тип имя (список объявлений параметров) тело функции
Список объявлений параметров — это список объявлений переменных, разделенных запятыми. Переменные, отличные от параметров функции, объявляются внутри тела, ограниченного фигурными скобками.
Пример
Обмен значениями
Аргументы используются для передачи значений из вызывающей функции в вызванную. Если переменные а и b имеют значения 5 и 2, то вызов
с = diff (а, b);
передает переменным х и у величины 5 и 2. Значения 5 и 2 называются фактическими аргументами, а переменные х и у в функции dif f() — формальными параметрами. Ключевое слово return передает одно значение из функции в вызывающую функцию. В приведенном примере с получает значение переменной z, которое равно 3. Обычно функция не воздействует на переменные в вызывающей функции. Чтобы напрямую влиять на переменные в вызывающей функции, применяйте указатели в качестве аргументов. Это может понадобиться, если в вызывающую функцию нужно возвратить больше одного значения.
Возвращаемый тип функции
Возвращаемый тип функции указывает тип значения, возвращаемого функцией. Если возвращаемое значение имеет тип, отличающийся от объявленного возвращаемого типа, значение приводится к объявленному типу.
Сигнатура функции
Возвращаемый тип функции вместе со списком параметров функции образуют сигнатуру функции. Таким образом, сигнатура указывает типы значений, которые поступают в функцию, и тип значения, передаваемого из нее.
Функции 363
Пример
Ключевые понятия
Чтобы успешно и эффективно программировать на С, необходимо понимать, как работают функции. Полезно и даже важно организовывать крупные программы в виде совокупности функций. Если придерживаться практики решения в одной функции только одной задачи, программу легче будет понять и отладить. Разберитесь в том, как функции обмениваются информацией друг с другом, т.е. убедитесь, что вы понимаете, как работают аргументы и возвращаемые значения функций. Кроме того, помните о том, что параметры и другие локальные переменные являются закрытыми для функции. Таким образом, объявление двух переменных с одним и тем же именем в разных функциях приводит к созданию двух разных переменных. Вдобавок одна функция не имеет прямого доступа к переменным, объявленным в другой функции. Такой ограниченный доступ помогает обеспечить целостность данных. Тем не менее, если нужно, чтобы одна функция имела доступ к данным в другой функции, можно использовать аргументы типа указателей.
Читать дальшеИнтервал:
Закладка: