Опубликован: 23.10.2009 | Уровень: для всех | Доступ: свободно
Лекция 7:

Другие типы данных

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >
Аннотация: В данной лекции рассматриваются пользовательские типы данных, такие как структуры, перечисления и объединения, а также "специальные" типы данных, как массивы различных типов данных, указатели и типы - "списки".
Ключевые слова: Паскаль, Си, символьные типы, автор, класс, string, Java, CSTRING, MFC, microsoft visual studio, массив, char, SUN, visual, Basic, script, доступ, адрес, индекс массива, синтаксис объявления, перегрузка операций, динамические массивы, тип char*, разыменование, адрес переменной, передача параметров, фактический параметр, голова списка, последний элемент списка, императивный, алгоритм, реализация языка, парадигма программирования, Lisp, Prolog, ZIP, объектно-ориентированное программирование, пользователь, пользовательский тип данных, тип данных, python, JScript, ENUM, оператор DEFINE, именованная константа, создание массива, null pointer, хвост списка, список, variant, unsigned, PUC, IsEmpty, операция конкатенации, чувствительность к регистру, comparator, MID, OEM, NPOS, CP/M, PAT, pos, EXT, шаблон регулярного выражения, пробельный символ, prepend, входящий поток, конец файла, reserved, resizing, инкремент, strip, substring, COW, лексикографический порядок, lexicographic order, Entry, equalizer, IndexOf, LastIndexOf, trim, ASC, код символа, chr, vbscript, lens, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, SIM, CNT, MSCS, w-buffer, argument, метасимволы, строковый элемент, таблица символов, обратная функция, HEX, reversibility, списки значений, управляющий символ, study, splice, список удалений, pop

7.1. Структуры, объединения и перечисления

Одним из преимуществ "новых" языков программирования (таких как "Паскаль", "Си") является появление "пользовательских" типов данных. В языке Си к таким данным относят структуры, объединения и перечисления. Рассмотрим их поподробнее.

Структура

Структура представляет собой несколько типов данных, расположенных вместе, в соседних ячейках памяти. Структура имеет собственное имя как тип данных, длина ее элемента (в памяти компьютера) вычисляется с помощью функции sizeof (в C и C++). Пример структуры следующий:

[Пример 01]

/* Инициализируем константу */

const unsigned short MAXSTRINGLENGTH = 256;

/* Описание структуры stringz */

struct stringz
{
	char string[MAXSTRINGLENGTH];
	short nLength;
}

Здесь определена структура с именем stringz, содержащая в себе массив string длиной MAXSTRINGLENGTH (в нашем случае - это 256 символов), и целым числом длиной 2 байта nLength, в котором может, например, храниться реальная длина строки.

Объединение

Объединение похоже на структуру, но в ней данные хранятся не вместе друг с другом, а вместо друг друга. Например, в следующем объединении с тегом data:

[Пример 02]

/* Объявление константы

const unsigned short STRDATALENGTH = 32:

/* Объявление объединения

union data{
	long intdata;
	double doubledata;
	char strdata[STRDATALENGTH];
}

Может храниться либо длинное целое, либо данные с плавающей точкой, либо массив-строка символов длиной 32 байта, причем все - в одних и тех же ячейках памяти. Функция sizeof, примененная к объединению, выдает значение самого длинного типа данных в объединении.

Обращение к элементам структуры и объединения осуществляется либо через знак "." (для переменной), либо знаком "->" (для указателей). Например:

[Пример 03]

/* Инициализируем константу */

const unsigned short MAXSTRINGLENGTH = 256;

/* Объявление переменных */

struct stringz aString, *theString;
union data aData, *theData;

/* Присвоение значений переменным */

aString.nLength = 5;
memset(theString -> string, '\0', MAXSTRINGLENGTH);

aData.intdata = 1;
theData -> doubledata = 7.0;

Перечисления

Перечисления иногда называют именованными типами данных. Их объявление на языке Си следующее:

enum <тег> {<константа 0>, <константа 1>, ... <константа n>};
Листинг 7.1.

Например:

[Пример 04]

