Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Использование структур в функцияхСодержание книги
Поиск на нашем сайте
Как и для обычных переменных, C++ поддерживаeт как вызов функции с передачей копии всей структурной переменной или только отдельных ее полей (Call-By-Value), так и с передачей указателя на всю структурную переменную или только на отдельные поля структурной переменной (Call-By-Reference). Функция может возвращать как структурную переменную, так и указатель на нее. Вызов функции с передачей всей структурной переменной связан с дополнительными потерями времени на запись ее копии в стек. Зато при этом все манипуляции с копией не влияют на исходную переменную. По той же причине возврат функцией целой структурной переменной требует затрат на размещение в стеке возвращаемого значения. Единственно возможные операции над структурами – это их копирование, присваивание, взятие адреса с помощью & и осуществление доступа к ее членам. Передача структур функциям в качестве аргументов и возврат их от функций в виде результата также относятся к операциям копирования и присваивания. Структуры нельзя сравнивать. Инициализировать структуру можно списком константных значений ее членов; автоматическую структуру можно инициализировать также присваиванием. Чтобы лучше познакомиться со структурами, напишем несколько функций, санипулирующих точками и прямоугольниками. Возникает вопрос: а как передавать функциям названные объекты? Существует по крайней мере три подхода: передавать компоненты по отдельности, передавать свю структуру целиком и передавать указатель на структуру. Каждый подход имеет свои плюсы и минусы. Первая функция, makepoint, получает два целых значения и возвращает структуру point. // makepoint: формирует точку по компонентам х и у struct point makepoint(int x, int y) { struct point temp; temp.x = x; temp.y = y; return temp; } Заметим: никакой путаницы из-за того, что имя аргумента совпадает с именем члена структуры не возникает; более того, одно и то же имя подчеркивает родство обозначаемых им объектов. Теперь с помощью makepoint можно выполнять динамическую инициализацию любой структуры или формировать структурные аргументы для той или иной функции: struct rect screen; struct point middle; struct point makepoint(int, int); screen.pt1 = makepoint(0, 0); screen.pt2 = makepoint(XMAX, YMAX); middle = makepoint((screen.pt1.x+screen.pt2.x)/2, (screen.pt1.y+screen.pt2.y)/2); Нам может понадобиться ряд функций, реализующих различные операции над точками. В качестве примера рассмотрим следующую функцию: // addpoint: сложение двух точек struct point addpoint(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return p1; } Здесь оба аргумента и возвращаемое значение – структуры. Мы увеличиваем компоненты прямо в р1 и не используем для этого временной переменной, чтобы подчеркнуть, что структурные параметры передаются по значению так же, как и любые другие. В качестве другого примера приведем функцию ptinrect, которая проверяет: находится ли точка внутри прямоугольника, относительно которого мы принимаем соглашение, что в него входят его левая и нижняя стороны, но не входят верхняя и правая. // printrect: возвращает 1, если р в r, и 0 в прот. случае int ptinrect(struct point p, struct rect r) { return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y; } Здесь предполагается, что прямоугольник представлен в стандартном виде, т.е. координаты точки pt1 меньше соответствующих координат точки pt2. Следующая функция гарантирует получение прямоугольника в каноническом виде. #define min(a, b) ((a)<(b)?(a):(b)) #define max(a, b) ((a)>(b)?(a):(b)) // canonrect: канонизация координат прямоугольника struct rect canonrect(struct rect r) { struct rect temp; temp.pt1.x = min(r.pt1.x, r.pt2.x); temp.pt1.y = min(r.pt1.y, r.pt2.y); temp.pt2.x = max(r.pt1.x, r.pt2.x); temp.pt2.y = max(r.pt1.y, r.pt2.y); return temp; } Если функции передается большая структура, то, чем копировать ее целиком, эффективнее передать указатель на нее. Указатели на структуры ничем не отличаются от указателей на обычные переменные. Декларация struct point *pp; сообщает, что рр есть указатель на структуру типа struct point. Если рр ссылается на структуру point, то *рр есть сама структура, а (*рр).х и (*рр).у – ее члены. Используя указатель рр, мы могли бы написать sctruct point origin, *pp; pp = &origin; printf("origin: (%d, %d)\n", (*pp).x, (*pp).y); Скобки в (*рр).х необходимы, поскольку приоритет оператора. выше, чем приоритет *. Выражение *рр.х будет проинтерпретировано как *(рр.х), что неверно, поскольку рр.х не является указателем.
|
||||
|
Последнее изменение этой страницы: 2017-02-05; просмотров: 406; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.41 (0.006 с.) |