- •Программирование и основы алгоритмизации Методические указания к лабораторным работам
- •Введение
- •Порядок выполнения лабораторных работ
- •Оформление отчетов к лабораторным работам
- •Лабораторная работа 1
- •Директивы препроцессора
- •Комментарии
- •Простые типы
- •Операции над простыми типами
- •Функции
- •Ввод-вывод в стиле с
- •Массивы
- •Варианты индивидуальных заданий
- •Лабораторная работа №2 Указатели. Связь массивов и указателей
- •Понятие указателя
- •Связь между массивами и указателями
- •Динамическое формирование массивов
- •Варианты индивидуальных заданий
- •Лабораторная работа №3 Обработка строк текста
- •Примеры программ
- •Варианты индивидуальных заданий
- •Лабораторная работа №4 Работа с файлами
- •Примеры программ
- •Варианты индивидуальных заданий
- •Заключение
- •Библиографический список
Лабораторная работа №2 Указатели. Связь массивов и указателей
Цели работы:
освоить основные операции с указателями;
научиться выполнять доступ к элементам массива через указатели
Краткие сведения об использовании указателей
Понятие указателя
Указатель – это переменная, в которой хранится адрес памяти. Основные операции при работе с указателями - & и *.
Операция определения адреса & определяет адрес ячейки памяти, содержащей заданную переменную. Например, если v – имя переменной, то &v – указатель на эту переменную (т.е. её адрес).
Операция косвенной адресации (операция разыменования указателя) * позволяет обратиться к значению, на которое указывает указатель. Если p – указатель, то *p – значение, на которое он указывает.
Объявление указателя выполняется следующим образом:
тип * имя_указателя[=инициатор];
Пример:
int a=10, b;
int *ptr = &a; //инициализация указателя адресом переменной a
cout <<“указатель =“<<ptr<<“\nПеременная =”<<*ptr;
*ptr=8;
cout << “Переменная a=” << a << endl; // будет выведено 8
Размер указателя зависит от архитектуры компьютера и используемой модели памяти (обычно 4 байта).
Над указателями могут выполняться некоторые арифметические операции - --, ++, к нему можно прибавить и вычесть целое число, из одного указателя можно вычесть другой. При выполнении арифметических действий с указателями предполагается, что указатель указывает на массив элементов соответствующего типа. При прибавлении к указателю целочисленного значения указатель сдвигается на соответствующее количество элементов.
Например:
int *p;
p+=5;
Если int имеет размер 4 байта, то при прибавлении к указателю числа 5 он сдвигается на 20 байт.
Разность двух указателей представляет собой количество элементов массива, их разделяющих.
Связь между массивами и указателями
В C++ массивы и указатели тесно связаны друг с другом. Имя массива можно рассматривать как указатель-константу на начало массива (адрес первого элемента массива):
int a[10];
int *p=a; //то же самое, если бы мы написали int *p = &a[0]; - адрес первого элемента массива
Наоборот, с указателями можно работать как с массивами - использовать операцию индексирования - []:
p[3]=11; //можно было бы написать *(p+3)=11; , используя смещение вместо индекса
cout << a[3]; //11
Следует не забывать, что имя массива можно рассматривать как указатель-константу, его изменение невозможно.
Динамическое формирование массивов
Для динамического управления памятью используются операции new и delete. Операция new выделяет объём памяти для одного или нескольких объектов указанного типа:
int *i, *j;
i = new int; //выделяет память под один элемент int и возвращает указатель на него
j = new int [50]; // выделяет память под массив из 50 элементов int и возвращает указатель на первый элемент
k = new int [20][30]; //выделяет память под массив 20*30 элементов и возвращает указатель на первый элемент.
Операция delete освобождает захваченную память: delete i;
delete [] j; delete [] k;
Пример программы с использованием указателей
В данном примере динамически формируется массив из N элементов и заполняется с клавиатуры. Если первый элемент массива больше последнего элемента, то они меняются местами. После этого массив выводится на экран.
#include <iostream.h>
void main()
{ int n, *c;
cout<<”количество элементов?”; cin>>n; cin.get();
c=new int[n]; int*p=c;
cout<< ”введите элементы массива”<<endl;
for(;p<c+n;p++) cin>>*p;
if (*c>*(c+n-1))//c+n-1 – адрес последнего элемента
{int temp=*c; *c=*(c+n-1); *(c+n-1)=temp;}
for(p=c;p<c+n;p++) cout<<*p<<’ ‘;
cout<<endl; cin.get();
}