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

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

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

7.4. Списки

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

  1. У списков нет индекса, а значит обращение к его любому значению напрямую невозможно:
  2. Получить доступ можно только к его первому элементу (голове списка), а ко всем последующим - только через метод next() ;
  3. Элементы (узлы) списка могут размещаться в любых ячейках памяти, а не только подряд. Почему - см. следующий пункт;
  4. Тип "список" может быть реализован, например, следующим образом:

    [Пример 16]

    struct list_node{
    	union data datum_node;
    	struct list_node *next_node;
    }
    где data - объединение из примера 02. Этот элемент, в принципе, может иметь любой тип: как примитивный, так и определенный тип-класс. Второй элемент, имеющий тип: struct list_node * (указатель на собственный тип), является обязательным. В этом указателе находится либо адрес следующего элемента списка-узла ("node" по-английски - "звено, узел"), или нулевой указатель (обозначение - NULL), если это последний элемент списка. Поскольку указатель (адрес звена) может принимать любое значение, то расположение звеньев в памяти может быть любым;
  5. Размер списка, в принципе, может быть любым.

С первого взгляда кажется, что использование списка, по сравнению с массивом, неудобно. Но это неудобство происходит только при работе с "императивными" алгоритмами, для которых существует только одна, основная последовательность в реализации алгоритма. Однако существуют также и "декларативные" алгоритмы, в которых задаются (описываются) только исходные данные, цель задачи, а алгоритм нахождения цели "встроен" в реализации языка и скрыт от программиста. На "декларативных" алгоритмах основана функциональная парадигма программирования (язык LISP) и логическая парадигма программирования (язык PROLOG). В этих языках вполне естественно (из логики построения программы) заменить произвольный доступ к элементам массива на доступ к "голове" (начальному элементу) и "хвосту" (остальной части) списка. Более подробно о языке Turbo Prolog смотри [files/prolog.zip] материалы по языку: "Турбо Prolog".

7.5. Резюме

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

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

Автор особо хотел бы остановить внимание на другом специальном типе данных - списке. Хотя списки практически не встречаются в "процедурных" языках программирования (их реализация имеется только в библиотеке ClassLib Borland C/C++), они очень широко используются при анализе текстов, грамматическом разборе приложениях, и других алгоритмах искусственного интеллекта. Поэтому автор советует изучить этот тип данных самостоятельно.

7.6. Глоссарий

