Similar presentations:
Лекция 04_Динамическая память и массивы
1. Динамическая память
12. Статические массивы на С++
Массив — структурированный тип данных, состоящий изфиксированного числа элементов одного типа.
2
3. Описание статических массивов
Описание статических массивовтип имя_переменной [размерность];
размерность — количество элементов в массивеконстанта. Например:
int x[10]; //Описание массива из 10 целых чисел. Первый
//элемент массива имеет индекс 0, последний 9.
float a[20]; //Описание массива из 20 вещественных чисел.
//Первый элемент массива имеет индекс 0, последний 19.
Размерность массива и тип его элементов определяют
объём памяти, который необходим для хранения массива.
const int n=15; //Определена целая положительная
константа.
double B[n]; //Описан массив из 15 вещественных чисел.
3
4. Особенности работы со статистическими массивами
1) При описании статического массива в качестве размерностиможно использовать целое положительное число или
предопределённую константу.
2) Элементы массива в С(С++) нумеруются с НУЛЯ. Первый
элемент всегда имеет номер ноль*, а номер последнего
элемента на единицу меньше заданной при его описании
размерности:
char C[5]; //Описан массив из 5 символов, нумерация от 0 до 4.
3) Статический массив нельзя удалить из памяти, если он уже
не нужен
* Индекс — это смещение относительно начала массива. Так элементы
массива легче адресовать в памяти.
4
5. Инициализация элементов массива
Доступ к каждому элементу массива осуществляется с помощьюиндекса — порядкового номера элемента.
имя_массива [индекс]
Например:
const int n=15; //размер массива задается КОНСТАНТОЙ
double C[n], S;
S=C[0]+C[n-1]; //Сумма первого и последнего элементов массива С.
Массиву, как и любой другой переменной, можно присвоить
начальное значение (инициализировать). Для этого значения
элементов массива нужно перечислить в фигурных скобках через
запятую:
тип имя_переменной[размерность]={элемент_0, элемент_1, ...};
5
6. Пример 1:
float a[6] = { 1.2, ( float ) 3/4, 5./6, 6.1 };Формируется массив из шести вещественных чисел, значения
элементам присваиваются по порядку.
Элементы, значения которых не указаны (в данном случае a[4], a[5]),
обнуляются:
a[0]=1.2, a[1]=(float)3/4, a[2]=5./6, a[3]=6.1, a[4]=0, a[5]=0,
для элементов a[1] и a[2] выполняется преобразование типов.
Можно задавать размер массива количеством элементов в списке
инициализации:
Результат – три инициализированных элемента:
Размер массива nz может быть определен так:
Функция sizeof (аргумент) возвращает размер аргумента в байтах.
6
7. Пример 2: инициализировать с помощью генератора случайных чисел целочисленный и вещественный два массивы
#include <iostream>#include<ctime>// для подключения функций генератора
случайных чисел
using namespace std;
int main()
{
int const na = 5, nb = 7;// размеры массивов а и b
int a[na];// выделение памяти под массив а стеком
double b[nb];// выделение памяти под массив b стеком
srand(0);// создаём базу случайных чисел (целые числа от 0
до RAND_MAX=32768 для Visual Studio)
7
8.
Инициализация с помощью генератора случайныхчисел целочисленного массива
/* инициализируем и выводим на консоль целочисленный
массив,значения элементов которого лежат в интервале
от -10 до +10 */
int mina = -10, maxa = +10;
cout << "\n Array a\n";
for(int i = 0;i<na; i++)
{
a[i] = rand() % (maxa - mina + 1) + mina;//rand()
берёт случайное число из базы
cout << a[i] << '\t';//вывод в строку полученных
элементов
}
cout << endl;// перевод строки
8
9.
Инициализация с помощью генератора случайныхчисел вещественного массива
/* инициализируем и выводим на консоль вещественный массив,
значения элементов которого лежат в интервале от -5,5 до +5,5 */
double bmin = -5.5, bmax = +5.5;
cout << "\n Array b\n";
for (int i = 0; i < nb; i++)
{
b[i] = (double)rand() / RAND_MAX*(bmax - bmin) + bmin;//rand()
// берёт случайное ЦЕЛОЕ число
// из базы, поэтому нужен описатель double, чтобы избежать
// целочисленного деления
cout << b[i] << '\t';//вывод в строку полученных элементов
}
cout << endl;// перевод строки
system("pause");
return 0;
9
10.
Результаты работы программыЕсли вместо табулятора ‘\t’ использовать пробелы “ “, то результаты для
вещественного массива будут выглядеть более понятно
10
11. Динамическая память на С++ Динамические массивы
1112. Способы описания одномерных динамических массивов
int n = 10;int *a = new int[n];
Во второй строке описан указатель на целую величину,
которому присваивается адрес начала непрерывной области
динамической памяти, выделенной с помощью функции new.
Выделяется столько памяти, сколько необходимо для хранения
n величин типа int.
Величина n может быть переменной.
Обнуление памяти при её выделении не происходит:
содержание выделенного блока памяти не инициализируется,
оно остается с неопределенными значениями.
Инициализировать
динамический
помощью списка констант нельзя.
массив
с
12
13. 3-е задание контрольной работы - Результаты вычислений Задания 1 занести в массив и найти в нём первый элемент, который ближе
всего по значению к некоторому наперёдзаданному числу F.
#include <iostream>
#include <cmath>
using namespace std;
float f(float x, int N);// вычисление суммы ряда функции
F(x,N)
// void table(float xn,float xk,float dx, int N);
// Предыдущий вариант
void table(float xn,float xk,float dx, int N, float *&A, int
&NX);// Построение таблицы функции, инициализация массива А,
// вычисление его размера NX
int nearest_value(float *A, int n, float F);// поиск индекса
элемента, ближайшего к F
13
14. Главная программа
int main(){
float *A, xn, xk, dx, F;// указатель для массива
int N, NX, in;
cout<<"Input xn xk dx:"; cin>>xn>>xk>>dx;
cout<<"\n Input number of terms in a series:"; cin>>N;
table (xn, xk, dx, N, A, NX);// по указателю возвращаем значения
элементов массива, по ссылке & его размер.
cout<<"Input F:"; cin>>F;
in=nearest_value(A,NX,F);
cout<< "\n the nearest value to "<<F<< " is A[ "<<in<<" ]="<<A[in]<<
" with x = " <<xn+in*dx<<endl;// нельзя разбивать на строки строковую
константу
system("pause");
return 0;
}
Главная программа имеет линейную структуру
14
15. Дополненная функция table
void table(float xn,float xk,float dx, int N, float *&A, int&Nx)
{
Nx=int((xk-xn)/dx)+1;// определение размера массива
A=new float[Nx]; ;// Выделение памяти по массив
int i=0;
for(float x = xn; x < xk + dx/2; x += dx, i++)
{
float y=f(x,N);
A[i]=y; ;// инициализация элементов массива
cout<<'\t'<<x<<'\t'<<y<<endl;
}
cout<<endl<<endl;
return;
}
Массив доступен вызывающей функции по указателю
15
16. Функция nearest_value
int nearest_value(float *A, int n, float F)// поиск индекса элемента,ближайшего к F
{
int im = 0;// переменная= индекс наиболее близкого к F элемента
double dd, d = abs(A[0] - F);//разность между 1-м элементом массива и
величиной F
for (int i = 1; i < n; i++)// перебираем все элементы массива,
начиная со 2-го
{
dd = abs(A[i] - F);
if (dd < d)
{
d = dd; im = i;
}
}
return im;
}
16
17. Результаты работы программы
1718. Задача: 2. Написать процедуру Mean(X,Y,Amean,Gmean), вычисляющую средне арифметическое Amean =(X+Y)/2 и среднее геометрическое
Задания для самостоятельной работы(рекомендуется попробовать решить самому, потом
проверить решение по следующим слайдам)
Задача: 2. Написать процедуру Mean(X,Y,Amean,Gmean),
вычисляющую средне арифметическое Amean =(X+Y)/2 и
среднее геометрическое Gmean = двух положительных
чисел X, Y. С помощью функции найти среднее
арифметическое и среднее геометрическое для пар (A,B),
(A,C), (A,D), если заданы A,B,C,D.
Задача: 3. Написать функцию DigitCountSum(K, S), находящую
количество цифр целого положительного числа К, а также их сумму
S. Применить процедуру к пяти случайным числам К, содержащим
не менее 5 и не более 9 цифр. Для определения числа цифр в числе
создать соответствующую функцию.
18
19. Решение задачи 1
void Mean(int X, int Y, double &Amean, double &Gmean);using namespace std;
int main()
{
int A, B, C, D;
double Amean,Gmean;
cout<<"Input A B C D: "; cin>>A>>B>>C>>D;
Mean(A,B,Amean,Gmean);
cout<<"for A = "<<A<< " and B = "<<B<<" Amean = "<<Amean<<" Gmean = "<<Gmean<<endl;
cout<<" A = "<<A<<" B= "<<B<<endl;
Mean(A,C,Amean,Gmean);
cout<<"for A = "<<A<< " and C = "<<C<<" Amean = "<<Amean<<" Gmean = "<<Gmean<<endl;
Mean(A,D,Amean,Gmean);
cout<<"for A = "<<A<< " and D = "<<D<<" Amean = "<<Amean<<" Gmean = "<<Gmean<<endl;
return 0;
}
void Mean(int X, int Y, double &Afmean, double &Gfmean)//
// первом вызове X=A=2,Y=B=10
{
Afmean=(X+Y)/2.;
Gfmean=sqrt(X*Y);
X+=4;Y*=3;
return;
}
19
20. Решение задачи 2
#include <iostream>using namespace std;
int DigitCountSum(int K, int &S);
int DigitCount(int K);
int main()
{
int K,Digit_K, SumDigit_K=0;// число К, кол-во цифр в К, сумма цифр
cout<<" Input a pozitive integer number: "; cin>>K;
Digit_K=DigitCountSum(K,SumDigit_K);
cout<<"the number K = "<<K<<" contains "<<Digit_K<<" digits. The sum
of digits equals to "<<SumDigit_K<<endl;
return 0;
}
int DigitCount(int K)
int DigitCountSum(int K, int &S)
{
{
int count=1;
int k, D_K=DigitCount(K);
do{
while(K/=10)//
k=K%10;// выделяем первую цифру
count++;
S+=k;// копим сумму цифр
return count;
}while(K/=10);//убираем из К левую цифру
}
return D_K;
}
20
21. 3. Создать программу для проверки коллинеарности двух n-мерных векторов.
Два вектора коллинеарны (параллельны), еслиотношения их координат равны.
Формальное применение данного определения коллинеарности имеет
существенный минус: условие неприменимо, если одна из компонент
вектора равна нулю. Этот вариант необходимо предусмотреть:
запрограммировать прерывание с соответствующим сообщением.
21
22. Вместо словесного алгоритма прототипы функций
#include <iostream>#include <iomanip>
#include <ctime>
#include <windows.h>
using namespace std;
void vector(int *x,int n, int mn, int mx); //инициализация
вектора случайными числами
void print_vect(int *x, int n);// печать вектора
bool check(int*x, int*y, int n);// проверка коллинеарности
векторов
22
23. Главная программа
int main(){
int n;// размер векторов
bool result;
cout<<"input vector size:"; cin>>n;
int *a= new int[n];
int *b= new int[n];
vector (a,n,-5,5);print_vect(a, n);
vector(b,n,-5,5);print_vect(b, n);
result= check(a,b,n);
if(result) cout<<"\n vectors are
colinear\n";
else cout<<"\n vectors are non colinear\n";
system ("pause");
return 0;
}
23
24. Коды объявленных функций
void vector(int *x,int nx, int mn, int mx){
sleep(1000);//приостановка программы на
1000 миллисекунд
srand((unsigned int)time(0));
for(int i=0; i<nx; i++)
{
x[i] = rand() % (mx – mn + 1) + mn;
if(x[i] == 0)
{cout<<"\n The vector contains a zero
component, \n then the method is not
applicable\n";
system("pause"); exit(1);
}
}
return;
}
24
25. Коды объявленных функций
bool check(int*x, int*y,int n){
float rat=x[1]/y[1];bool res=1;
for(int i=0;i<n;i++)
if((float)x[i]/float(y[i])!=rat)
{res=0.;break;}
return res;
}
if(abs((float)x[i]/float(y[i])-rat)<1e-6)
1e-6=0,000001
5 цифр верных
25
26. Результаты работы программы исчерпывают проверку полноты решения:
2627. Форматированный вывод int printf (const char *format, arg-list)
Строка, на которую указывает format, состоит из объектовдвух различных назначений.
Во-первых, это символы, которые сами должны быть
выведены на экран.
Во-вторых, это спецификаторы формата, определяющие
вид, в котором будут выведены аргументы из списка arg-list.
Спецификаторы формата состоят из символа процент %, за
которым следует код формата.
Команды форматирования приведены в таблице.
Количество аргументов должно точно соответствовать
количеству спецификаторов формата, причем следовать они
должны в одинаковом порядке.
27
28. Форматированный вывод спецификаторы формата
Строка, на которую указывает format, состоит из объектовдвух различных назначений.
Во-первых, это символы, которые сами должны быть
выведены на экран.
Во-вторых, это спецификаторы формата, определяющие
вид, в котором будут выведены аргументы из списка arg-list.
Спецификаторы формата состоят из символа процент %, за
которым следует код формата.
Команды форматирования приведены в таблице.
Количество аргументов должно точно соответствовать
количеству спецификаторов формата, причем следовать они
должны в одинаковом порядке.
28
programming