Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Bilety_programmirovanie_1-7.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.4 Mб
Скачать

77. Тип данных «Массив массивов»

рассмотрим фрагмент кода, в котором показано, как объявляется двумерный динамический массив.

// объявление двумерного динамического массива на 10 элементов:

float **ptrarray = new float* [2]; // две строки в массиве

for (int count = 0; count < 2; count++)

ptrarray[count] = new float [5]; // и пять столбцов

// где ptrarray – массив указателей на выделенный участок памяти под массив вещественных чисел типа float

Сначала объявляется указатель второго порядка float **ptrarray, который ссылается на массив указателей float* [2], где размер массива равен двум. После чего в цикле for каждой строке массива объявленного в строке 2 выделяется память под пять элементов. В результате получается двумерный динамический массив ptrarray[2][5]. Рассмотрим пример высвобождения памяти отводимой под двумерный динамический массив.

// высвобождение памяти отводимой под двумерный динамический массив:

for (int count = 0; count < 2; count++)

delete [] ptrarray[count];

// где 2 – количество строк в массиве

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

// new_delete_array2.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h"

#include <iostream>

#include <ctime>

#include <iomanip>

using namespace std;

int main(int argc, char* argv[])

{

srand(time(0)); // генерация случайных чисел

// динамическое создание двумерного массива вещественных чисел на десять элементов

float **ptrarray = new float* [2]; // две строки в массиве

for (int count = 0; count < 2; count++)

ptrarray[count] = new float [5]; // и пять столбцов

// заполнение массива

for (int count_row = 0; count_row < 2; count_row++)

for (int count_column = 0; count_column < 5; count_column++)

ptrarray[count_row][count_column] = (rand() % 10 + 1) / float((rand() % 10 + 1)); //заполнение массива случайными числами с масштабированием от 1 до 10

// вывод массива

for (int count_row = 0; count_row < 2; count_row++)

{

for (int count_column = 0; count_column < 5; count_column++)

cout << setw(4) <<setprecision(2) << ptrarray[count_row][count_column] << " ";

cout << endl;

}

// удаление двумерного динамического массива

for (int count = 0; count < 2; count++)

delete []ptrarray[count];

system("pause");

return 0;

}

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

78. Представление строк в языках программирования. Достоинства и недостатки различных представлений (отличие ‘a’ от “a”).

В программировании, строковый тип (англ. string «нить, вереница») — тип данных, значениями которого является произвольная последовательность (строка) символов алфавита. Каждая переменная такого типа (строковая переменная) может быть представлена фиксированным количеством байтов либо иметь произвольную длину.

Реализация в языках программирования

• В первых языках программирования вообще не было строкового типа; программист должен был сам строить функции для работы со строками того или другого типа.

• В Си используются нуль-терминированные строки с полным ручным контролем со стороны программиста.

• В стандартном Паскале строка выглядит как массив из 256 байтов; первый байт хранил длину строки, в остальных хранится её тело. Таким образом, длина строки не может превышать 255 символов. В Borland Pascal 7.0 также появились строки «а-ля Си» — очевидно, из-за того, что в число поддерживаемых платформ вошла Windows.

• В Object Pascal и STL строка является «чёрным ящиком», в котором выделение/высвобождение памяти происходит автоматически — без участия программиста. При создании строки память выделяется автоматически; как только на строку не останется ни одной ссылки, память возвращается системе. Преимущество этого метода в том, что программист не задумывается над работой строк. С другой стороны, программист имеет недостаточный контроль над работой программы в критичных к скорости участках; также трудно реализуется передача таких строк в качестве параметра в DLL. Также Object Pascal автоматически следит, чтобы в конце строки был символ с кодом 0. Поэтому если функция требует на входе нуль-терминированную строку, для конвертации надо просто написать PAnsiChar(строковая_переменная) или PWideChar(строковая_переменная) (для Pascal), переменная.c_str() (для Builder/STL).

• В C# и других языках со сборкой мусора строка является неизменяемым объектом; если строку нужно модифицировать, создаётся другой объект. Этот метод медленный и расходует немало временной памяти, но хорошо сочетается с концепцией сборки мусора. Преимущество этого метода в том, что присваивание происходит быстро и без дублирования строк. Также имеется некоторый ручной контроль над конструированием строк (в Java, например, через класс StringBuffer) — это позволяет уменьшить количество выделений и высвобождений памяти и, соответственно, увеличить скорость.

Представление массивом символов

В этом подходе строки представляются массивом символов; при этом размер массива хранится в отдельной (служебной) области. От названия языка Pascal, где этот метод был впервые реализован, данный метод получил название Pascal strings.

Слегка оптимизированным вариантом этого метода является т. н. формат c-addr u (от англ. character-aligned address + unsigned number), применяемый в Форте. В отличие от Pascal strings, здесь размер массива хранится не совместно со строковыми данными, а является частью указателя на строку.

Преимущества

• программа в каждый момент времени «знает» о размере строки, и операции добавления символов в конец, копирования и получения размера строки выполняются достаточно быстро;

• строка может содержать любые данные;

• возможно на программном уровне следить за выходом за границы строки при её обработке;

