Массивы и cтроки

Содержание

Слайд 2

Массивы Инициализация массивов. Размерность массива. Динамические массивы. Многомерные массивы.

Массивы

Инициализация массивов.
Размерность массива.
Динамические массивы.
Многомерные массивы.

Слайд 3

МАССИВЫ. Массивы представляют собой ограниченную упорядоченную совокупность однотипных величин. Каждая отдельная

МАССИВЫ.

Массивы представляют собой ограниченную упорядоченную совокупность однотипных величин.
Каждая отдельная величина называется

компонентой массива.
Вся совокупность компонент определяется одним именем.
Слайд 4

МАССИВЫ. Элементы массива нумеруются с нуля. При описании массива используются те

МАССИВЫ.

Элементы массива нумеруются с нуля.
При описании массива используются те же модификаторы,

что и для простых переменных:
класс памяти, const и инициализатор.

Описание массива отличается от описания простой переменной наличием после имени квадратных скобок, в которых задается количество элементов массива (размерность):

float a [10];
// описание массива из 10 вещественных чисел

Слайд 5

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

Инициализация массивов

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

по порядку.
Слайд 6

Инициализация массивов Если элементов в массиве больше, чем инициализаторов, элементы, для

Инициализация массивов

Если элементов в массиве больше, чем инициализаторов, элементы, для которых

значения не указаны, обнуляются.

Пример:

int b[5] = {3,2,1};
// b[0]=3, b[1]=2, b[2]=1, b[3]=0, b[4]=0

Слайд 7

Размерность массива Размерность массива может быть задана только целой положительной константой

Размерность массива

Размерность массива может быть задана только целой положительной константой или

константным выражением
Последний элемент массива имеет номер, на единицу меньший заданной при его описании размерности.
Слайд 8

Размерность массива Если при описании массива не указана размерность, должен присутствовать

Размерность массива

Если при описании массива не указана размерность, должен присутствовать инициализатор.


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

Размерность может быть опущена также в списке формальных параметров.

Слайд 9

Размерность массива Для доступа к элементу массива после его имени указывается

Размерность массива

Для доступа к элементу массива после его имени указывается номер

элемента (индекс)
в квадратных скобках.
Слайд 10

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

При обращении к элементам массива автоматический контроль выхода индекса за границу

массива не производится.
Слайд 11

Размерность массива // подсчитывается сумма элементов массива #include int main(){ const

Размерность массива

