Главная » Просмотр файлов » Керниган и Ритчи - Язык программирования Си

Керниган и Ритчи - Язык программирования Си (793773), страница 32

Файл №793773 Керниган и Ритчи - Язык программирования Си (Керниган и Ритчи - Язык программирования Си) 32 страницаКерниган и Ритчи - Язык программирования Си (793773) страница 322019-04-24СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 32)

Имена элементов и тегов безкаких-либо коллизий могут совпадать с именами обычных переменных (т. е. не элементов), так как они всегдаразличимы по контексту. Более того, одни и те же имена элементов могут встречаться в разных структурах,хотя, если следовать хорошему стилю программирования, лучше одинаковые имена давать только близкимпо смыслу объектам.9От английского слова tag — ярлык, этикетка. — Примеч. пер.В некоторых изданиях (в том числе во 2-м издании на русском языке этой книги) structure members переводится какчлены структуры.

— Примеч. ред.10Объявление структуры определяет тип. За правой фигурной скобкой, закрывающей список элементов, могутследовать переменные точно так же, как они могут быть указаны после названия любого базового типа.Таким образом, выражениеstruct {…} х, у, z;с точки зрения синтаксиса аналогично выражениюint x, у, z;в том смысле, что и то и другое объявляет x, y и z переменными указанного типа; и то и другое приведет квыделению памяти соответствующего размера.Объявление структуры, не содержащей списка переменных, не резервирует памяти; оно просто описываетшаблон, или образец структуры.

Однако если структура имеет тег, то этим тегом далее можно пользоватьсяпри определении структурных объектов. Например, с помощью заданного выше описания структуры pointстрокаstruct point pt;определяет структурную переменную pt типа struct point. Структурную переменную при ееопределении можно инициализировать, формируя список инициализаторов ее элементов в виде константныхвыражений:struct point maxpt = { 320, 200 };Инициализировать автоматические структуры можно также присваиванием или обращением к функции,возвращающей структуру соответствующего типа.Доступ к отдельному элементу структуры осуществляется посредством конструкции вида:имя-структуры.элементОператор доступа к элементу структуры .

(точка) соединяет имя структуры и имя элемента. Чтобы напечатать,например, координаты точки pt, годится следующее обращение к printf:printf("%d,%d", pt.x, pt.y);Другой пример: чтобы вычислить расстояние от начала координат (0,0) до pt, можно написатьdouble dist, sqrt(double);dist = sqrt((double)pt.x * pt.x + (double)pt.y * pt.y);Структуры могут быть вложены друг в друга.

Одно из возможных представлений прямоугольника — это параточек на углах одной из его диагоналей:struct rect {struct point pt1;struct point pt2;};Структура rect содержит две структуры point. Если мы объявим screen какstruct rect screen;тоscreen.pt1.xобращается к координате х точки pt1 из screen.6.2. Структуры и функцииЕдинственно возможные операции над структурами — это их копирование, присваивание, взятие адреса спомощью & и осуществление доступа к ее элементам. Копирование и присваивание также включают в себяпередачу функциям аргументов и возврат ими значений.

Структуры нельзя сравнивать. Инициализироватьструктуру можно списком константных значений ее элементов; автоматическую структуру также можноинициализировать присваиванием.Чтобы лучше познакомиться со структурами, напишем несколько функций, манипулирующих точками ипрямоугольниками. Возникает вопрос: а как передавать функциям названные объекты? Существует покрайней мере три подхода: передавать компоненты по отдельности, передавать всю структуру целиком ипередавать указатель на структуру.

