Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
default-1.doc
Скачиваний:
28
Добавлен:
28.09.2019
Размер:
221 Кб
Скачать
☆
  1. Массивы указателей. Массивы динамической памяти.

Массив указателей (МУ) – простейшая структура данных, в которой проявляется различие между физическим и логическим порядком следования элементов. Способ организации данных ясен уже из самого определения: это массив, каждый элемент которого содержит указатель на переменную (объект).

Операция new при использовании с массивами имеет следующий формат:

new <тип массива>.

Такая операция позволяет выделить в динамической памяти участок для размещения массива соответствующего типа, но не позволяет его инициализировать. В результате выполнения операция new возвратит указатель, значением которого служит адрес первого элемента массива. При выделении динамической памяти для массива его размеры должны быть полностью определены, например:

long (*lp)[2] [4] ; // Определили указатель.

lp = new long[3][2][4] ; // Выделили память для массива.

В данном примере использован указатель на объекты в виде двумерных массивов, каждый из которых имеет фиксированные размеры 2 на 4 и содержит элементы типа long. В определении указателя следует обратить внимание на круглые скобки, без которых обойтись нельзя. После выполнения приведенных операторов указатель lp становится средством доступа к участку динамической памяти с размерами 3 * 2 * 4 * sizeof(long) байтов. В отличие от имени массива (имени у этого массива из примера нет) указатель lp есть переменная, что позволяет изменять его значение и тем самым, например, перемещаться по элементам массива.

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

delete [] lp;

освободит целиком всю память, выделенную для определенного выше трехмерного массива, если lp адресует его начало.

B отличие от определения массивов, не размещающихся в динамической памяти, инициализация динамических массивов не выполняется. Поэтому при выделении памяти для динамических массивов их размеры должны быть полностью определены явно. Кроме того, только первый (самый левый) размер массива может быть задан с помощью переменной. Остальные размеры многомерного массива могут быть определены только с помощью констант. Это затрудняет работу с многомерными динамическими массивами. Обойти это ограничение позволяет применение массивов указателей.

  1. Представление символа и строки в памяти эвм. Ввод-вывод символов и строк.

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

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

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

Основные проблемы в машинном представлении строкового типа:

строки могут иметь достаточно существенный размер (до нескольких десятков мегабайтов);

изменяющийся со временем размер — возникают трудности с добавлением и удалением символов.

В представлении строк в памяти компьютера существует два принципиально разных подхода.

[править]

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

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

[править]

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

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

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

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

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

[править]

Недостатки

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

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

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

  1. Функции для работы со строками.

Давайте вначале посмотрим, что нам может дать наша библиотека stdio.h, которая содержит парочку функций работы со строками:

int getchar()

возвращает значение символа, введенного вами с клавиатуры. А вот и вывод этого числа:

printf("%d", getchar());

char *gets (char *s)

функция просит вводить пользователя строку, которую она помещает в массив s, пока пользователь не нажмет 'Enter':

char str[7] = "";

gets(str) ;

int putchar (int c)

печатает символ, который имеет код 'c':

putchar(97);//напечатает символ а

int puts (char *s)

печатает строку s и переводит курсор на новую строку:

char str[7] = "sergey";

puts(str);

int sprintf (char *s, char *format, ...)

Выполняет тоже, что и функция printf, за тем исключением, что записывает данные в массив s:

char str[37] = "";

sprintf (str,"chislo:%d, month: %s",10,"desember");

//В массиве будет: chislo:10, month: desember

int sscanf (char *s, char *format, ...)

происходит ввод значений не с клавиатуры, а из массива s:

char str[37] = "sergey", s[100]="";

sscanf (str,"%s", s);

string.h

Теперь давайте рассмотрим очень мощную библиотеку для работы со строками c: string.h. Естественно, что для работы функций библиотеки string.h ее надо подключить к нашей программе.

Вот перечень функций:

char *strcpy (char *srt1, char str2)

Копирует строку str2 в строку str1, возвращаемым значением этой функции является новая, полученная строка str1

char str[37] = "sergey", s[100]="monk";

strcpy(str,s);

char *strncpy (char *srt1, char str2, int n)

эта функция делает все тоже самое, что и предвидущая, за исключением того, что тут возможен контроль количества копируемых символов:

char str[37] = "sergey", s[100]="monk";

strncpy(str,s,3);//ответ: mongey

char *strcat (char *srt1, char str2)

Функция добавляет в строку str1 строку str2. Т.е. на место нуль-терминатора в строке str1, вставляется строка str2:

char str[37] = "sergey", s[100]="monk";

strcat(str,s); //Ответ: sergeymonk

char *strncat (char *srt1, char str2, int n)

Добавляет к первой строке ровно n символов из второй строки

char str[37] = "sergey", s[100]="monk";

strncat(str,s,2);//ответ: sergeymo

Вот вы и посмотрели функции работы со строками c и библиотечный файл string.h. С ними все намного упрощается. Но прежде чем вы будете их использовать, надо выполнить домашнее задание.