Файл: Лабораторная работа 1 Изучение среды разработки программ 3 Лабораторная работа 2 Исследование базовых типов данных языка Си 18.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 274
Скачиваний: 3
СОДЕРЖАНИЕ
Лабораторная работа № 1Изучение среды разработки программ
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Лабораторная работа № 2Исследование базовых типов данных языка Си
Лабораторная работа № 4Применение управляющих инструкций языка для организации ветвлений в программе
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
ЗАДАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
Лабораторная работа № 5Исследование циклов
Лабораторная работа № 6Применение массивов и указателей для решения прикладных задач
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Лабораторная работа № 7Исследование массивов и указателей
Лабораторная работа № 8Применение функций работы со строками для решения прикладных задач
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Практическое занятие № 6Использование функций для работы с массивами
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Практическое занятие № 7Программирование рекурсивных алгоритмов
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Практическое занятие № 8Применение производных типов данных для решения прикладных задач
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Лабораторная работа № 5Исследование методов доступа к файлам данных
Лабораторная работа № 6Исследование связанных списков данных
ЗАДАНИЕ НА ИССЛЕДОВАНИЕ
-
Исследование взаимосвязи между массивами и указателями
-
Описать два массива и два вспомогательных указателя. -
Проинициализировать указатели адресами массивов. -
Исследовать возможность обмена адресами начала массивов через указатели. -
Исследовать возможность обмена значениями указателей. -
Исследовать возможность обращения к элементу массива через индекс и через вспомогательный указатель. -
Исследовать возможность обращения к элементу массива через индекс и через имя массива. -
Исследовать возможность изменения значения элемента массива через вспомогательный указатель. -
Исследовать возможность изменения значения элемента массива через имя массива без использования индекса.
-
Исследование способов создания динамических массивов
-
Создать динамический массив с использованием операции new[]. -
Создать динамический массив с использованием функции malloc. -
Исследовать возможность удаления первого массива функцией free(). -
Исследовать возможность удаления второго массива операцией delete [].
Занятие 8
Лабораторная работа № 8
Применение функций работы со строками для решения прикладных задач
Цель занятия:
-
Совершенствование навыков разработки программ в среде программирования MS Visual C++ -
Совершенствование навыков использования циклов и ветвлений в программах -
Получение начальных навыков в объявлении, инициализации и использовании символьных массивов -
Получение начальных навыков в обработке строк в языке Си
Время на выполнение работы: 2 часа
Учебные вопросы:
-
Изучение способов формирования строк в языке Си -
Применение функций работы со строками для обработки символьных массивов
Подготовка к выполнению работы:
-
Изучить рекомендованную литературу (структура программы на языке высокого уровня, алфавит и элементарные конструкции языка Си, переменные и константы, стандартные типы данных, выражения и операции в языке Си, базовые конструкции структурного программирования, массивы и указатели, строковые функции). -
Изучить материал настоящего руководства.
Материалы для подготовки к занятию:
-
Конспект лекций -
[1] стр. 63-65.
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
В Cи отсутствует специальный тип строк. Строки рассматриваются как массивы символов, оканчивающиеся нулевым символом ('\0'). Строка доступна через указатель на первый символ в строке. Значением строки является адрес ее первого символа. Таким образом, можно сказать, что в Cи строка является указателем - указателем на первый символ строки. В этом смысле строки подобны массивам, потому что массив тоже является указателем на свой первый элемент (рисунок 8.1).
| . . . | |
A[4] | \0 | |
0x0012FF84 | ||
A[3] | я | |
0x0012FF83 | ||
A[2] | с | |
0x0012FF82 | ||
A[1] | а | |
0x0012FF81 | ||
A[0] | В | |
0x0012FF80 | ||
| . . . | |
const char *A | 0x0012FF80 | 0x0012FF70 |
| ||
| ||
| ||
| . . . | |
Рисунок 8.1 – Представление массива элементов в памяти ЭВМ
В приведенном примере объявлен символьный массив A на 5 элементов: char A[]=”Вася”;
Обратите внимание на то, что теперь под хранение каждого символа выделяется один байт памяти, а под указатель будет по-прежнему выделено 4 байта. Необходимо отметить, что в приведенном примере размер массива не указан, он определен автоматически по длине строки-инициализатора, причем, автоматически добавлен символ окончания строки.
Строка может быть объявлена либо как массив символов, либо как переменная типа char*. Каждое из двух приведенных ниже эквивалентных объявлений
char S[] = "строка";
char *Sp = "строка";
присваивает строковой переменной начальное значение "строка". Первое объявление создает массив из 7 элементов S содержащий символы 'с', 'т', 'р', 'о', 'к', 'а' и '\0'. Второе объявление создает переменную указатель Sp, который указывает на строку с текстом "строка", лежащую где-то в памяти. Но в любом случае число хранимых символов на 1 больше числа значащих символов за счет оконечного нулевого символа.
Доступ к отдельным символам строки осуществляется по индексам, начинающимся с нуля. Например, S[0] и Sp[0] - первые символы объявленных выше строк, S[1] и Sp[1] - вторые и т.д.
В приведенных объявлениях длина строк определялась автоматически компилятором. Можно объявлять строковые переменные заданной длины. Например, оператор char buff[100];
объявляет переменную buff, которая может содержать строку до 99 значащих символов плюс заключительный нулевой символ.
Теперь приступим к знакомству с наиболее полезным применением символьных указателей: запоминанию массивов строк. На самом деле нельзя создать массив строк, но можно запомнить массив символьных указателей, каждый из которых содержит адрес строки в памяти.
Определением массива символьных указателей создается динамический массив. Этот массив похож на двумерную таблицу с одним исключением: все строки в этом массиве могут иметь разную длину (разное количество символов в строке).
Все двумерные таблицы, которые рассматривались ранее, выровнены с обеих сторон. Например, объявим символьную таблицу с 5 строками и 10 колонками, каждая строка которой содержит одинаковое число символов. Ее можно определить следующим образом:
char names [ 5 ] [ 10 ] = { { "Сергей" },
{ "Михаил" },
{ "Николай" },
{ "Иван" },
{ "Алексей" }};
Она показана на рисунке 8.2. Обратите внимание, в таблице много пробелов. Каждая строка занимает 10 символов даже в том случае, когда символов в строке намного меньше. Незаполненные элементы содержат символ ограничитель строки, потому что Cи записывает этот символ во все неинициализированные вами элементы массива. Этот тип таблиц занимает слишком много места в памяти.
Колонки | |||||||||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
0 | С | е | р | г | е | й | \0 | | | | |
1 | М | и | х | а | и | л | \0 | | | | |
Строки 2 | Н | и | к | о | л | а | й | \0 | | | |
3 | И | в | а | н | \0 | | | | | | |
4 | А | л | е | к | с | е | й | \0 | | | |
Рисунок 8.2 – Пример двумерного символьного массива строк
Для устранения проблемы нерационального использования памяти объявим одномерный массив символьных указателей. Каждый указатель содержит адрес сроки в памяти, и эти строки могут иметь разную длину. Вот примеры определения таких массивов:
char *names [ 5 ] =
{
{ "Сергей" },
{ "Михаил" },
{ "Николай" },
{ "Иван" },
{ "Алексей" }
};
или просто
char *names [ ] =
{
{ "Сергей" },
{ "Михаил" },
{ "Николай" },
{ "Иван" },
{ "Алексей" }
};
Это одномерные массивы. Хотя раньше ничего подобного не рассматривалось, не следует смущаться. Звездочка перед
names говорит о том, что это массив указателей. Указатели имеют символьный тип. Строки не присваиваются элементам массива, но в массиве содержатся адреса этих строк. На рисунке 8.3 показан этот массив указателей. Строки могут находиться в любом месте памяти. Их местоположение не существенно, так как каждый указатель содержит адрес первого элемента соответствующей строки. Строки не занимают лишнюю память; каждая строка использует ровно столько пространства, сколько нужно для ее размещения и символа ограничителя строки. Такая структура содержит данные в форме с рваными краями.
| names | | | | | | | | | |
[0] | | | С | е | р | г | е | й | \0 | |
[1] | | | М | и | х | а | и | л | \0 | |
[2] | | | Н | и | к | о | л | а | й | \0 |
[3] | | | И | в | а | н | \0 | | | |
[4] | | | А | л | е | к | с | е | й | \0 |
Рисунок 8.3 – Массив указателей
Для вывода первой строки можно использовать оператор