Каждый подход имеет свои плюсы и минусы.Первая функция, makepoint, получает два целых значения и возвращает структуру point./* makepoint: формирует точку по компонентам х и y */struct point makepoint(int x, int y){struct point temp;temp.x = x;temp.у = у;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, которая проверяет: находится ли точка внутрипрямоугольника, относительно которого мы принимаем соглашение, что в него входят его левая и нижняястороны, но не входят верхняя и правая./* ptinrect: возвращает 1, если р в г, и 0 в противном случае */int ptinrect(struct point p, struct rect r){return p.x >= r.ptl.x && p.x < r.pt2.x&& p.y >= r.ptl.y && p.y < r.pt2.y;}Здесь предполагается, что прямоугольник представлен в стандартном виде, т.

е. координаты точки pt1меньше соответствующих координат точки pt2. Следующая функция гарантирует получение прямоугольникав каноническом виде.#define min(a, b) ((a) < (b) ? (а) : (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.ptl.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,то *рр — это сама структура, а (*рр).х и (*рр).y — ее элементы. Используя указатель рр, мы могли бынаписатьstruct point origin, *pp;рр = &origin;printf ("origin: (%d,%d)\n", (*pp).x, (*pp).y);Скобки в (*рр).х необходимы, поскольку приоритет оператора . выше, чем приоритет *. Выражение*рр.х будет проинтерпретировано как *(рр.х), что неверно, поскольку рр.х не является указателем.Указатели на структуры используются весьма часто, поэтому для доступа к ее элементам была придумана ещеодна, более короткая форма записи.

Если р — указатель на структуру, тор -> элемент-структурыесть ее отдельный элемент. (Оператор -> состоит из знака -, за которым сразу следует знак >.) Поэтомуprintf можно переписать в видеprintf("origin: (%d,%d)\n", pp->x, pp->y);Операторы . и -> выполняются слева направо. Таким образом, при наличии объявленияstruct rect r, *rp = &r;следующие четыре выражения будут эквивалентны:r.pt1.хrp->pt1.x(r.pt1).x(rp->pt1).xОператоры доступа к элементам структуры . и -> вместе с операторами вызова функции () и индексациимассива [] занимают самое высокое положение в иерархии приоритетов и выполняются раньше любыхдругих операторов. Например, если задано объявлениеstruct {int len;char *str;} *p;то++p->lenувеличит на 1 значение элемента структуры len, а не указатель р, поскольку в этом выражении как бынеявно присутствуют скобки: ++(р->len). Чтобы изменить порядок выполнения операций, нужны явныескобки. Так, в (++р)->len, прежде чем взять значение len, программа прирастит указатель р.

В (р++)>len указатель р увеличится после того, как будет взято значение len (в последнем случае скобки необязательны).По тем же правилам *p->str обозначает содержимое объекта, на который указывает str; *p->str++прирастит указатель str после получения значения объекта, на который он указывал (как и в выражении*s++); (*p->str)++ увеличит значение объекта, на который указывает str; *p++->str увеличит р послеполучения того, на что указывает str.6.3. Массивы структурРассмотрим программу, определяющую число вхождений каждого ключевого слова в текст Си-программы.Нам нужно уметь хранить ключевые слова в виде массива строк и счетчики ключевых слов в виде массивацелых.

Один из возможных вариантов — это иметь два параллельных массива:char *keyword[NKEYS];int keycount[NKEYS];Однако именно тот факт, что они параллельны, подсказывает нам другую организацию хранения — черезмассив структур. Каждое ключевое слово можно описать парой характеристикchar *word;int count;Такие пары составляют массив. Объявлениеstruct key {char *word;int count;} keytab[NKEYS];объявляет структуру типа key и определяет массив keytab, каждый элемент которого является структуройэтого типа и которому где-то будет выделена память.

Это же можно записать и по-другому:struct key {char *word;int count;};struct key keytab[NKEYS];Так как keytab содержит постоянный набор имен, его легче всего сделать внешним массивом иинициализировать один раз в момент определения. Инициализация структур аналогична ранеедемонстрировавшимся инициализациям — за определением следует список инициализаторов, заключенныйв фигурные скобки:struct key {char *word;int count;} keytab[] = {"auto", 0,"break", 0,"case", 0,"char", 0,"const", 0,"continue", 0,"default", 0,..."unsigned", 0,"void", 0,"volatile", 0,"while", 0};Инициализаторы задаются парами, чтобы соответствовать конфигурации структуры. Строго говоря, паруинициализаторов для каждой отдельной структуры следовало бы заключить в фигурные скобки, как,например, в{ "auto", 0 },{ "break", 0 },{ "case", 0 },Однако когда инициализаторы — простые константы или строки символов и все они имеются в наличии, вовнутренних скобках нет необходимости.

Характеристики

Тип файла
PDF-файл
Размер
2,25 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7041
Авторов
на СтудИзбе
259
Средний доход
с одного платного файла
Обучение Подробнее