• возможно быстрое выполнение операции вида «взятие N-ого символа с конца строки».

Недостатки

• проблемы с хранением и обработкой символов произвольной длины;

• увеличение затрат на хранение строк — значение «длина строки» также занимает место и в случае большого количества строк маленького размера может существенно увеличить требования алгоритма к оперативной памяти;

• ограничение максимального размера строки. В современных языках программирования это ограничение скорее теоретическое, так как обычно размер строки хранится в 32-битовом поле, что даёт максимальный размер строки в 4 294 967 295 байт (4 гигабайта).

Метод «завершающего байта»

Основная статья: Нуль-терминированная строка

Второй метод заключается в использовании «завершающего байта». Одно из возможных значений символов алфавита (как правило, это символ с кодом 0) выбирается в качестве признака конца строки, и строка хранится как последовательность байтов от начала до конца. Есть системы, в которых в качестве признака конца строки используется не символ 0, а байт 0xFF (255) или код символа «$».

Метод имеет три названия — ASCIIZ (символы в кодировке ASCII с нулевым завершающим байтом), C-strings (наибольшее распространение метод получил именно в языке Си) и метод нуль-терминированных строк.

Преимущества

• отсутствие дополнительной служебной информации о строке (кроме завершающего байта);

• возможность представления строки без создания отдельного типа данных;

• отсутствие ограничения на максимальный размер строки;

• экономное использование памяти;

• простота получения суффикса строки;

• простота передачи строк в функции (передаётся указатель на первый символ);

• возможность использовать алфавит с переменным размером символа (например, UTF-8).

Недостатки

• долгое выполнение операций получения длины и конкатенации строк;

• отсутствие средств контроля за выходом за пределы строки, в случае повреждения завершающего байта возможность повреждения больших областей памяти, что может привести к непредсказуемым последствиям — потере данных, краху программы и даже всей системы;

• невозможность использовать символ завершающего байта в качестве элемента строки.

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

При построении алгоритмов обработки строк полезно знать и использовать следующие возможности: стандартные процедуры и функции для строк (символов); упорядоченность множества символов; механизм динамических строк и их внутреннее представление; основные способы обработки строковых переменных. Основные алгоритмы обработки строк: включение и исключение символов или последовательности символов; поиск в строке (алгоритмы Кнута, Мориса и Пратта, Боуера и Мура и др.); прямой поиск и т.д. Алгоритмы преобразования строк применимы сейчас к широкому кругу задач: редактирование текстов; перевод текста с одного естественного языка в другой; криптология; информационно-поисковые системы; структурный подход к задаче распознавания образов и др.

80. Основные функции стандартной библиотеки <cctype>

Заголовочный файл cctype содержит функции обработки символов. Эта библиотека объявляет набор функций для выполнения различных классификаций и некоторых операций преобразования отдельных символов.

Все функции, определённые в заголовочном файле cctype принимают в качестве аргумента значение типа int (эквивалент одного символа) и возвращают целое число, которое является эквивалентом символа, либо значением, которое представляет логическое значение: целочисленное значение 0 — ложь, и целочисленное значение, отличное от 0 — истина. В этом файле определены два набора функций:

  • функции классификации символов ;

  • функции преобразования символов.

Первый набор — функции возвращающие логическое значение, они проверяют, к какой категории символов относится символ, переданный им в качестве аргумента. К ним относятся следующие функции:

isalumn

Функция возвращает истинное значение true, если её аргумент - буква или цифра, и false(ложь) в других случаях.

isalpha

Функция возвращает истинное значение true, если её аргумент — буква,  и false(ложь) в других случаях.

iscntrl

Функция возвращает истинное значение true, если её аргумент - управляемый символ, и false(ложь) в других случаях.

isdigit

Функция возвращает истинное значение true, если её аргумент — десятичная цифра, и false(ложь) в других случаях.

isgraph

Функция возвращает истинное значение true, если её аргумент — символ, имеющий графическое представление, и false(ложь)  в других случаях.

islower

Функция возвращает истинное значение true, если её аргумент — строчный символ алфавита, и false(ложь) в других случаях.

isprint

Функция возвращает истинное значение true, если её аргумент — печатный символ, и false(ложь) в других случаях.

ispunct

Функция возвращает истинное значение true, если её аргумент — знак пунктуации, и false(ложь) в других случаях.

isspace

Функция возвращает истинное значение true, если её аргумент — любой знак пробела, и false(ложь) в других случаях.

isupper

Функция возвращает истинное значение true, если её аргумент — прописная буква алфавита, и false(ложь) в других случаях.

isxdigit

Функция возвращает истинное значение true, если её аргумент — цифра шестнадцатеричной системы исчисления, и false(ложь) в других случаях.

Второй набор функций — это функции, выполняющие некоторые преобразования символов. Их всего две:

tolower

Преобразование заглавного символа в строчный.

toupper

Преобразование строчного символа в  заглавный.

81. Основные функции стандартной библиотеки <cstring>

Эта библиотека определяет несколько функций для обработки Cи-строк и массивов. В таблице кратко описаны функции, макросы и типы данных этого заголовочного файла.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]