- •Лабораторная работа №2 Структуры. Указатели.
- •1. Программирование алгоритмов с использованием структур
- •Краткие теоретические сведения
- •Пример на использование структур
- •2. Указатели Теоретические сведения
- •Указатели и операции над адресами
- •Операции над указателями (адресная арифметика)
- •Указатели на указатели
- •Таким образом, указатели на указатели – это имена многомерных массивов.
- •Массивы указателей
- •Динамическое размещение данных
- •Пример использования структуры и указателя
- •Варианты индивидуальных заданий Задание 1.
- •Задание 2.
Динамическое размещение данных
В языке С/С++ есть операция, с помощью которой можно определить размер участка памяти в байтах, который компилятор отводит под массив после его объявления, это операция sizeof. Формат записи:
sizeof(параметр);
параметр – тип объекта или его идентификатор (только не имя функции). Операция sizeof позволяет определить размер объекта по имени или типу, результатом является размер памяти в байтах (тип результата int).
Если указан идентификатор сложного объекта (массив, структура, объединение), то получаем размер всего сложного объекта. Например:
sizeof(int) -> 2 байта,
int b[5]; sizeof(b) -> 10 байт;
int c[3][4]; sizeof(c) -> 24 байта.
Операция sizeof применяется при динамическом распределении памяти:
float *x; // Указатель массива
int n; // Количество элементов массива
x=(float*)calloc(n,sizeof(float)); // Захват и очистка памяти
Прототипы функций работы с памятью находятся в библиотеке alloc.h, рассмотрим основные из них:
void *calloc(unsigned n, unsigned m); - возвращает указатель на начало области памяти для размещения n элементов по m байт каждый, при неудачном завершении возвращает значение NULL;
void *malloc(unsigned n); - возвращает указатель на блок памяти длиной n байт, при неудачном завершении возвращает значение NULL;
void *realloc(void *bf, unsigned n); - изменяет размер ранее выделенной памяти с адресом начала bf на n байт;
void free(void *bf); - освобождает ранее выделенный блок памяти с адресом bf;
coreleft(void); - возвращает значение объема неиспользованной памяти (тип возвращаемого результата unsigned – для моделей памяти tiny, small, medium; unsigned long – для других моделей памяти).
Приведем пример динамического размещения одномерного массива
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<alloc.h>
void main(void)
{ int i,n; float *a;
puts(“\n Input n:”); scanf(“%d”,&n);
printf(“\n Свободная память -%d”,coreleft());
a=(float *)calloc(n,sizeof(float)); // захват памяти
printf(“\n Array a \n”);
for(i=0; i<n; i++) {
*(a+i)=(float)random(10); // диапазон от 0 до 10
printf(“ %d“, a[i]);
}
printf(“\n Память после захвата -%d”,coreleft());
free(a); // освобождение памяти
getch(); }
Пример динамического размещения двумерного массива
. . .
void main(void)
{ int i,j,n,m; float **a;
puts(“\n Input n,m:”); scanf(“%d %d”,&n,%m);
printf(“\n Свободная память -%d”,coreleft());
a=(float **)calloc(n,sizeof(float*)); // захват памяти
for(i=0; i<n; i++)
a[i]=(float *)calloc(m,sizeof(float));
. . .
printf(“\n Память после захвата -%d”,coreleft());
for(i=0; i<n; i++) free(a[i]); // освобождение памяти
free(a);
getch(); }
Пример использования структуры и указателя
Создать структуру макаронные изделия, хранящую информацию о макаронных изделиях, продающихся в данном магазине: наименование, производитель, сорт, информация о наличии. Создать массив таких структур и заполнить его. Создать поиск по сорту изделия: пользователь вводит интересующий его сорт, а программа выводит все изделия этого сорта, имеющиеся в наличии. Все действия со структурой производить с помощью указателя на нее, напрямую к полям структуры обращаться нельзя.
Программа:
//описываем структуру с указанными полями
struct m_izd
{
char name[10];
char firma[10];
int sort;
int nalichie; //информацию о наличии будем хранить в целочисленной переменной, где 1 – товар есть, 0 – товар отсутствует в продаже
};
int main(int argc, char* argv[])
{
const col=20; //число хранимых изделий
m_izd mag2[col]; //массив структур размером, описанным в константе
m_izd *m; //описываем указатель на структуру
for(m=mag2;m<mag2+col;m++) // задаем цикл от адреса начального элемента до адреса последнего массива структур
//заполняем поля структуры, используя указатель
{ cout<<"Vvedite nazvanie izdelija\n";
cin>>m->name;
cout<<"\nVvedite nazvanie proizvoditelja\n";
cin>>m->firma;
cout<<"\nVvedite sort izdelija\n";
cin>>m->sort;
cout<<"\nEst li v nalichii izdelie(1-yes or 0-no)\n";
cin>>m->nalichie;
}
//запрашиваем у пользователя интересующий его сорт изделия
cout<<"\nVvedite interesujushij vas sort\n";
int s;
cin>>s;
for(m=mag2;m<mag2+col;m++)
{if ((m->sort==s)&&(m->nalichie==1)) // при помощи оператора указателя на структуру обращаемся к полям структуры и проверяем соответствие критерию поиска
cout<<"Izdelija "<<s<<" sorta:\t"<<m->name<<"\t"<<m->firma<<"\n";
}