Термин Английский термин Разъяснение
специальный символьный тип данных special symbol data type Символьный тип данных, реализованный в виде классов. К специальным символьным типам данных относят классы: "string" из библиотеки ClassLib Borland C/C++, "CString" из библиотеки MFC Microsoft Visual C/C++, стандартный класс языка Java - "String" и др. Как правило, текст внутри переменных такого типа не меняется!
массив array Представляет собой смежные ячейки памяти, начиная с начального адреса массива, и до последней ячейки памяти массива. Доступ к каждой ячейке памяти массива осуществляется при помощи его индекса.
индекс index Порядковый номер ячейки массива. В Си-подобных языках индекс первой ячейки начинается с 0.
Си подобные языки C based languages Языки программирования, имеющие синтаксис и обозначения, сходные с принятыми обозначениями в языке Си. К Си-подобным языкам автор относит: C++, C#, Java, Perl, Python, C--, JScript и др.
структура structure Представляет собой несколько типов данных, расположенных вместе, в соседних ячейках памяти. Структура как тип данных имеет собственное имя, длина ее элемента вычисляется с помощью функции: sizeof.
объединение union Представляет собой несколько типов данных, расположенных в одной ячейке памяти вместо друг друга. Объединение имеет собственное имя как тип данных.
перечисления enumerate Представляет собой целые переменные без знака, способные принимать значения только именованных констант, причем первой константе присваивается значение 0.
пользовательский тип данных users' data type Тип данных, созданный системным или прикладным программистам для собственных нужд. К пользовательским типам данных на языке Си относят классы, структуры, объединения и перечисления.
именованный тип данных denominate data type Целый тип данных, значения (константы) для которых записаны как имена (идентификаторы). Это позволяет использовать в различных операциях вместо безликого числа некоторого "осмысленного имени", что улучшает "читабельность" программы. На языке Си именованные константы вводятся оператором enum или прагма оператором #define.
константа constant Число или символьная строка, не меняющаяся во время исполнения программ. Именованная константа - переменная с неизменным значением. Константа имеет определенный тип данных.
переменная variable Идентификатор, обозначающий ячейку памяти для хранения данных со значением определенного типа. Этот идентификатор называется именем переменной.
идентификатор identification Любая последовательность латинских букв и цифр, начинающаяся с латинской буквы. Идентификаторы служат именами констант и переменных.
модификатор modification Идентификатор, служащий для уточнения и/или изменения значения по-умолчанию для указателей, типов данных и т.п.
целая константа integer constant Переменная (идентификатор), имеющее постоянное неизменное целое значение. В языке Си эти константы объявляются либо прагма оператором #define, либо оператором const int.
явное указание максимальных индексов strict direction of ultimate index Указание максимального значения индекса массива в процессе его создания или объявления без инициализации. Если массив указан как последовательность типов данных, то это значение изменить нельзя без удаления и повторного создания массива.
неявное указание максимального индекса implicit direction of ultimate index Указание максимального индекса массива при его объявлении с инициализацией. Это значение определяется количеством констант (символов) в строке, которой инициализируется массив. При неявном указании максимального значения индекса его значение изменить уже нельзя!
указатель 1. pointer 1. Целая переменная, хранящая адрес переменной или константы заданного типа. В Си-подобных языках обозначения массива и указателя эквивалентны.
указатель 2. pointer 2. Целая переменная, хранящая в себе адрес другой переменной (или массива) указанного типа. В языке Си указателем является специальный тип - "адресная переменная" того типа данных, на которое указывает указатель. Это делает невозможным (так надо!) применения целочисленных операций над указателями.
NULL-указатель NULL 1. См. пустой (нулевой) указатель. Используется в языке Си.
пустой (нулевой) указатель empty (zero) pointer Указатель, принимающий нулевое целое значение. При попытке обращения к "пустому" указателю генерируется отказ системы ("NULL pointer assigned). Это значение указателя используется в специальных целях.
ссылка link "Разыменованный" указатель, которой в операции присвоения используется как переменная, а в параметрах функции - как адрес этой переменной. Ссылки следует использовать с осторожностью!
список list Структура данных, представляющее собой "значение" и ссылку на следующий элемент списка. Обратиться к элементу списка можно через голову списка и многократному применению методов next.
голова списка head of the list Адрес первого элемента списка.
хвост списка tail of the list Все элементы списка, расположенные после текущего элемента. Хвост списка может быть пустым.
метод next next (method) Ищет адрес следующего элемента списка. Возвращает значение: NULL, если текущий элемент списка - последний.
NULL NULL 2. "Нулевой символ" при адресации памяти. При обращении программы по этому адресу выводится сообщение: "NULL pointer assigned", и программа перестает выполняться.

7.7. Приложение

В таблицах 7.1 - 7.7 Дан список основных функций работы с символьными данными.

Таблица 7.1. Символьные типы данных
Тип данных Префикс/Окончание Разрядность регистров/длина Примечание
Quick Basic
STR <идентификатор>$ Переменная длина (до 255 символов) Для хранения 1 символа в кодировке ASCII. Не защищен от изменений.
VB Script
Variant в зависимости от конкретного значения Переменная длина Используется для хранения всех видов данных.
Java
char с 2 байта Для хранения одного символа в кодировке Unicode
String str Переменная длина Класс для хранения символов в кодировке Unicode. Защищено от изменений!
javascript
variant в зависимости от конкретного значения Переменная длина Используется для хранения всех видов данных.
C/C++
char с 1 байт Для хранения одного символа в кодировке ASCII (со знаком)
unsigned char uc 1 байт Для хранения одного символа в кодировке ASCII (без знака)
char * pc от 2 до 4 байт Указатель на массив (переменной длины)
unsigned char * puc от 2 до 4 байт Указатель на массив (переменной длины)
C/C++ Windows API
BYTE b 1 байт Эквивалентен unsigned char
NPSTR npsz 2 байта Эквивалентен char near *
LPSTR lpch 4 байта Эквивалентен char far *
LPCSTR lpsz 4 байта Эквивалентен const char far *
C++ MFC
CString cstr, str Переменная длина Класс для хранения символов в кодировке Unicode. Защищено от изменений!
C++ Classlib
string str Переменная длина Класс для хранения символов в кодировке ASCII (и Unicode?). Защищено от изменений!
Таблица 7.2. Функции для работы с текстом
Группа функций Функция/Метод Описание Пример
Язык С++. Функции MFC для Microsoft Visual Studio
Конструктор CString Конструктор объекта CString различными способами.
Строка как массив GetLength Возвращает число символов в строке.
IsEmpty Проверяет, является ли строка пустой (т.е. она состоит из 0 символов).
Empty Удаляет из строки все символы.
GetAt Возвращает символ в текущей позиции.
operator [] Функция аналогична функции: GetAt
SetAt Записывает символ в указанную позицию.
operator LPCTSTR Прямой доступ к символам текущей строки в формате языка Си.
Присвоение и конкатенация operator = Назначает новое значение строки объекту.
operator + Операция конкатенации двух строк.
operator += Операция конкатенации второй строки к концу первой.
Сравнение operator == <, etc. Операторы сравнения (чувствительные к регистру).
Compare Сравнение двух строк (чувствительное к регистру).
CompareNoCase Сравнение двух строк (без учета регистра).
Извлечение Mid Выделяет среднюю часть строки (как функция MID$ в Бейсике).
Left Выделяет левую часть строки (как функция LEFT$ в Бейсике).
Right Выделяет правую часть строки (как функция Бейсика RIGHT$).
SpanIncluding Выделяет подстроку, которая содержит только символы из данного множества;
SpanExcluding Выделяет подстроку, которая содержит символы, не входящие в указанное множество.
Другие преобразования MakeUpper Преобразует все символы в строке в верхний регистр.
MakeLower Преобразует все символы в строке в нижний регистр.
MakeReverse Изменяет порядок символов в строке на обратный порядок следования символов.
Format Форматирует строку в соответствии со спецификацией sprintf.
TrimLeft Обрезает "лидирующие", начальные пробелы в строке.
TrimRight Обрезает "хвостовые" пробелы в строке.
FormatMessage Форматирует строку сообщения.
Поиск Find Ищет символ или подстроку внутри текущей строки.
ReverseFind Ищет символ или подстроку внутри текущей строки, начиная с ее конца.
FindOneOf Finds the first matching character from a set.
Архивация/Дамп operator << Помещает строку в выходной поток данных.
operator >> Читает строку из входного потока данных.
Buffer Access Функции манипуляции с буфером
GetBuffer Возвращает указатель на символы из строки.
GetBufferSetLength Возвращает указатель на символы из строки CString, урезанную по указанной длине.
ReleaseBuffer Удаляет буфер для хранения строки данных.
FreeExtra Удаляет все заголовки этого строкового объекта, предварительно размещенного во внешней памяти,
LockBuffer Делает ссылку на строку активной (т.е. к размещенной строке командой GetBuffer, можно обращаться).
UnlockBuffer Делает ссылку на строку не активной, разрешая операционной системе произвольно перемещать буфер в памяти.
Специфичные для Windows AllocSysString Размещает BSTR из данных CString
SetSysString Устанавливает текущий BSTR объект данными из CString объекта.
LoadString Загрузить существующую строку из ресурсов Windows.
AnsiToOem Преобразует строку символов из формата ANSI в OEM в соответствии с заданными национальными настройками.
OemToAnsi Преобразует строку символов из формата OEM в формат ANSI в соответствии с национальными настройками операционной системы.
Таблица 7.3. Функции для работы с текстом
Функция/Метод Синтаксис Описание Пример
Язык С++. Функции ClassLib Borland C/C++
Header File cstring.h
Конструкторы: string::string
Данные - члены класса: StripType
Публичные методы:
ansi_to_oem void ansi_to_oem(); перевод текста строки из кодировки ANSI в кодировку OEM (согласно установленному национальному стандарту)
append string _FAR & append( const string _FAR &s );

string _FAR & append( const string _FAR &s, size_t start, size_t n = NPOS );

string _FAR & append( const char _FAR *cp, size_t start, size_t n = NPOS );
добавляет заданную строку s к текущей строке.
assign string _FAR & assign( const string _FAR &s );

string _FAR & assign( const string _FAR &s, size_t start, size_t n = NPOS );

compare int compare(const string _FAR &s) const throw();

int compare(const string _FAR &s, size_t orig, size_t n = NPOS ) const throw();

строка s сравнивается с исходной строкой в лексикографическом порядке, и выдается значение: меньше нуля, если исходная строка меньше s, 0, когда строки равны и больше нуля, когда исходная строка больше s.
contains int contains(const char _FAR * pat) const;

int contains(const string _FAR & s) const;

проверяется вхождение строки s (или pat) в текущую строку. Возвращает 1 если строка входит в текущую строку, и 0, если не входит.
copy size_t copy( char _FAR *cb, size_t n = NPOS );

size_t copy( char _FAR *cb, size_t n, size_t pos );

string copy() const throw( xalloc ).;
функция копирует n символов в строку cb из текущей строки. Возвращает точное число скопированных символов. В третьей форме синтаксиса функция возвращает собственную копию;
c_str const char _FAR *c_str() const;
find size_t find( const string _FAR &s );

size_t find( const string _FAR &s, size_t pos );

Возвращает позицию первого вхождения подстроки s в текущую строку.
find size_t find( const TRegexp _FAR &pat, size_t i = 0 );

size_t find( const TRegexp _FAR &pat, size_t _FAR *ext, size_t i = 0 ) const;

Возвращает позицию первого вхождения подстроки с шаблоном регулярного выражения pat в текущую строку, начиная с позиции i. Число i сообщает длину строки, совпадшей с шаблоном.
find_first_of size_t find_first_of( const string _FAR &s ) const;

size_t find_first_of( const string _FAR &s, size_t pos ) const;

возвращает первый символ из текущей строки, совпавший с любым символом из строки s.
find_first_not_of size_t find_first_not_of( const string _FAR &s ) const;

size_t find_first_not_of( const string _FAR &s, size_t pos ) const;

find_last_of size_t find_last_of( const string _FAR &s ) const;

size_t find_last_of( const string _FAR &s, size_t pos ) const;

find_last_not_of size_t find_last_not_of( const string _FAR &s ) const;

size_t find_last_not_of( const string _FAR &s, size_t pos ) const;

get_at char get_at( size_t pos ) const throw( outofrange ); возвращает символ в указанной позиции pos.
get_case_sensitiveFlag static int get_case_sensitive_flag(); Возвращает значение 0, если сравнение чувствительно к регистру букв.
get_initial_capacity static unsigned get_initial_capacity();
get_max_waste static unsigned get_max_waste();
get_paranoid_check static int get_paranoid_check();
get_resize_increment
static unsigned get_resize_increment();
get_skipwhitespace_flag static int get_skipwhitespace_flag(); возвращает 1, если при поиске пропускаются пробельные символы.
hash unsigned hash() const; Выдает значение хеш величины типа данных;
initial_capacity static size_t initial_capacity(size_t ic = 63);
insert string _FAR &insert( size_t start, const string _FAR &s );

string _FAR &insert( size_t pos, const string _FAR &s, size_t start, size_t n = NPOS );

Вставляет pos символов из строки s в текущую строку, начиная с позиции start.
is_null int is_null() const; Возвращает 1, если строка пустая;
length unsigned length() const; возвращает длину текущей строки.
MaxWaste static size_t MaxWaste(size_t mw = 63); задает максимальное число пробельных символов и расширяет строку.
oem_to_ansi void oem_to_ansi(); функция преобразует строку из кодировки oem в кодировку ANSI согласно указанным региональным стандартам.
prepend string _FAR &prepend( const string _FAR &s );

string _FAR &prepend( const string _FAR &s, size_t start, size_t n = NPOS );

string _FAR &prepend( const char _FAR *cp );

string _FAR &prepend( const char _FAR *cp, size_t start, size_t n = NPOS );

Функция прибавляет к началу текущей строки строку s, начиная с позиции start.
put_at void put_at( size_t pos, char c ) throw( outofrange ); записывает в позицию pos символ c.
read_file istream _FAR &read_file(istream _FAR &is); читает файл из входящего потока в строку;
read_line istream _FAR &read_line(istream _FAR &is); читает строку файла из указанного потока в строку, пока не достигнут знак "перевод строки" или "конец файла".
read_string istream _FAR &read_string(istream _FAR &is); читает строку файла из указанного потока в строку, пока не достигнут знак "\0" или "конец файла".
read_to_delim istream _FAR &read_to_delim(istream _FAR &is, char delim = '\n'); читает строку файла из указанного потока в строку, пока не достигнут знак delim или "конец файла".
read_token istream _FAR &read_token(istream _FAR &is); читает строку файла из указанного потока в строку, пока не достигнут пробельный символ или "конец файла". Пустые строки в начале файла игнорируются.
rfind size_t rfind( const string _FAR &s );

size_t rfind( const string _FAR &s, size_t pos );

возвращает последний символ из текущей строки, совпавший с любым символом из строки s.
remove string _FAR &remove( size_t pos );

string _FAR &remove( size_t pos, size_t n = NPOS );

удаляет часть текущей строки (длиной n или до конца строки), начиная с позиции pos.
replace string _FAR &replace( size_t pos, size_t n = NPOS, const string _FAR &s );

string _FAR &replace( size_t pos, size_t n1, const string _FAR &s, size_t start, size_t n2 );

удаляет, по крайней мере, n (n1) позиций из текущей строки, начиная с позиции pos, и заменяет ее, по крайней мере, n2 позициями строки s, начиная с позиции start (или всей строкой s).
reserve size_t reserve() const;

void reserve( size_t ic );

resize void resize(size_t m); увеличивает длину строки на m байт.
resize_increment static size_t resize_increment(size_t ri = 64); устанавливает инкремент для автоматического изменения длины строки в ri байт.
set_case_sensitive static int set_case_sensitive(int tf = 1); устанавливает чувствительность к регистру символов при сравнении строк: 1 - чувствительный к регистру, 0 - не чувствительный.
set_paranoid_check static int set_paranoid_check(int ck = 1);
skip_whitespace static int skip_whitespace(int sk = 1); Устанавливается в единицу, чтобы пропускать пробельные символы при чтении слов (цепочек), или 0 в противном случае;
strip TSubString strip( StripType s = Trailing, char c=' '); удалят из текущей строки все пробельные или заполняющие с символы вначале, в конце строки или в обоих направлениях, и выдается ссылка на результирующую строку типа TSubString.
substr string substr( size_t pos ) const;

string substr( size_t pos, size_t n = NPOS ) const;

возвращает подстроку из текущей строки, начинающейся с позиции pos текущей строки.
substring TSubString substring( const char _FAR *cp );

const TSubString substring( const char _FAR *cp ) const;

TSubString substring( const char _FAR *cp, size_t start );

const TSubString substring( const char _FAR *cp, size_t start ) const;

создает объект типа TSubstring, содержащей копию строки cp.
to_lower void to_lower(); переводит строку в нижний регистр;
to_upper void to_upper(); переводит символы строки в верхний регистр.
Protected Member Functions
valid_element int valid_element( size_t pos ) const; возвращает 1, если в позиции pos находится элемент строки, и 0 в противном случае.
valid_index int valid_index( size_t pos ) const; возвращает 1, если pos нормальный индекс строки символов, и 0 в противном случае.
assert_element
assert_index
cow
Operators =; +=; +=; +; []; (); ==; !=; <; <=; >; >=;
Related Global Operators and Functions >>; <<; +; getline; to_lower; to_upper;
< Лекция 6 || Лекция 7: 1234 || Лекция 8 >