Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Программирование » Язык программирования Си. Издание 3-е, исправленное - Брайан Керниган

Язык программирования Си. Издание 3-е, исправленное - Брайан Керниган

Читать онлайн Язык программирования Си. Издание 3-е, исправленное - Брайан Керниган
1 ... 31 32 33 34 35 36 37 38 39 ... 81
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

char datatype[MAXTOKEN]; /* тип = char, int и т.д. */

char out[1000]; /* выдаваемый текст */

main() /* преобразование объявления в словесное описание */

{

 while (gettoken() != EOF) {/* 1-я лексема в строке */

  strcpy(datatype, token); /* это тип данных */

  out[0] = '';

  dcl(); /* разбор остальной части строки */

  if (tokentype != 'n')

   printf("синтаксическая ошибкаn");

  printf("%s: %s %sn", name, out, datatype);

 }

 return 0;

}

Функция gettoken пропускает пробелы и табуляции и затем получает следующую лексему из ввода: "лексема" (token) - это имя, или пара круглых скобок, или пара квадратных скобок (быть может, с помещенным в них числом), или любой другой единичный символ.

int gettoken(void) /* возвращает следующую лексему */

{

 int с, getch(void);

 void ungetch(int);

 char *p = token;

 while ((c = getch()) == ' ' || с == 't')

  ;

 if (c == '(') {

  if ((c = getch()) == ')' {

   strcpy(token, "()");

   return tokentype = PARENS;

  } else {

   ungetch(c);

   return tokentype = '(';

  }

 } else if (c == '[') {

  for (*p++ = c; (*p++ = getch()) != ']';)

   ;

  *p = '';

  return tokentype = BRACKETS;

 } else if (isalpha(c)) {

  for (*p++ = c; isalnum(c = getch());)

  *p++ = c;

  *p = '';

  ungetch(c);

  return tokentype = NAME;

 } else

 return tokentype = c;

}

Функции getch и ungetch были рассмотрены в главе 4.

Обратное преобразование реализуется легче, особенно если не придавать значения тому, что будут генерироваться лишние скобки. Программа undcl превращает фразу вроде "x есть функция, возвращающая указатель на массив указателей на функции, возвращающие char", которую мы будем представлять в виде

х () * [] * () char

в объявление

char (*(*х())[])()

Такой сокращенный входной синтаксис позволяет повторно пользоваться функцией gettoken. Функция undcl использует те же самые внешние переменные, что и dcl.

/* undcl: преобразует словесное описание в объявление */

main()

{

 int type;

 char temp[MAXTOKEN];

 while (gettoken() != EOF) {

  strcpy(out, token);

  while ((type = gettoken()) != 'n')

   if (type == PARENS || type == BRACKETS)

    strcat(out, token);

   else if (type == '*') {

    sprintf(temp, "(*%s)", out);

    strcpy(out, temp);

   } else if (type == NAME) {

    sprintf(temp, "%s %s", token, out);

    strcpy(out, temp);

   } else

    printf("неверный элемент %s в фразеn", token);

  printf("%sn", out);

 }

 return 0;

}

Упражнение 5.18. Видоизмените dcl таким образом, чтобы она обрабатывала ошибки во входной информации.

Упражнение 5.19. Модифицируйте undcl так, чтобы она не генерировала лишних скобок.

Упражнение 5.20. Расширьте возможности dcl, чтобы dcl обрабатывала объявления с типами аргументов функции, квалификаторами вроде const и т. п.

Глава 6. Структуры

Структура - это одна или несколько переменных (возможно, различных типов), которые для удобства работы с ними сгруппированы под одним именем. (В некоторых языках, в частности в Паскале, структуры называются записями.) Структуры помогают в организации сложных данных (особенно в больших программах), поскольку позволяют группу связанных между собой переменных трактовать не как множество отдельных элементов, а как единое целое.

Традиционный пример структуры - строка платежной ведомости. Она содержит такие сведения о служащем, как его полное имя, адрес, номер карточки социального страхования, зарплата и т. д. Некоторые из этих характеристик сами могут быть структурами: например, полное имя состоит из нескольких компонент (фамилии, имени и отчества); аналогично адрес, и даже зарплата. Другой пример (более типичный для Си) - из области графики: точка есть пара координат, прямоугольник есть пара точек и т. д.

Главные изменения, внесенные стандартом ANSI в отношении структур, - это введение для них операции присваивания. Структуры могут копироваться, над ними могут выполняться операции присваивания, их можно передавать функциям в качестве аргументов, а функции могут возвращать их в качестве результатов. В большинстве компиляторов уже давно реализованы эти возможности, но теперь они точно оговорены стандартом. Для автоматических структур и массивов теперь также допускается инициализация.

6.1 Основные сведения о структурах

Сконструируем несколько графических структур. В качестве основного объекта выступает точка с координатами x и y целого типа.

Указанные две компоненты можно поместить в структуру, объявленную, например, следующим образом:

struct point {int x; int y;};

Объявление структуры начинается с ключевого слова struct и содержит список объявлений, заключенный в фигурные скобки. За словом struct может следовать имя, называемое тегом структуры (от английского слова tag - ярлык, этикетка. - Примеч. пер.), point в нашем случае. Тег дает название структуре данного вида и далее может служить кратким обозначением той части объявления, которая заключена в фигурные скобки.

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

Объявление структуры определяет тип. За правой фигурной скобкой, закрывающей список элементов, могут следовать переменные точно так же, как они могут быть указаны после названия любого базового типа. Таким образом, выражение

struct {…} x, y, z;

с точки зрения синтаксиса аналогично выражению

int х, у, 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

обращается к координате x точки pt1 из screen.

6.2 Структуры и функции

Единственно возможные операции над структурами - это их копирование, присваивание, взятие адреса с помощью & и осуществление доступа к ее элементам. Копирование и присваивание также включают в себя передачу функциям аргументов и возврат ими значений. Структуры нельзя сравнивать. Инициализировать структуру можно списком константных значений ее элементов; автоматическую структуру также можно инициализировать присваиванием.

1 ... 31 32 33 34 35 36 37 38 39 ... 81
Перейти на страницу:
Открыть боковую панель
Комментарии
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее
Мприна
Мприна 08.12.2024 - 01:05
Эх, а где же продолжение?
Анна
Анна 07.12.2024 - 00:27
Какая прелестная история! Кратко, ярко, захватывающе.
Любава
Любава 25.11.2024 - 01:44
Редко встретишь большое количество эротических сцен в одной истории. Здесь достаточно 🔥 Прочла с огромным удовольствием 😈