// подсчитывается сумма элементов массива
#include
int main(){
const int n

= 10;
int i, sum;
int mas[n] = {3, 4, 5, 4, 4};
for (i = 0, sum = 0; i cout << "Сумма элементов: " << sum;
return 0; }

Пример:

Слайд 12

Размерность массива Идентификатор массива является константным указателем на его нулевой элемент

Размерность массива

Идентификатор массива является константным указателем на его нулевой элемент

для массива

из предыдущего листинга имя mas — это то же самое, что &mas[0], а к i-му элементу массива можно обратиться, используя выражение *(mas+i).
Слайд 13

Размерность массива // программа копирует все элементы массива a в массив

Размерность массива

// программа копирует все элементы массива a в массив b
int

а[100], b[100];
int *pa = а; // или int *p = &а[0];
int *pb = b;
for(int i=0; i<100; i++)
*pb++ = *pa++; // или pb[i] = pa[i];

Можно описать указатель,
присвоить ему адрес начала массива
и работать с массивом через указатель

Пример:

Слайд 14

Динамические массивы Динамические массивы создают с помощью операции new, при этом необходимо указать тип и размерность.

Динамические массивы

Динамические массивы создают с помощью операции new, при этом необходимо

указать тип и размерность.
Слайд 15

Динамические массивы нельзя инициализировать при создании, и они не обнуляются!!!

Динамические массивы нельзя инициализировать при создании, и они не обнуляются!!!

Слайд 16

Динамические массивы int n = 100; float *р = new float

Динамические массивы

int n = 100;
float *р = new float [n];

создается указатель

на float,
в динамической памяти отводится непрерывная область, для размещения 100 элементов вещественного типа,
адрес ее начала записывается в указатель р.

Пример:

Слайд 17

Динамические массивы например, к элементу номер 5 приведенного выше массива можно

Динамические массивы

например, к элементу номер 5 приведенного выше массива можно обратиться

как
р[5] или *(р+5).

Доступ к элементам динамического массива осуществляется точно так же, как к статическим.

Слайд 18

Динамические массивы int n = 100; float *q = (float *)

Динамические массивы

int n = 100;
float *q = (float *) malloc(n *

sizeof(float));

Операция преобразования типа, записанная перед обращением к функции malloc, требуется потому, что функция возвращает значение указателя тина void*, а инициализируется указатель на float.

Альтернативный способ создания динамического массива — использование функции malloc библиотеки С.

Слайд 19

Динамические массивы Память, зарезервированная под динамический массив с помощью new [],

Динамические массивы

Память, зарезервированная под динамический массив с помощью new [], должна

освобождаться оператором delete[],
а память, выделенная функцией malloc — посредством функции free

delete [] p; free (q);

При несоответствии способов выделения и освобождения памяти результат не определен

Размерность массива в операции delete не указывается, но квадратные скобки обязательны

Слайд 20

Многомерные массивы Многомерные массивы задаются указанием каждого измерения в квадратных скобках.

Многомерные массивы

Многомерные массивы задаются указанием каждого измерения в квадратных скобках.

Слайд 21

Многомерные массивы Пример: int matr [6][8]; В памяти такой массив располагается

Многомерные массивы

Пример:

int matr [6][8];

В памяти такой массив располагается в последовательных ячейках

построчно.

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

Слайд 22

Многомерные массивы Для доступа к элементу многомерного массива указываются все его

Многомерные массивы

Для доступа к элементу многомерного массива указываются все его индексы.

например,

matr[i][j]
или более экзотическим способом: *(matr[i]+j)
или *(*(matr +i)+j)

Это возможно, поскольку matr[i] является адресом начала i-й строки массива.

Слайд 23

М А С С И В Ы При инициализации многомерного массива

М А С С И В Ы

При инициализации многомерного массива он

представляется :

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

в этом случае левую размерность при описании можно не указывать

либо задается общий список элементов в том порядке, в котором элементы располагаются в памяти

Примеры:

int mass2[][2] ={{1, 1},{0. 2},{1, 0}};
int mass2[3][2] = {1, 1, 0, 2, 1, 0};

Слайд 24

Динамические многомерные массивы Динамические многомерные массивы Для создания динамического многомерного массива

Динамические многомерные массивы

Динамические многомерные массивы

Для создания динамического многомерного массива необходимо указать

в операции new все его размерности

самая левая размерность может быть переменной

Пример:

int nstr = 5;
int ** m = (int **) new int [nstr][10];

Слайд 25

Динамические многомерные массивы Более универсальный и безопасный способ выделения памяти под

Динамические многомерные массивы

Более универсальный и безопасный способ выделения памяти под двумерный

массив, когда обе его размерности задаются на этапе выполнения программы, приведен ниже:

int nstr; nstb;
cout << " Введите количество строк и столбцов :";
cin >> nstr >> nstb;
int **a = new int *[nstr]; // 1
for(int i = 0; ia[i] = new int [nstb]; // 3

1

объявляется переменная типа «указатель на указатель на int» и выделяется память под массив указателей на строки массива

2

организуется цикл для выделения памяти под каждую строку массива

3

каждому элементу массива указателей на строки присваивается адрес начала участка памяти, выделенного под строку двумерного массива

Слайд 26

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

Динамические многомерные массивы

Процессы, происходящие в памяти при выполнении предыдущего фрагмента программы

можно проиллюстрировать следующей схемой:
Слайд 27

Динамические многомерные массивы Освобождение памяти из-под массива с любым количеством измерений

Динамические многомерные массивы

Освобождение памяти из-под массива с любым количеством измерений выполняется

с помощью операции delete [].
Слайд 28

Указатель на константу удалить нельзя!!!

Указатель на константу удалить нельзя!!!

Слайд 29

Обратите внимание Если при описании переменной используются одновременно префикс * (указатель)

Обратите внимание

Если при описании переменной используются одновременно префикс * (указатель) и

суффикс [] (массив), то переменная интерпретируется как массив указателей, а не указатель на массив:

int *p[10]; — массив из 10 указателей на int

Для правильной интерпретации объявлений полезно запомнить мнемоническое правило:
«суффикс привязан крепче префикса».

Слайд 30

Строки

Строки

Слайд 31

СТРОКИ. Строка представляет собой массив символов, заканчивающийся нуль-символом. Нуль-символ — это

СТРОКИ.

Строка представляет собой массив символов, заканчивающийся нуль-символом.
Нуль-символ — это символ с

кодом, равным 0, что записывается в виде управляющей последовательности '\0'.
По положению нуль-символа определяется фактическая длина строки.
Слайд 32

С Т Р О К И Строку можно инициализировать строковым литералом:

С Т Р О К И

Строку можно инициализировать строковым литералом:

char str[10]

= "Vasia";
// выделено 10 элементов с номерами от 0 до 9
// первые элементы - 'V','а','s','i','а','\0'
Слайд 33

С Т Р О К И Если строка при определении инициализируется,

С Т Р О К И

Если строка при определении инициализируется, ее

размерность можно опускать

компилятор сам выделит соответствующее количество байт

char str[] = "Vasia";
// выделено и заполнено 6 байт

Слайд 34

С Т Р О К И Оператор char *str = "Vasia"

С Т Р О К И

Оператор
char *str = "Vasia"
создает

не строковую переменную,
а указатель на строковую константу,
изменить которую невозможно

к примеру, оператор str[1]='o' не допускается

Слайд 35

Знак равенства перед строковым литералом означает инициализацию, а не присваивание!!!

Знак равенства перед строковым литералом означает инициализацию,
а не присваивание!!!

Слайд 36

С Т Р О К И Операция присваивания одной строки другой

С Т Р О К И

Операция присваивания одной строки другой не

определена и может выполняться с помощью цикла или функций стандартной библиотеки

поскольку строка является массивом

Библиотека (<сstring.h>) предоставляет возможности копирования, сравнения, объединения строк, поиска подстроки, определения длины строки и т. д., а также содержит специальные функции ввода строк и отдельных символов с клавиатуры и из файла

Слайд 37

С Т Р О К И Пример : // Программа запрашивает

С Т Р О К И

Пример :

// Программа запрашивает пароль не

более трех раз.
#include
#include
int main(){
char s[80], passw[] = "kuku"; // passw - эталонный пароль.
// Можно описать как *passw = "kuku";
int i, k = 0;
for (i=0; !k && i<3; i++){
printf("\nвведите пароль:\n"); gets(s); // функция ввода строки
if (strstr(s,passw))k = 1; // функция сравнения строк
}
if (k) printf("\nпароль принят");
else printf("\nпароль не принят");
return 0;
}
Слайд 38

С Т Р О К И При работе со строками часто

С Т Р О К И

При работе со строками часто используются

указатели

Очевидный алгоритм имеет вид:

Рассмотрим процесс копирования строки src в строку dest.

char src[10], dest[10];
for (int i = 0; i<=strlen(src); i++) dest[i] = src[i];

Таким образом, строка фактически просматривается дважды.

Длина строки определяется с помощью функции strlen, которая вычисляет длину, выполняя поиск нуль-символа.

Слайд 39

С Т Р О К И Более эффективным будет использовать проверку

С Т Р О К И

Более эффективным будет использовать проверку на

нуль-символ непосредственно в программе:

#include
int main(){
char *src = new char [10];
char *dest = new char [10], *d = dest;
cin >> src;
while ( *src != 0) *d++ = *src++;
*d = 0; // завершающий нуль
cout << dest;
return 0;
}

Слайд 40

Обратите внимание В приведенном примере, результат операции присваивания — передаваемое значение,

Обратите внимание

В приведенном примере, результат операции присваивания — передаваемое значение, которое,

собственно, и проверяется в условии цикла, поэтому можно поставить присваивание на место условия, а проверку на неравенство нулю опустить
(при этом завершающий нуль копируется в цикле, и отдельного оператора для его присваивания не требуется).

В результате цикл копирования строки принимает вид:

while ( *d++ = *src++);

Слайд 41

С Т Р О К И Оба способа работы со строками

С Т Р О К И

Оба способа работы со строками
(через

массивы или указатели) приемлемы и имеют свои плюсы и минусы, но в общем случае лучше не изобретать велосипед, а пользоваться функциями библиотеки или определенным в стандартной библиотеке C++ классом string, который обеспечивает индексацию, присваивание, сравнение, добавление, объединение строк и поиск подстрок, а также преобразование из С-строк, то есть массивов типа char, в string, и наоборот.
Слайд 42

С Т Р О К И Распространенные ошибки при работе со

С Т Р О К И

Распространенные ошибки при работе со строками:
отсутствие

нуль-символа
выход указателя при просмотре строки за ее пределы