/* определяет булевский тип данных */

enum boolean {FALSE, TRUE}

Переменные типа "перечисление" представляют собой целые переменные без знака, способные принимать значения только из списка: <константа 0> ... <константа n>, причем первой константе соответствует значение "0".

Переменную перечисления в Си можно привести к целому типу. Обратное действие вызывает неопределенность.

Если Ваш язык не поддерживает перечисления, можно определить целые константы, соответствующие перечислению, и определить целую переменную, которая будет работать только с этими константами. Но это уже должен отслеживать программист, то есть Вы.

Замечание. Некоторые языки не поддерживают структуры. Тогда их можно эмулировать следующим образом:

[Пример 05]

stringZ$ = "Привет!"
stringZ% = 7

В этом примере вместо структуры stringz в языке Quick Basic используются переменные stringZ$ (для хранения символьных данных) и stringZ% для хранения целого числа.

7.2. Составные специальные типы

К составным специальным символьным типам данных автор относит такие типы данных, как класс "string" из библиотеки ClassLib в Borland C/C++, класс "String" стандартной библиотеки языка Java, класс "CString" в библиотеке MFC из пакета Microsoft Visual Studio и т.д. Эти классы частично заменяют такой примитивный символьный тип данных, как массив скаляров char[]. В стандартах на языки C++ и Sun Java 2 наличие таких предопределенных классов является обязательным. В таблице [[C_Tables.xls]07.I.] представлены стандартные методы классов "string" в Borland C/C++, "String" в Sun Java 2, "CString" в Microsoft MFC 2.0 и функции работы с символьными данными в Visual Basic Script.

Замечание: классы "String" в Sun Java 2 и "CString" в MFC 2.0 представляют символы только в кодировке Unicode.

В примерах [06 - 08] дается реализация алгоритмов Примера 01 "Примитивные символьные данные" с помощью классов "CString", "String" и "string" соответственно.

Замечание: к примеру 06. Несмотря на то, что класс "CString" содержит в себе данные в кодировке Unicode, текст для них пишется в 8-ми битной кодировке. Поэтому для перевода текста в кодировку Unicode используется функция: _T(...). В компиляторе Java 2 нет специальной функции для перевода 8-ми битных кодировок в Unicode.

[Пример 06]

// Определение переменной: <имярек>.
CString strImyaRek("Света");
// Определение переменной-результата.
Cstring strResult();
// Символьные вычисления.
strResult = _T("Привет ") + strImyaRek + _T("! С добрым утром.");

[Пример 07]

// Определение переменной: <имярек>.
string strImyaRek("Света");
// Определение переменной-результата.
string strResult();
// Символьные вычисления.
strResult.append("Привет ");
strResult += strImyaRek;
strResult.append("! С добрым утром.");

[Пример 08]

// Определение переменной: <имярек>.
String strImyaRek("Света");
// Определение временных переменных
strPrivet("Привет ");
strEnd("! С добрым утром.");
// Определение переменной-результата.
Cstring strResult();
// Символьные вычисления.
strResult = strPrivet + strImyaRek + strEnd;

Подробнее о символьных типах данных смотри следующую литературу:

  • примитивные символьные типы языка Си [31];
  • пример класса String, определенного в C++ [51];
  • диск с учебниками по программированию;
  • класс String в Java 2 [74];
  • класс CString в MFC 2.0 [Он-лайн руководство по Microsoft Visual C/C++];
  • класс string в ClassLib [Он-лайн руководство по Borland C/C++ 5.01];
  • описание языка Perl [59].

Замечания, касающиеся "взлома" программ

Реализацию собственных символьных классов следует производить с осторожностью. Если класс закрыт от изменений, но при этом он возвращает свои защищенные значения, то хакер может получить ссылку на этот объект, и, изменяя содержимое этой ссылки, фактически он меняет содержимое этого защищенного элемента класса. Более подробно об этой проблеме смотри примеры в книге [74].

Также к составным специальным символьным типам относят все переменные Perl. Подробнее о типах языках Perl см. "Переменные Perl" .

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >