- •1.1. Элементы языка программирования
- •Основные правила записи программы:
- •1.2. Алфавит языка
- •1.3. Лексемы
- •1.4. Концепция данных
- •2.2. Операции
- •2.2.1. Арифметические операции
- •2.2.2. Операции присваивания
- •2.2.3. Операции отношения
- •2.2.4. Логические операции
- •2.2.5. Поразрядные операции
- •2.2.6. Вычисление выражений
- •3. Структурное программирование
- •3.1. Общая характеристика операторов
- •3.2. Оператор-выражение
- •3.3. Условный оператор
- •3.4. Составной оператор
- •3.5. Операторы для программирования циклов
- •3.5.1. Оператор цикла for
- •3.5.2. Оператор цикла while
- •3.5.3. Оператор цикла do while
- •3.5.4. Оператор break
- •3.5.5. Оператор continue
- •3.6. Оператор goto
- •3.7. Пустой оператор
- •3.8. Оператор switch
- •3.9. Оператор return
- •4. Массивы
- •4.1. Объявление массива
- •4.2. Обращение к элементам массива
- •4.3. Типовые алгоритмы работы с массивами
- •4.4. Многомерные массивы
- •5. Строки
- •5.1. Объявление строки
- •5.2. Посимвольная обработка строк
- •5.3. Ввод строк
- •5.4. Библиотечные функции для работы с текстом
- •6. Указатели
- •6.1. Объявление указателей
- •6.2. Операции над указателями
- •6.3. Связь между указателями и массивами
- •6.4. Функция strtok для выделения лексем из текста
- •6.5. Динамические массивы
- •7. Структуры и объединения
- •7.1. Объявление структуры
- •Компонент структуры может быть любого типа, кроме типа объявляемой структуры.
- •7.2. Операции над структурами
- •7.3. Объявление объединения
- •8. Модульное программирование
- •8.1. Нисходящее проектирование и программирование
- •8.2. Определение и вызов функции
- •8.3. Место определения функции в программе
- •8.4. Обмен данными между функциями
- •8.4.1. Использование глобальных переменных
- •8.4.2. Использование аппарата формальных и фактических параметров
- •8.4.3. Передача массивов в функцию
- •8.5. Перегрузка функции
- •8.6. Шаблон функции
- •8.7. Рекурсивные функции
- •8.8. Функции с параметрами по умолчанию
- •8.9. Передача в функцию другой функции
- •9. Работа с файлами
- •9.1. Текстовые и двоичные файлы
- •9.2. Объявление файловых переменных
- •9.3. Чтение текстового файла
- •9.4. Создание текстового файла
- •9.5. Изменение данных в текстовом файле
- •9.6. Вывод в двоичный файл
- •9.7. Чтение данных из двоичного файла
- •9.8. Изменение данных двоичного файла
- •9.9. Организация файла с произвольным доступом
- •10. Данные с динамической структурой
- •10.1. Линейный список
- •10.1.1. Специальные типы линейных списков
- •10.1.2. Реализация линейного списка с помощью массива
- •10.1.3. Реализация линейного списка с помощью связанного однонаправленного списка
- •10.1.4. Реализация линейного списка с помощью связанного двунаправленного списка
- •10.2. Деревья
- •10.2.1. Основная терминология
- •10.2.2. Реализация двоичных деревьев поиска Для реализации дерева поиска используются массивы и связанные указателями элементы [3, 4].
- •10.2.3. Сбалансированные деревья
- •Основные достоинства в-дерева:
- •10.3. Графы
- •10.3.1. Определения
- •10.3.2. Реализация графа с помощью списков смежности
- •10.3.3. Реализация графа с помощью матрицы смежности
- •10.3.4. Поиск кратчайших путей. Алгоритм Дейкстры
- •10.3.5. Матрица достижимости. Алгоритм Уоршалла
6.3. Связь между указателями и массивами
Указатели и массивы в языке С++ взаимосвязаны и могут использоваться в программе почти одинаково. В языке С++ имя массива является константным указателем, содержащим адрес начала массива (адрес 0-элемента). Изменить значение константного указателя нельзя, поэтому нельзя присвоить один массив другому. Но так как массив является указателем, то к нему можно применять некоторые операции, определенные для указателей. Например, можно обращаться к элементам массива с помощью смещения указателя относительно начала массива:
int a[5]={10, 20, 30, 40, 50};
*a=1; //равносильно a[0]=1;
*(a+1)=2; //равносильно a[1]=2;
Для С++ справедливо утверждение: указатель, содержащий адрес начала массива (или адрес любого элемента массива), можно рассматривать как массив, который находится по адресу, хранящемуся в указателе. Следовательно, указатель, который указывает на элемент массива, можно индексировать.
Пример использования указателя и массива:
char s[10]=”abcdef”; //массив символов
char *ps; //указатель на символ
ps=s; //указатель содержит адрес массива символов s
cout<<s<<endl; //abcdef
cout<<ps;<<endl; //abcdef
ps=&s[2]; // указатель содержит адрес элемента массива символов
cout<<ps;<<endl; //cdef (вывод части строки)
ps[0]=’#’; //изменение содержимого строки через указатель
cout<<ps;<<endl; //#def (вывод части строки)
cout<<s;<<endl; //ab#def (вывод измененной строки)
6.4. Функция strtok для выделения лексем из текста
Слова текста можно рассматривать как неделимые объекты – лексемы, а знаки пунктуации – как разделители лексем. Можно лексемой считать предложение, а разделителями лексем-предложений считать точку, восклицательный и вопросительный знаки.
Функция strtok из стандартной библиотеки string используется для выделения лексем из строки. У функции есть два аргумента. При первом вызове первый аргумент – строка, из которой надо выделить первую лексему, а второй – строка разделителей лексем. Результат функции – адрес первой лексемы. Например, для выделения первого слова в тексте, в котором слова разделены пробелами и запятыми, можно использовать код:
char s[81]=”abc fgh, aa”;
char *p;
p=strtok(s,” ,“);
cout<<p<<endl; // abc
Функция находит первый символ ('a'), отличный от разделителя – адрес этого символа и есть адрес первой лексемы. Кроме того, функция находит первый разделитель в строке (' ') и заменяет его 0-символом. Теперь можно вывести строку, заданную указателем р или выполнить с ней другие действия. Функция также находит в строке и сохраняет в своих внутренних переменных адрес следующей лексемы (или 0, если в строке больше нет лексем). Для выделения из строки следующей лексемы функция вызывается повторно, но в качестве первого аргумента функции указывается значение 0. Например,
p=strtok(0,” ,“);
cout<<p<<endl; //fgh
Функция strtok, выделяя из строки лексемы, изменяет строку. Поэтому, если со строкой надо работать далее, ее надо предварительно сохранить в другой переменной.
Пример программы, которая находит количество вхождений заданного слова в текст, слова в котором разделены знаками пунктуации и пробелами:
#include <conio.h>
#include <iostream.h>
#include <string.h>
void main()
{
char r[]=" ,.!?:;-"; //массив разделителей
char s[81]; //текст
char word[21]; //слово-образец
char *pw; //адрес очередного слова (лексемы)
int k; //счетчик вхождений слова word в текст
cout<<”s? “;
cin.getline(s,81); //чтение строки с пробелами
cout<<”word? “;
cin>>word;
k=0;
pw=strtok(s,r); //выделение первого слова
while(pw!=0) //цикл выделения и сравнения слов-лексем
{
if (strcmp(pw,word)==0)
k++;
pw=strtok(0,r); //выделение следующего слова
}
cout<<”k=”<<k;
getch();
}
