Не зависят от конкретного компьютера Язык Си
![]()
|
Динамические массивы Результат работы программы: успешное завершение Динамические массивы Результат работы программы: досрочное завершение Динамические массивы Пример. Задана матрица A(N,M). Требуется сформировать вектор P(M) и записать в него номера строк максимальных элементов каждого столбца матрицы. Алгоритм решения задачи: для каждого столбца матрицы находим максимальный элемент и его номер, номер максимального элемента j-го столбца матрицы записываем в j-й элемент массива P. Динамические массивы … int main() { setlocale(LC_ALL,"Rus"); int i, j, N, M; int **ptrarray, *ptrvalue; int max, Nmax; … // ввод размерности матрицы // выделение памяти ptrarray = new int *[N]; for(i = 0; i < N; i++) ptrarray[i] = new int [M]; ptrvalue = new int [M]; Динамические массивы … // заполнение матрицы случайными числами из диапазона [a,b] и вывод ее на экран // поиск в j-м столбце максимального элемента и его номера строки for (j = 0; j < M; j++) { max = ptrarray[0][j]; Nmax = 0; for (i = 0; i < N; i++) if (ptrarray[i][j] > max) {max = ptrarray[i][j]; Nmax = i;} // записываем найденный Nmax в j-й элемент массива максимальных значений ptrvalue[j] = Nmax; cout << setw(5) << ptrvalue[j] << " |"; } Динамические массивы // высвобождение памяти for (i = 0; i < N; i++) delete [ ] ptrarray[i]; delete [ ] ptrarray; delete [ ] ptrvalue; … } Динамические массивы Результат работы программы: Строки и символьные массивы Для работы с символами используется тип char. Переменным типа char в качестве значения можно присваивать символьные константы. Символьная константа представляет собой символ, заключенный в апострофы (одинарные кавычки), например, 's'. Пример объявления символьной переменной: char symbol = 's'; symbol – имя переменной типа char Строки и символьные массивы Для представления управляющих символов используются комбинации символов, начинающиеся с символа обратной косой черты, например, \n – перевод строки, \r – возврат каретки и др. Обратная косая черта используется и в том случае, когда необходимо представить символ с помощью его восьмеричного или шестнадцатеричного кода. Например, '\163', '\x73' и 's' – это одна и та же константа. Строки и символьные массивы Текстовая (строковая) константа – это последовательность символов, заключенная в двойные кавычки, например "s". Обратите внимание. При размещении текстовой константы в памяти транслятор автоматически добавляет в конец нуль-терминатор '\0', поэтому для хранения строковой константы "s" потребуется 2 байта памяти (1 байт для самого символа и 1 байт для нуль-терминатора, добавляемого компилятором), т.е. на 1 байт больше, чем для хранения символьной константы 's'. Строки и символьные массивы Функции стандартной библиотеки С++ для работы с символами находятся в заголовочном файле Основную их часть составляют функции, проверяющие принадлежность символа некоторому множеству. Аргументом функций является код символа. Функции возвращают ненулевое значение (истина), если символ принадлежит нужному множеству, и ноль (ложь), если не принадлежит. Также в файле есть функции, переводящие символ из одного регистра в другой. Строки и символьные массивы Примеры функций обработки символов: isalpha - проверяет, является ли символ буквой или цифрой; isalpha – проверяет, является ли символ буквой; isdigit – проверяет, является ли символ цифрой; isprint – проверяет, является ли символ печатным (примечание: печатными являются все символы, кроме управляющих); ispunct – проверяет, является ли символ знаком пунктуации; isspace – проверяет, является ли символ пробелом; Строки и символьные массивы Примеры функций обработки символов: islower – проверяет, является ли символ строчной буквой алфавита; isupper – проверяет, является ли символ прописной буквой алфавита; tolower – преобразует прописной символ алфавита в строчный; toupper – преобразует строчный символ алфавита в прописной. Строки и символьные массивы Пример. Напишем функцию, которая выводит на экран символы, являющиеся буквой, и их коды. void Prim11_1() { unsigned char ch; int i = 0; for (ch = 1; ch != 0; ch++) { if (isalpha(ch)) { i++; cout << setw(7) << (int) ch << setw(3) << ch; if (i == 7) { cout << endl; i = 0; } } } сout << endl; } Строки и символьные массивы Функция перебирает все коды от 1 до 255 (символ с кодом 0 – нуль-терминатор) и для каждого кода вызывает функцию isalpha. Обратите внимание. Если в заголовке цикла for написать условие (ch = 1; ch <= 255; ch++), то программа зациклится, так как после сложения 255 с единицей значение ch будет равно нулю, а для нуля условие выполняется. Чтобы вывести на экран код символа, мы преобразовали ch к типу int. Строки и символьные массивы Результат работы функции зависит от того, выполнялась ли функция setlocale. Если нет, то на экран будут выведены только латинские буквы и их коды: Строки и символьные массивы В противном случае, кроме латинских будут выведены русские и другие буквы (кириллица), которые есть в кодировке cp1251. Некоторые из них на экране отображены некорректно. Строки и символьные массивы Строки (Си-строки или строки в стиле Си) в С++ представляются как массивы элементов типа char, заканчивающиеся нуль-терминатором \0. Символы такого массива располагаются последовательно в соседних ячейках памяти – в каждой ячейке хранится один символ и занимает один байт. Если в последней ячейке находится символ, отличный от признака конца строки ( '\0' ), для компилятора это уже не строка. И работать с таким набором символов необходимо как с обычным массивом. Строки и символьные массивы Важно: при объявлении строкового массива необходимо учитывать наличие в конце строки нуль-терминатора, и отводить под него дополнительный байт. Пример объявления строки: char string[10]; string – имя строковой переменной, 10 – размер символьного массива, т.е. в данной строке может поместиться 9 символов, а последнее место отводится под нуль-терминатор. Строки и символьные массивы Доступ к элементам строки осуществляется так же, как доступ к элементам обычного массива. Пример: char sym = string[2]; Переменная sym будет содержать 3-й элемент строки. Строка при объявлении может быть инициализирована начальным значением. Пример инициализации строки при объявлении: char string[10] = "abcdefghi"; Строки и символьные массивы В данном случае строка размером 10 символов инициализирована строковой константой "abcdefghi", состоящей из 9 символов, последнее место отводится под нуль-терминатор. Признак конца строки прописывать не надо, он присутствует неявно и добавляется компилятором в каждую такую строковую константу автоматически. Cтрока выводится на экран символ за символом, пока не встретит в одной из ячеек массива признак конца строки и вывод прервется: cout << string << endl; Строки и символьные массивы При объявлении строки не обязательно указывать еe размер (его подсчитает компилятор), но при этом обязательно нужно еe инициализировать начальным значением. Тогда размер строки определится автоматически и в конец строки добавится нуль-терминатор. Пример: char string[ ] = "abcdefghi"; Строки и символьные массивы Строка при объявлении может быть инициализирована символьными константами. В таком случае последним символом строки должен быть прописан нуль-терминатор ('\0'). Пример посимвольной инициализации строки: char string[10] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0' }; Строка может содержать символы, цифры и специальные знаки. Строки и символьные массивы Рассмотрим ввод строк с клавиатуры. Если начальные значения строки вводятся с клавиатуры, то необходимо объявить массив типа char с указанием его размера, достаточного для хранения вводимых символов, включая \0. Например, если в массиве хранится 14 символов, его размер должен быть на единицу больше – то есть 15. Строки и символьные массивы Пример ввода строки и вывода ее на экран. … int main() { setlocale(LC_ALL,"Rus"); char siteName[15] = ""; cout << "Название сайта: "; cin >> siteName; cout << siteName << endl; … } Результат работы программы: Строки и символьные массивы Используя пустые кавычки при инициализации строки, мы присваиваем каждому элементу массива значение \0. Таким образом строка будет очищена от «мусора» других программ. В данном случае, если пользователь введет название сайта, содержащее меньшее количество символов, следующий за названием сайта символ будет \0. В памяти данная строка выглядит так:
Строки и символьные массивы Перезапишем 5-ю ячейку данного массива siteName[5] = '\0';
Результат работы программы: Строки и символьные массивы Обратите внимание, несмотря на то, что в ячейках 6, 7 остались храниться символы, при обнаружении нулевого символа '\0' в 5-й ячейке вывод на экран прервался и все, что находится за ним, на экране не показано. Строки и символьные массивы Пример ввода строки с клавиатуры через объект cin и вывод ее на экран. Примечание: при вводе строки использовать латиницу. … int main() { setlocale(LC_ALL,"Rus"); char string[100] = ""; cout << "Ваша любимая цитата: "; cin >> string; cout << string << endl; … } Строки и символьные массивы Результат работы программы: Обратите внимание, введенная цитата выведена на экран не полностью, выведено только первое слово. Это связано с тем, что операция потока ввода >> воспринимает пробел, символ новой строки и табуляцию как признак конца строки. То есть в данном случае операция потока ввода >> прочитала только первое слово и автоматически добавила знак конца строки. Строки и символьные массивы Для того, чтобы считать все введенные символы из входного потока данных вместе с операцией потока ввода >> можно воспользоваться функциями getline() или get() : getline() – считывает неформатированные данные из потока в строку. Останавливается, как только достигнут максимальный размер строки, найден символ, равный символу завершения ввода, или исчерпан поток. Сам символ завершения ввода не читается. По умолчанию символом завершения ввода является символ новой строки. Строки и символьные массивы Обратите внимание, cin.getline(имя_строки, размер_строки) считывает из входного потока всю строку, включая пробелы и табуляции, пока не произойдет нажатие Enter или пока не будет превышен размер массива и записывает ее в указанную строковую переменную. При этом символ перевода строки \n из потока удаляется и заменяется на нулевой символ \0. Строки и символьные массивы get() – считывает неформатированные данные из потока по одному символу. Останавливается, как только достигнут максимальный размер строки, найден символ, равный символу завершения ввода, или исчерпан поток. Обратите внимание, cin.get(имя_строки, размер_строки) считывает из входного потока каждый символ, пока не произойдет нажатие Enter или пока не будет превышен размер массива и записывает их в указанную строковую переменную. При этом символ перевода строки \n из потока не удаляется. Строки и символьные массивы В результате при вводе нескольких строк будет введена только первая строка. Вместо последующих строк окажутся пустые строки, так как символ перевод строки \n, оставленный в потоке ввода, будет обнаружен следующей функцией get() и интерпретирован как ввод пустой строки. Строки и символьные массивы Использование функций get() и getline() с тремя аргументами: имя строковой переменной, длина строки, символ завершения ввода позволяет вводить поток, состоящий из нескольких строк. Таким образом, строка будет вводится до тех пор, пока не будет введен символ, объявленный признаком завершения ввода, или пока не будет превышен максимальный размер строки. Например, cin.get(string, 100, '*'); или cin.getline(string, 100, '*'); Строки и символьные массивы Для определения максимального размера строки удобно использовать оператор sizeof(). Например, при изменении размера массива, оператор sizeof() будет использовать его корректный размер. cin.getline(string, sizeof(string)); или cin.get(string, sizeof(string)); Строки и символьные массивы Дополним программу вводом с использованием функции |