Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Важно отметить, что him — указатель, но him->income — это член структуры, на которую он указывает. Это значит, что в данном случае him->income представляет собой переменную типа float.
Второй метод для указания значения члена структуры соответствует следующей последовательности утверждений: если him == &fellow [0], то *him == fellow [0], поскольку операции & и * являются обратными. Следовательно, после подстановки мы получаем такое выражение:
fellow[0].income == (*him).income
580 глава 14
Круглые скобки здесь обязательны, т.к. операция . имеет более высокий приоритет, чем *. Подводя итоги, если him — это указатель на структуру типа guy по имени barney, то следующие выражения эквивалентны:
barney.income == (*him).income == him->income //предполагая, что him == &barney А теперь давайте посмотрим на взаимодействие между структурами и функциями.
Сообщение функциям о структурах
Вспомните, что аргументы функции передают ей значения. Каждое значение является числом — возможно, int, float, ASCII-кодом символа или адресом.
Структура сложнее одиночного значения, поэтому не должно вызывать удивление то, что ранние реализации С не позволяют применять структуру в качестве аргумента для функции. В более новых реализациях это ограничение было снято, и ANSI С позволяет использовать структуры в аргументах функций. Таким образом, современные реализации С предлагают возможность выбора между передачей в качестве аргумен- тов самих структур и указателей на эти структуры, либо, если вас интересует только часть структуры — передачей в аргументах членов структуры. Мы исследуем все три метода, начав с передачи членов структуры как аргументов.
Передача членов структуры
До тех пор, пока член структуры имеет тип данных с единственным значением (т.е. int или один из его производных типов, char, float, double либо указатель), его можно передавать в качестве аргумента функции, которая принимает этот конкретный тип. Простейшая программа финансового анализа из листинга 14.5, которая складывает сумму на обычном банковском счете клиента и сумму на его сберегательном счете, иллюстрирует это утверждение.
Листинг 14.5. Программа funds1.c
Структуры и другие формы данных 581
Вот результаты пробного запуска:
Общая сумма на счетах у Стэна составляет $12576.21.
Итак, программа работает. Обратите внимание, что функция sum() не знает, да и не заботится о том, являются ли фактические аргументы членами структуры; она только требует, чтобы они имели тип double.
Конечно, если вы хотите, чтобы вызываемая функция оказывала воздействие на значение члена в вызывающей функции, то можете передавать адрес этого члена:
modify(sstan.bankfund);
Это могла бы быть функция, изменяющая сумму на банковском счету Стэна. Следующий подход к сообщению функции о структуре предусматривает уведомление о том, что функция имеет дело со струк турой.
Использование адреса структуры
Мы будем решать ту же задачу, что и ранее, но на этот раз в качестве аргумента применим адрес структуры. Поскольку функция будет работать со структурой funds, она также должна использовать объявление funds. Код программы приведен в листинге 14.6.
Листинг 14.6. Программа funds2.c
Запуск программы дает тот же самый результат:
Общая сумма на счетах у Стэна составляет $12576.21.
Функция sum() принимает указатель (money) на структуру funds в своем единственном аргументе. Передача адреса &stan функции приводит к тому, что теперь указатель money указывает на структуру stan. Затем с помощью операции -> мы получаем
582 Глава 14 значения stan .bankfund и stan. savefund. Поскольку функция не изменяет значение, на которое ссылается указатель, money объявляется как указатель на const.
Эта функция также имеет доступ к членам, представляющим названия учреждений, хотя и не пользуется ими. Обратите внимание, что для получения адреса структуры должна применяться операция &. В отличие от имени массива имя структуры не является синонимом ее адреса.
Передача структуры в качестве аргумента
Для компиляторов, которые разрешают передавать структуры в качестве аргументов, последний пример можно переписать так, как показано в листинге 14.7.
Листинг 14.7. Программа funds3.c
И снова вывод оказывается прежним:
Сумма на счету у Стэна составляет $12576.21.
Мы заменили указатель на struct funds по имени money переменной типа struct funds с именем moolah. При вызове sum() создается автоматическая переменная moolah, согласованная с шаблоном funds. Затем члены этой структуры инициализируются копиями значений соответствующих членов структуры stan. По этой причине вычисления производятся с участием копии исходной структуры, тогда как в предыдущей программе (в которой использовался указатель) задействована сама исходная структура. Так как moolah является структурой, в программе применяется moolah.bankfund, а не moolah->bankfund. С другой стороны, в листинге 14.6 используется money->bankfund, потому что money — указатель, а не структура.
Структуры и другие формы данных 583
Дополнительные возможности структур
Современный язык С позволяет присваивать одну структуру другой — то, чего нельзя делать с массивами. То есть, если n data и o_data — струк туры того же типа, то можно записать следующий код:
o_data = n_data; // присваивание одной структуры другой
Это приводит к тому, что каждому члену n data присваивается значение соответствующего члена o data. Это работает, даже если член оказывается массивом. Кроме того, струк туру можно инициализировать другой структурой того же типа:
struct names right_field = {"Джеймс", "Бонд" };
struct names captain = right_field; //инициализация структуры другой структурой
В современном языке С, включая ANSI С, структуры не только можно передавать функции в качестве аргументов, но также и возвращать их из функции. Применение структур в аргументах функции позволяет передавать ей информацию о структуре. Использование функций для возвращения структур дает возможность передавать информацию о структуре из вызываемой функции в вызывающую. Указатели на структуры также допускают двусторонний обмен данными, так что вы часто будете применять один из этих подходов при решении разнообразных задач. Рассмотрим еще один набор примеров, иллюстрирующих данные два подхода.
Чтобы сравнить эти два подхода, мы напишем простую программу, которая обрабатывает структуры с использованием указателей, и затем переделаем ее лак, чтобы в ней выполнялась передача и возвращение структур. Сама программа запрашивает имя и фамилию и сообщает общее количество букв в них. Этот проект едва ли требует структур, но он предлагает простую инфраструктуру, которая позволяет увидеть, как они работают. В листинге 14.8 представлена версия программы с указателями.
Читать дальшеИнтервал:
Закладка: