🗊Презентация Указатели и адреса

Нажмите для полного просмотра!
Указатели и адреса, слайд №1Указатели и адреса, слайд №2Указатели и адреса, слайд №3Указатели и адреса, слайд №4Указатели и адреса, слайд №5Указатели и адреса, слайд №6Указатели и адреса, слайд №7Указатели и адреса, слайд №8Указатели и адреса, слайд №9Указатели и адреса, слайд №10Указатели и адреса, слайд №11Указатели и адреса, слайд №12Указатели и адреса, слайд №13Указатели и адреса, слайд №14Указатели и адреса, слайд №15Указатели и адреса, слайд №16Указатели и адреса, слайд №17Указатели и адреса, слайд №18Указатели и адреса, слайд №19Указатели и адреса, слайд №20Указатели и адреса, слайд №21Указатели и адреса, слайд №22Указатели и адреса, слайд №23Указатели и адреса, слайд №24Указатели и адреса, слайд №25Указатели и адреса, слайд №26Указатели и адреса, слайд №27Указатели и адреса, слайд №28Указатели и адреса, слайд №29Указатели и адреса, слайд №30Указатели и адреса, слайд №31Указатели и адреса, слайд №32

Содержание

Вы можете ознакомиться и скачать презентацию на тему Указатели и адреса. Доклад-сообщение содержит 32 слайдов. Презентации для любого класса можно скачать бесплатно. Если материал и наш сайт презентаций Mypresentation Вам понравились – поделитесь им с друзьями с помощью социальных кнопок и добавьте в закладки в своем браузере.

Слайды и текст этой презентации


Слайд 1





Лекция 7
Описание слайда:
Лекция 7

Слайд 2





Указатели и адреса
Каждая переменная в программе – это объект, имеющий имя и значение. По имени можно обратиться к переменной и получить её значение. 
Указатели - это переменные, значениями которых являются адреса других переменных (описывает расположение переменной в машинной памяти). 
Синтаксис: при объявлении указателя используется символ звездочка (*):
                                           ТИП* ИМЯ_УКАЗАТЕЛЯ;
Здесь ТИП это тип переменной, адрес которой может храниться в указателе. 
Пример
Унарный оператор & выдает адрес своего операнда. 
                  double* pd;                                    // pd – указатель на переменную типа double
                   double d = 3.14159;                     // d - переменная типа double
                   pd = &d;                                         // В указатель pd скопирован адрес переменной d
Указатель pd будет содержать адрес переменной d (говорят, что pd указывает или ссылается на d). 
Переменная d типа double занимает 8 байтов памяти, а указатель pd – четыре. Такое количество памяти выделяется под указатели на 32 – разрядных компьютерах.
Описание слайда:
Указатели и адреса Каждая переменная в программе – это объект, имеющий имя и значение. По имени можно обратиться к переменной и получить её значение. Указатели - это переменные, значениями которых являются адреса других переменных (описывает расположение переменной в машинной памяти). Синтаксис: при объявлении указателя используется символ звездочка (*): ТИП* ИМЯ_УКАЗАТЕЛЯ; Здесь ТИП это тип переменной, адрес которой может храниться в указателе. Пример Унарный оператор & выдает адрес своего операнда. double* pd; // pd – указатель на переменную типа double double d = 3.14159; // d - переменная типа double pd = &d; // В указатель pd скопирован адрес переменной d Указатель pd будет содержать адрес переменной d (говорят, что pd указывает или ссылается на d). Переменная d типа double занимает 8 байтов памяти, а указатель pd – четыре. Такое количество памяти выделяется под указатели на 32 – разрядных компьютерах.

Слайд 3





Доступ к объектам через указатели
Для доступа к объекту по его адресу используется унарный оператор раскрытия ссылки “*“ (оператор разадресации).
Пример
                                                          ini x=1,y=2;
                                                          int *p;
                                                          p=&x;                          // теперь p указывает на x
                                                          y=*p;                           // y теперь равен единице
                                                          *p=0;                           // x теперь равен нулю
Приоритет операций.
Операции взятия адреса имеют более высокий приоритет, чем все арифметические операции, поэтому следующие выражения эквивалентны и обозначают увеличение переменно i на единицу (pi=&i).
Описание слайда:
Доступ к объектам через указатели Для доступа к объекту по его адресу используется унарный оператор раскрытия ссылки “*“ (оператор разадресации). Пример ini x=1,y=2; int *p; p=&x; // теперь p указывает на x y=*p; // y теперь равен единице *p=0; // x теперь равен нулю Приоритет операций. Операции взятия адреса имеют более высокий приоритет, чем все арифметические операции, поэтому следующие выражения эквивалентны и обозначают увеличение переменно i на единицу (pi=&i).

Слайд 4





Программа «Работа с указателями»
#include <iostream>
#include <clocale>
#include <cstdlib>
using namespace std;
int main()
{    setlocale(LC_ALL, "Russian");
double* pd;                                                    // Указатель на double
cout << "Адрес указателя pd: &pd = " << &pd << endl;
double d = 3.14159;                                     // Переменная типа double
cout << "Адрес переменной d: &d = " << &d << endl;
pd = &d;                                                         // В указатель pd скопирован адрес переменной d
cout << "Значение указателя pd: pd = " << pd << endl;
cout << "Значение переменной d: d = " << d << endl;
cout << "Значение переменной, на которую указывает pd: *pd = "<< *pd << endl;
*pd = 2.71828;                                             // Изменение переменной d через указатель pd  на нее
cout << "Значение переменной d: d = " << d << endl;
char* pc;                                                       // Указатель на символ
int* pi;                                                            // Указатель на целое
cout << "Размеры указателей:\n";
cout << "sizeof(char*) = " << sizeof(pc) << "\n"<< "sizeof(int*) = " << sizeof(pi) << "\n"<< "sizeof(double*) = " << sizeof(pd) << "\n";
system("pause");    return 0;    }
Описание слайда:
Программа «Работа с указателями» #include <iostream> #include <clocale> #include <cstdlib> using namespace std; int main() { setlocale(LC_ALL, "Russian"); double* pd; // Указатель на double cout << "Адрес указателя pd: &pd = " << &pd << endl; double d = 3.14159; // Переменная типа double cout << "Адрес переменной d: &d = " << &d << endl; pd = &d; // В указатель pd скопирован адрес переменной d cout << "Значение указателя pd: pd = " << pd << endl; cout << "Значение переменной d: d = " << d << endl; cout << "Значение переменной, на которую указывает pd: *pd = "<< *pd << endl; *pd = 2.71828; // Изменение переменной d через указатель pd на нее cout << "Значение переменной d: d = " << d << endl; char* pc; // Указатель на символ int* pi; // Указатель на целое cout << "Размеры указателей:\n"; cout << "sizeof(char*) = " << sizeof(pc) << "\n"<< "sizeof(int*) = " << sizeof(pi) << "\n"<< "sizeof(double*) = " << sizeof(pd) << "\n"; system("pause"); return 0; }

Слайд 5





Указатели как аргументы функций
В C++  аргументы функции передаются по значению, то есть функция получает лишь локальные копии аргументов. Передав функции адреса переменных, можно изменить их значение в вызывающей программе. При этом аргументы должны быть декларированы как указатели.
Если указатель на переменную является аргументом функции, то внутри функции становится известен адрес этой внешней по отношению к функции переменной, что позволяет работать с этой переменной, в том числе изменять ее значение.
Описание слайда:
Указатели как аргументы функций В C++ аргументы функции передаются по значению, то есть функция получает лишь локальные копии аргументов. Передав функции адреса переменных, можно изменить их значение в вызывающей программе. При этом аргументы должны быть декларированы как указатели. Если указатель на переменную является аргументом функции, то внутри функции становится известен адрес этой внешней по отношению к функции переменной, что позволяет работать с этой переменной, в том числе изменять ее значение.

Слайд 6





Программа «Обмен значениями»
#include <iostream>
#include <clocale>
#include <cstdlib>
using namespace std;
void swap1 (int a, int b)
{
	int tmp=a;
	a=b;
	b=tmp;
}
void swap2 (int* a, int* b)
{
	int tmp=*a;
	*a=*b;
	*b=tmp;
}
int main()
{  
	setlocale(LC_ALL, "Russian");
	int a,b;
	cout<<"Введите 2 числа"<<endl;
	cin>>a>>b;
	swap1(a,b);
	cout<<"swap1: a="<<a<<", b="<<b<<endl;
	swap2(&a,&b);
	cout<<"swap2: a="<<a<<", b="<<b<<endl;
	system("pause");    
	return 0;    
}
Описание слайда:
Программа «Обмен значениями» #include <iostream> #include <clocale> #include <cstdlib> using namespace std; void swap1 (int a, int b) { int tmp=a; a=b; b=tmp; } void swap2 (int* a, int* b) { int tmp=*a; *a=*b; *b=tmp; } int main() { setlocale(LC_ALL, "Russian"); int a,b; cout<<"Введите 2 числа"<<endl; cin>>a>>b; swap1(a,b); cout<<"swap1: a="<<a<<", b="<<b<<endl; swap2(&a,&b); cout<<"swap2: a="<<a<<", b="<<b<<endl; system("pause"); return 0; }

Слайд 7





Программа «Расчет треугольника»
Пусть требуется вычислить периметр и площадь треугольника по трем его сторонам a, b, c. Напишем для этого функцию triangle(). 
Так как треугольник существует не для любых значений длин сторон, функция должна как-то информировать об этом. Пусть она будет возвращать true, если для заданных длин сторон треугольник существует, и false, если не существует. Две остальные величины – периметр и площадь – будем возвращать из функции через аргументы, имеющее тип указателя.
Вычисления можно проводить по формулам:
Описание слайда:
Программа «Расчет треугольника» Пусть требуется вычислить периметр и площадь треугольника по трем его сторонам a, b, c. Напишем для этого функцию triangle(). Так как треугольник существует не для любых значений длин сторон, функция должна как-то информировать об этом. Пусть она будет возвращать true, если для заданных длин сторон треугольник существует, и false, если не существует. Две остальные величины – периметр и площадь – будем возвращать из функции через аргументы, имеющее тип указателя. Вычисления можно проводить по формулам:

Слайд 8





Программа «Расчет треугольника»
#include <iostream>
#include <cmath>
#include <clocale>
#include <cstdlib>
using namespace std;
// triangle: вычисление периметра и площади треугольника. Возвращает true, если треугольник существует и false 
// если не существует.  a, b, c - стороны треугольника, p_perim - указатель на переменную для периметра
// p_area - указатель на переменную для площади
bool triangle(double a, double b, double c, double* p_perim, double* p_area)
{    if(a > b + c || b > a + c || c > a + b)       // Проверка существования треугольника
           return false;                                         // Треугольник не существует, выход из функции
     double p = (a + b + c) / 2.0;                     // Полупериметр
    *p_perim = p * 2.0;                                    // Периметр
    *p_area = sqrt(p * (p - a) * (p - b) * (p - c)); // Площадь
     return true;   }
int main()
{   setlocale(LC_ALL, "Russian");
double r, s, t, P, A; // Стороны треугольника, периметр и площадь
cout << "Введите три стороны треугольника: ";
cin >> r >> s >> t;
if( triangle(r, s, t, &P, &A) == false )
cout << "Такого треугольника не существует\n";
else
cout << "Периметр: " << P << ", площадь: " << A << "\n";
system("pause");   return 0;   }
Описание слайда:
Программа «Расчет треугольника» #include <iostream> #include <cmath> #include <clocale> #include <cstdlib> using namespace std; // triangle: вычисление периметра и площади треугольника. Возвращает true, если треугольник существует и false // если не существует. a, b, c - стороны треугольника, p_perim - указатель на переменную для периметра // p_area - указатель на переменную для площади bool triangle(double a, double b, double c, double* p_perim, double* p_area) { if(a > b + c || b > a + c || c > a + b) // Проверка существования треугольника return false; // Треугольник не существует, выход из функции double p = (a + b + c) / 2.0; // Полупериметр *p_perim = p * 2.0; // Периметр *p_area = sqrt(p * (p - a) * (p - b) * (p - c)); // Площадь return true; } int main() { setlocale(LC_ALL, "Russian"); double r, s, t, P, A; // Стороны треугольника, периметр и площадь cout << "Введите три стороны треугольника: "; cin >> r >> s >> t; if( triangle(r, s, t, &P, &A) == false ) cout << "Такого треугольника не существует\n"; else cout << "Периметр: " << P << ", площадь: " << A << "\n"; system("pause"); return 0; }

Слайд 9





Взаимодействие формальных параметров и фактических аргументов функции triangle()
При вызове функции triangle() формальные параметры a, b, c получают значения фактических аргументов r, s, t. Размеры прямоугольников p_perim, p_area в два раза меньше, чем размеры прямоугольников a, b, c, так как a, b, c имеют тип double размером 8 байт, а указатели p_perim, p_area имеют размер 4 байта. Формальные параметры p_perim, p_area получают значения адресов внешних переменных P и A.
Описание слайда:
Взаимодействие формальных параметров и фактических аргументов функции triangle() При вызове функции triangle() формальные параметры a, b, c получают значения фактических аргументов r, s, t. Размеры прямоугольников p_perim, p_area в два раза меньше, чем размеры прямоугольников a, b, c, так как a, b, c имеют тип double размером 8 байт, а указатели p_perim, p_area имеют размер 4 байта. Формальные параметры p_perim, p_area получают значения адресов внешних переменных P и A.

Слайд 10





Указатели и массивы
Задан целочисленный массив из 10 элементов , то есть блок из 10 расположенных последовательно переменных целого типа с именами a[0], a[1], …, a[9].
int a[10];
int *pi;         //  определен указатель на целое число
pi = &a[0];   // указатель pi будет содержать адрес первого элемента массива a
По определению, pi + 1 указывает на следующий элемент массива, pi + i указывает на i-й элемент после pi, pi - i указывает на i-й элемент перед pi.  Таким образом, имея указатель на начало массива, можно получить доступ к любому его элементу, например, *pi есть первый элемент массива, *(pi + 1) – второй и т.д. Присваивание
                                         *(pi + 1) = 0;        // a[1] = 0
обнуляет второй элемент массива, номер которого равен 1.
Описание слайда:
Указатели и массивы Задан целочисленный массив из 10 элементов , то есть блок из 10 расположенных последовательно переменных целого типа с именами a[0], a[1], …, a[9]. int a[10]; int *pi; // определен указатель на целое число pi = &a[0]; // указатель pi будет содержать адрес первого элемента массива a По определению, pi + 1 указывает на следующий элемент массива, pi + i указывает на i-й элемент после pi, pi - i указывает на i-й элемент перед pi. Таким образом, имея указатель на начало массива, можно получить доступ к любому его элементу, например, *pi есть первый элемент массива, *(pi + 1) – второй и т.д. Присваивание *(pi + 1) = 0; // a[1] = 0 обнуляет второй элемент массива, номер которого равен 1.

Слайд 11





Указатели и массивы
По определению, имя массива имеет значение адреса первого элемента массива, соответственно имя массива имеет тип указателя на элемент массива. 
Пример: a имеет тип int* (указатель на целое).  Доступ к i - му элементу массива можно получить, используя индексацию a[i] или выражение 
*(a + i).
Указатель – это переменная, которой можно присваивать различные значения.
Пример:
pi = a + 1;     //  Теперь pi указывает на второй элемент массива a.
Имя массива является константой, так как содержит адрес конкретного участка памяти, и записи типа a = pi; a++ недопустимы.
Вывод: значение имени массива изменить нельзя, во всем остальном имя массива подобно указателю.
Пусть:
                  pi=a;
Эквивалентные выражения:
Описание слайда:
Указатели и массивы По определению, имя массива имеет значение адреса первого элемента массива, соответственно имя массива имеет тип указателя на элемент массива. Пример: a имеет тип int* (указатель на целое). Доступ к i - му элементу массива можно получить, используя индексацию a[i] или выражение *(a + i). Указатель – это переменная, которой можно присваивать различные значения. Пример: pi = a + 1; // Теперь pi указывает на второй элемент массива a. Имя массива является константой, так как содержит адрес конкретного участка памяти, и записи типа a = pi; a++ недопустимы. Вывод: значение имени массива изменить нельзя, во всем остальном имя массива подобно указателю. Пусть: pi=a; Эквивалентные выражения:

Слайд 12





Различия между указателем и массивом
Указатель – это переменная, а имя массива это константа, равная адресу элемента с индексом 0.
                                                int *pi, a[10];
                                                pi=a;          // допустимо
                                                pi++;         // допустимо
                                                a=pi;         // не допустимо
                                                a++;          // не допустимо
Это связано с различием в выделении памяти. Память под массив выделяется при его определении, расположение массива в памяти фиксировано. При определении указателя память отводится только для хранения адреса.
Описание слайда:
Различия между указателем и массивом Указатель – это переменная, а имя массива это константа, равная адресу элемента с индексом 0. int *pi, a[10]; pi=a; // допустимо pi++; // допустимо a=pi; // не допустимо a++; // не допустимо Это связано с различием в выделении памяти. Память под массив выделяется при его определении, расположение массива в памяти фиксировано. При определении указателя память отводится только для хранения адреса.

Слайд 13





Адресная арифметика
1) Указателям можно присваивать значение другого указателя такого же типа.
2) К указателям можно прибавлять и вычитать целые числа (сдвиг указателя).
Если p – указатель на некоторый элемент массива, то выражение p++ или ++p изменяет p так, чтобы он указывал на следующий элемент массива, а выражение p-- или --p переводит указатель на предыдущий элемент массива. Выражение p += i изменяет p так, чтобы он указывал на i - й элемент, после того, на который он указывал ранее.
3) Из одного указателя можно вычесть значение другого указателя, если они ссылаются на элементы одного и того массива.
Если p и q указывают на элементы одного и того же массива и p < q, то
 q - p есть число элементов от p до q.
Описание слайда:
Адресная арифметика 1) Указателям можно присваивать значение другого указателя такого же типа. 2) К указателям можно прибавлять и вычитать целые числа (сдвиг указателя). Если p – указатель на некоторый элемент массива, то выражение p++ или ++p изменяет p так, чтобы он указывал на следующий элемент массива, а выражение p-- или --p переводит указатель на предыдущий элемент массива. Выражение p += i изменяет p так, чтобы он указывал на i - й элемент, после того, на который он указывал ранее. 3) Из одного указателя можно вычесть значение другого указателя, если они ссылаются на элементы одного и того массива. Если p и q указывают на элементы одного и того же массива и p < q, то q - p есть число элементов от p до q.

Слайд 14





Адресная арифметика
4) Указателям можно присваивать значение, равно нулю, либо сравнивать на равенство с нулём (NULL).
Если значение указателя равно нулю, это трактуется так, что указатель никуда не указывает.
5) К указателям, ссылающимся на элементы одного и того же массива, можно применить операции сравнения (==, !=, <, <=, >, >=).
Выражение p < q истинно, если p указывает на более ранний элемент массива, чем q.
Описание слайда:
Адресная арифметика 4) Указателям можно присваивать значение, равно нулю, либо сравнивать на равенство с нулём (NULL). Если значение указателя равно нулю, это трактуется так, что указатель никуда не указывает. 5) К указателям, ссылающимся на элементы одного и того же массива, можно применить операции сравнения (==, !=, <, <=, >, >=). Выражение p < q истинно, если p указывает на более ранний элемент массива, чем q.

Слайд 15





Программа «Массивы и указатели»
#include <iostream>
#include <locale>
using namespace std;
int main()
{  setlocale(LC_ALL, "Russian");
int a[10], *p, *q;                                      // Массив и два указателя
for (int i = 0; i < 10; i++)
	a[i] = i;
p = &a[0];                                              // Указатель на первый элемент массива, можно p = a;
cout << "Значение имени массива a = " << a << endl<< "Значение указателя p = " << p << endl;
cout << "Элементы массива:\n"<< "Использование индексации:\n";
for (int i = 0; i < 10; i++)
	cout << a[i] << " ";
cout << "\nИспользование имени массива:\n";
for (int i = 0; i < 10; i++)
	cout << *(a + i) << " ";
cout << "\nИспользование указателя:\n";
for (int i = 0; i < 10; i++)
	cout << *(p + i) << " ";
q = &a[9];                                             // Указатель на последний элемент массива
cout << "\np = " << p << ", q = " << q << ", q - p = " << (q - p)<< "\nint(q) - int(p) = " << (int(q) - int(p));
++p; --q;                                               // Изменение указателей
cout << "\n++p = " << p << ", --q = " << q << ", q - p = " << q - p;
cin.get();    return 0;   }
Описание слайда:
Программа «Массивы и указатели» #include <iostream> #include <locale> using namespace std; int main() { setlocale(LC_ALL, "Russian"); int a[10], *p, *q; // Массив и два указателя for (int i = 0; i < 10; i++) a[i] = i; p = &a[0]; // Указатель на первый элемент массива, можно p = a; cout << "Значение имени массива a = " << a << endl<< "Значение указателя p = " << p << endl; cout << "Элементы массива:\n"<< "Использование индексации:\n"; for (int i = 0; i < 10; i++) cout << a[i] << " "; cout << "\nИспользование имени массива:\n"; for (int i = 0; i < 10; i++) cout << *(a + i) << " "; cout << "\nИспользование указателя:\n"; for (int i = 0; i < 10; i++) cout << *(p + i) << " "; q = &a[9]; // Указатель на последний элемент массива cout << "\np = " << p << ", q = " << q << ", q - p = " << (q - p)<< "\nint(q) - int(p) = " << (int(q) - int(p)); ++p; --q; // Изменение указателей cout << "\n++p = " << p << ", --q = " << q << ", q - p = " << q - p; cin.get(); return 0; }

Слайд 16





Массивы как аргументы функции
Почему, когда массив является аргументом функции, он не копируется внутрь функции?
Массив в языке C++ является понятием низкого уровня. Во многих случаях массив теряет информацию о своём размере. При использовании массива в качестве аргументов функции передаётся только его базовый адрес:
Пусть объявлена функция с аргументом – массивом:
                                                 void f(char s[]);
Так как имя массива – это указатель на первый элемент массива, то данное объявление эквивалентно такому:
                                                         void f(char* s);
То есть, внутри функции создается копия указателя на первый элемент массива и принцип передачи аргументов по значению остается в силе.
Элементы массива не копируются внутрь функции. Используя адрес первого элемента массива, можно внутри функции получить доступ к любому элементу массива и изменить его. Таким образом, если массив является аргументом функции, его элементы можно изменить внутри функции.
Описание слайда:
Массивы как аргументы функции Почему, когда массив является аргументом функции, он не копируется внутрь функции? Массив в языке C++ является понятием низкого уровня. Во многих случаях массив теряет информацию о своём размере. При использовании массива в качестве аргументов функции передаётся только его базовый адрес: Пусть объявлена функция с аргументом – массивом: void f(char s[]); Так как имя массива – это указатель на первый элемент массива, то данное объявление эквивалентно такому: void f(char* s); То есть, внутри функции создается копия указателя на первый элемент массива и принцип передачи аргументов по значению остается в силе. Элементы массива не копируются внутрь функции. Используя адрес первого элемента массива, можно внутри функции получить доступ к любому элементу массива и изменить его. Таким образом, если массив является аргументом функции, его элементы можно изменить внутри функции.

Слайд 17





Программа «Сортировка массива»
Сортировкой называется упорядочение массива по возрастанию или убыванию.
Реализуемые функции: функция заполнения массива; функции вывода массива на экран; функция сортировки массива.
Вспомогательные действия:
1) Размер массива задается константой SIZEARR достаточно большого размера, чтобы выделенной под массив памяти хватило в большинстве случаев использования программы.
2) При вводе недопустимого размера массива вызывается библиотечная функция void exit(int k), которая завершает работу программы и передает в вызывающую программу значение своего аргумента k. Эта функция объявлена в stdlib.h.
3) Массив x заполняется случайными числами. Случайные целые числа из диапазона от 0 до RAND_MAX генерируется функцией стандартной библиотеки int rand(), объявленной в cstdlib. Величина RAND_MAX (обычно 32767) определена в файле cstdlib.
Функция void srand(unsigned int seed); (объявлена в сstdlib) настраивает генератор случайных чисел, используя для формирования первого псевдослучайного числа параметр seed. Чтобы получать при каждом запуске программы разную последовательности случайных чисел, функцию srand() следует вызывать с разными аргументами. В программе функции srand() передается число секунд, прошедших от 1 января 1970 г., возвращаемое функцией time(0) (объявлена в time.h).
Описание слайда:
Программа «Сортировка массива» Сортировкой называется упорядочение массива по возрастанию или убыванию. Реализуемые функции: функция заполнения массива; функции вывода массива на экран; функция сортировки массива. Вспомогательные действия: 1) Размер массива задается константой SIZEARR достаточно большого размера, чтобы выделенной под массив памяти хватило в большинстве случаев использования программы. 2) При вводе недопустимого размера массива вызывается библиотечная функция void exit(int k), которая завершает работу программы и передает в вызывающую программу значение своего аргумента k. Эта функция объявлена в stdlib.h. 3) Массив x заполняется случайными числами. Случайные целые числа из диапазона от 0 до RAND_MAX генерируется функцией стандартной библиотеки int rand(), объявленной в cstdlib. Величина RAND_MAX (обычно 32767) определена в файле cstdlib. Функция void srand(unsigned int seed); (объявлена в сstdlib) настраивает генератор случайных чисел, используя для формирования первого псевдослучайного числа параметр seed. Чтобы получать при каждом запуске программы разную последовательности случайных чисел, функцию srand() следует вызывать с разными аргументами. В программе функции srand() передается число секунд, прошедших от 1 января 1970 г., возвращаемое функцией time(0) (объявлена в time.h).

Слайд 18





Функция заполнения массива из n элементов
// get_array: заполняет массив y случайными числами
void get_array(int* y, int n)
{
srand((unsigned) time(NULL)); // Инициализация генератора случайных чисел
for(int i = 0; i < n; i++)
	y[i] = rand();           // rand() генерирует целое случайное число
}
Функция вывода массива на экран
// prn_array: вывод массива
void prn_array(int* y, int n)
{
for(int i = 0; i < n; i++)
	cout << y[i] << " ";
}
Описание слайда:
Функция заполнения массива из n элементов // get_array: заполняет массив y случайными числами void get_array(int* y, int n) { srand((unsigned) time(NULL)); // Инициализация генератора случайных чисел for(int i = 0; i < n; i++) y[i] = rand(); // rand() генерирует целое случайное число } Функция вывода массива на экран // prn_array: вывод массива void prn_array(int* y, int n) { for(int i = 0; i < n; i++) cout << y[i] << " "; }

Слайд 19





Функция сортировки массива методом пузырька
Алгоритм. Организуется проход по массиву, в котором сравниваются соседние элементы. Если предшествующий элемент оказывается больше следующего, они и меняются местами. В результате первого прохода наибольший элемент оказывается на своем, последнем месте («всплывает»). Затем проход по массиву повторяется до предпоследнего элемента, затем до третьего с конца массива и т.д. В последнем проходе по массиву сравниваются только первый и второй элементы.
// bubble_sort: сортировка массива y методом пузырька
void bubble_sort(int * y, int n)
{      for(int i = n - 1; i > 0; i--)                  // i задает верхнюю границу
               for(int j = 0; j < i; j++)   // Цикл сравнений соседних элементов
                         if(y[j] > y[j + 1])                 // Если нет порядка,
                               { int tmp = y[j];            // перестановка местами
                                  y[j] = y[j + 1];             // соседних
                                  y[j + 1] = tmp;  }         // элементов
}
Описание слайда:
Функция сортировки массива методом пузырька Алгоритм. Организуется проход по массиву, в котором сравниваются соседние элементы. Если предшествующий элемент оказывается больше следующего, они и меняются местами. В результате первого прохода наибольший элемент оказывается на своем, последнем месте («всплывает»). Затем проход по массиву повторяется до предпоследнего элемента, затем до третьего с конца массива и т.д. В последнем проходе по массиву сравниваются только первый и второй элементы. // bubble_sort: сортировка массива y методом пузырька void bubble_sort(int * y, int n) { for(int i = n - 1; i > 0; i--) // i задает верхнюю границу for(int j = 0; j < i; j++) // Цикл сравнений соседних элементов if(y[j] > y[j + 1]) // Если нет порядка, { int tmp = y[j]; // перестановка местами y[j] = y[j + 1]; // соседних y[j + 1] = tmp; } // элементов }

Слайд 20





Программа «Сортировка массива»
#include <iostream>
#include <cstdlib>                       // Для exit(), rand()
#include <time.h>                        // Для time()
using namespace std;
// Объявления функций
void get_array(int[], int n);                                         // Заполнение массива из n элементов
void bubble_sort(int[], int n);                                     // Сортировка массива методом пузырька
void prn_array(int[], int n);                                          // Вывод массива
int main()
{   setlocale(LC_ALL, "Russian");
const int SIZEARR = 500;                                               // Максимальный размер массива
int x[SIZEARR], n;                                                           // Массив и размер массива
cout << "Введите размер массива < " << SIZEARR << ": ";
cin >> n;
if(n > SIZEARR || n <= 0){                                             // Проверка размера
	cout << "Размер массива " << n<< " недопустим " << endl;
	system("pause");   exit(1);     }                // Завершение программы
get_array(x, n);                                                              // Заполнение массива
cout << "Исходный массив: \n";
prn_array(x, n);                                                            // Вывод исходного массива
bubble_sort(x, n);                                                        // Сортировка
cout << "\nОтсортированный массив: \n";
prn_array(x, n);                                                           // Вывод упорядоченного массива
cout << endl;   system("pause");    return 0;  }
Описание слайда:
Программа «Сортировка массива» #include <iostream> #include <cstdlib> // Для exit(), rand() #include <time.h> // Для time() using namespace std; // Объявления функций void get_array(int[], int n); // Заполнение массива из n элементов void bubble_sort(int[], int n); // Сортировка массива методом пузырька void prn_array(int[], int n); // Вывод массива int main() { setlocale(LC_ALL, "Russian"); const int SIZEARR = 500; // Максимальный размер массива int x[SIZEARR], n; // Массив и размер массива cout << "Введите размер массива < " << SIZEARR << ": "; cin >> n; if(n > SIZEARR || n <= 0){ // Проверка размера cout << "Размер массива " << n<< " недопустим " << endl; system("pause"); exit(1); } // Завершение программы get_array(x, n); // Заполнение массива cout << "Исходный массив: \n"; prn_array(x, n); // Вывод исходного массива bubble_sort(x, n); // Сортировка cout << "\nОтсортированный массив: \n"; prn_array(x, n); // Вывод упорядоченного массива cout << endl; system("pause"); return 0; }

Слайд 21





Символьные указатели
Для работы со строками символов часто используются указатели на char. 
                                                         char* pc;
Строковая константа, написанная в виде "Я строка", есть массив символов с нулевым символом '\0' на конце. Адрес начала массива, в котором расположена строковая константа, можно присвоить указателю:
                                                      pc = "Я строка";
Здесь копируется только адрес начала строки, сами символы строки не копируются.
Указатель на строку можно использовать там, где требуются строки.
           cout << pc << " длиной " << strlen(pc) << " символов";
Будет напечатано:   «Я строка длиной 8 символов».
Замечания:
1) При подсчете символов строки учитываются и пробелы, а завершающий символ '\0' не учитывается.
2) В отличие от указателей других типов, при выводе символьных указателей выводится не адрес, хранящийся в указателе, а строка символов, на которую указывает указатель.
Описание слайда:
Символьные указатели Для работы со строками символов часто используются указатели на char. char* pc; Строковая константа, написанная в виде "Я строка", есть массив символов с нулевым символом '\0' на конце. Адрес начала массива, в котором расположена строковая константа, можно присвоить указателю: pc = "Я строка"; Здесь копируется только адрес начала строки, сами символы строки не копируются. Указатель на строку можно использовать там, где требуются строки. cout << pc << " длиной " << strlen(pc) << " символов"; Будет напечатано: «Я строка длиной 8 символов». Замечания: 1) При подсчете символов строки учитываются и пробелы, а завершающий символ '\0' не учитывается. 2) В отличие от указателей других типов, при выводе символьных указателей выводится не адрес, хранящийся в указателе, а строка символов, на которую указывает указатель.

Слайд 22





Программа «Длина строки»
#include <iostream>
#include <cstdlib>     
#include <locale>
using namespace std;
int strlen1 (char*s)
     {
        int n;
        for (n=0; *s!='\0'; s++)
          n++;
        return n;
     }
int strlen2 (char*s)
     {
        char *t=s;
        while (*s!='\0')
          s++;
        return s-t;
     }
Описание слайда:
Программа «Длина строки» #include <iostream> #include <cstdlib> #include <locale> using namespace std; int strlen1 (char*s) { int n; for (n=0; *s!='\0'; s++) n++; return n; } int strlen2 (char*s) { char *t=s; while (*s!='\0') s++; return s-t; }

Слайд 23





Выделение и освобождение динамической памяти под переменную
Оператор new выделяет память под объект во время выполнения программы.
Пример:
            double* pd;        // pd - указатель на double, его значение не определено
Инструкция:
            pd = new double;
выделяет память под переменную типа double, адрес которой присваивается pd. После оператора new указывается тип создаваемого объекта. Теперь динамически созданную переменную можно использовать.
          *pd = sqrt(3.0);             // Размещение в памяти значения
           cout << *pd;                 // Печать значения
Оператор delete освобождает память, выделенную ранее оператором new.
Пример:
           delete pd;
Теперь указатель pd можно использовать для других целей, а память, освобожденная оператором delete, может быть повторно использована под объекты, создаваемые оператором new.
Описание слайда:
Выделение и освобождение динамической памяти под переменную Оператор new выделяет память под объект во время выполнения программы. Пример: double* pd; // pd - указатель на double, его значение не определено Инструкция: pd = new double; выделяет память под переменную типа double, адрес которой присваивается pd. После оператора new указывается тип создаваемого объекта. Теперь динамически созданную переменную можно использовать. *pd = sqrt(3.0); // Размещение в памяти значения cout << *pd; // Печать значения Оператор delete освобождает память, выделенную ранее оператором new. Пример: delete pd; Теперь указатель pd можно использовать для других целей, а память, освобожденная оператором delete, может быть повторно использована под объекты, создаваемые оператором new.

Слайд 24





Выделение и освобождение динамической памяти под массивы
Динамические массивы можно создавать оператором new[].
Пример:
char* s = new char[80]; // Создается динамический массив из 80 символов
Для удаления динамических массивов служит оператор delete[].
Пример:
delete[] s;      // Освобождение памяти, на которую указывает s
Замечания:
1) При освобождении памяти, выделенной оператором new, операторы delete и delete[] должны иметь возможность определять размер удаляемого объекта. Это обеспечивается тем, что под динамический объект памяти выделяется больше, чем под статический, обычно на одно слово, в котором хранится размер объекта.
2) С помощью оператора new[] можно создавать массивы, размер которых определяется в ходе работы программы.
Описание слайда:
Выделение и освобождение динамической памяти под массивы Динамические массивы можно создавать оператором new[]. Пример: char* s = new char[80]; // Создается динамический массив из 80 символов Для удаления динамических массивов служит оператор delete[]. Пример: delete[] s; // Освобождение памяти, на которую указывает s Замечания: 1) При освобождении памяти, выделенной оператором new, операторы delete и delete[] должны иметь возможность определять размер удаляемого объекта. Это обеспечивается тем, что под динамический объект памяти выделяется больше, чем под статический, обычно на одно слово, в котором хранится размер объекта. 2) С помощью оператора new[] можно создавать массивы, размер которых определяется в ходе работы программы.

Слайд 25





Программа «Выделение и освобождение памяти»
#include <iostream>
#include <clocale>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
// get_array: заполнение массива y случайными числами
void get_array(int* y, int n) // n – размер массива
{ for (int i = 0; i < n; i++)
    y[i] = rand(); } // rand() генерирует целое случайное число
// prn_array: вывод массива
void prn_array(int* y, int n)
{   for (int i = 0; i < n; i++)
       cout << y[i] << " ";   }
int main()
{  
setlocale(LC_ALL, "Russian");
double* pd = 0; // Указатель на double
pd = new double; // Выделение памяти
cout << "Адрес(pd) = " << pd << ", значение(*pd) = " << *pd;
*pd = sqrt(3.0); // Занесение в память значения
cout << "\nАдрес(pd) = " << pd << ", значение(*pd) = " << *pd;
delete pd; pd = 0; // Освобождение памяти
int *pi_1 = 0, *pi_2 = 0, *pi_3 = 0; // Указатели на целое
int size1, size2, size3; // Размеры динамических массивов
Описание слайда:
Программа «Выделение и освобождение памяти» #include <iostream> #include <clocale> #include <cstdlib> #include <ctime> #include <cmath> using namespace std; // get_array: заполнение массива y случайными числами void get_array(int* y, int n) // n – размер массива { for (int i = 0; i < n; i++) y[i] = rand(); } // rand() генерирует целое случайное число // prn_array: вывод массива void prn_array(int* y, int n) { for (int i = 0; i < n; i++) cout << y[i] << " "; } int main() { setlocale(LC_ALL, "Russian"); double* pd = 0; // Указатель на double pd = new double; // Выделение памяти cout << "Адрес(pd) = " << pd << ", значение(*pd) = " << *pd; *pd = sqrt(3.0); // Занесение в память значения cout << "\nАдрес(pd) = " << pd << ", значение(*pd) = " << *pd; delete pd; pd = 0; // Освобождение памяти int *pi_1 = 0, *pi_2 = 0, *pi_3 = 0; // Указатели на целое int size1, size2, size3; // Размеры динамических массивов

Слайд 26





Программа «Копия строки»
#include <iostream>
#include <clocale>
#include <cstdlib>
#include <string>
using namespace std;
char * copy (char *s)
  {
    char* s1=new char [strlen(s)+1]; // размерность массива trlen(s)+1, так как функция strlen     
                                    //не учитывает символ ‘\0’ в длине
    strcpy (s1,s);
    return s1;                     // Возвращаеи адрес выделенного участка
  }
int main()
{   setlocale(LC_ALL, "Russian");
char s1[20],*s2;  // Массив под строку и указатель под дубликат
cout<<"Введите строку:"<<endl;
cin.getline(s1,20);
s2=copy(s1);
cout<<"Копия строки длины  "<<strlen(s2)<<endl<<s2<<endl;
system("pause");  return 0;  }
Описание слайда:
Программа «Копия строки» #include <iostream> #include <clocale> #include <cstdlib> #include <string> using namespace std; char * copy (char *s) { char* s1=new char [strlen(s)+1]; // размерность массива trlen(s)+1, так как функция strlen //не учитывает символ ‘\0’ в длине strcpy (s1,s); return s1; // Возвращаеи адрес выделенного участка } int main() { setlocale(LC_ALL, "Russian"); char s1[20],*s2; // Массив под строку и указатель под дубликат cout<<"Введите строку:"<<endl; cin.getline(s1,20); s2=copy(s1); cout<<"Копия строки длины "<<strlen(s2)<<endl<<s2<<endl; system("pause"); return 0; }

Слайд 27





Утечка памяти
При работе с динамической памятью следует быть внимательным, чтобы не допустить ситуации, когда память выделяется динамически, но не освобождается, когда необходимость в ней отпадает, что приводит к уменьшению доступной свободной памяти. Это явление называют «утечка памяти».
Пример:
В программе в бесконечном цикле вызывается функция f(), которая при каждом вызове создает массив из 10 миллионов целых чисел, то есть запрашивает 4 107 байт памяти.
Замечание:
Следует знать, что захват одной программой большого объема памяти может замедлить выполнение других программ.
Описание слайда:
Утечка памяти При работе с динамической памятью следует быть внимательным, чтобы не допустить ситуации, когда память выделяется динамически, но не освобождается, когда необходимость в ней отпадает, что приводит к уменьшению доступной свободной памяти. Это явление называют «утечка памяти». Пример: В программе в бесконечном цикле вызывается функция f(), которая при каждом вызове создает массив из 10 миллионов целых чисел, то есть запрашивает 4 107 байт памяти. Замечание: Следует знать, что захват одной программой большого объема памяти может замедлить выполнение других программ.

Слайд 28





Утечка памяти
#include <iostream>
using namespace std;
void f()
{
// Создание массива из 10 миллионов целых
int* pi = new int[1024 * 1024 * 1024];
}
int main()
{
for(int i = 1; ; ++i){ // Бесконечный цикл
f();
cout << i << ' ';
}
}
Описание слайда:
Утечка памяти #include <iostream> using namespace std; void f() { // Создание массива из 10 миллионов целых int* pi = new int[1024 * 1024 * 1024]; } int main() { for(int i = 1; ; ++i){ // Бесконечный цикл f(); cout << i << ' '; } }

Слайд 29





Массивы указателей
Указатели, как и любые другие переменные, можно группировать в массивы. 
Удобно, например, использовать массив символьных указателей при работе с несколькими строками, которые могут иметь различную длину.
Пример:
Программа предлагает ввести номер месяца и выводит его название. Для доступа к строкам с названиями месяцев используется массив символьных указателей.
Описание слайда:
Массивы указателей Указатели, как и любые другие переменные, можно группировать в массивы. Удобно, например, использовать массив символьных указателей при работе с несколькими строками, которые могут иметь различную длину. Пример: Программа предлагает ввести номер месяца и выводит его название. Для доступа к строкам с названиями месяцев используется массив символьных указателей.

Слайд 30





Программа «Названия месяцев»
#include <iostream>
#include <clocale>
#include <cstdlib>     
using namespace std;
int main()
{    setlocale(LC_ALL, "Russian");
char* pmn[] = { // Массив указателей
"Неверный номер месяца", "Январь", "Февраль", "Март",
"Апрель", "Май", "Июнь", "Июль", "Август",
"Сентябрь", "Октябрь", "Ноябрь", "Декабрь " };
int month; // Номер месяца
cout << "Введите номер месяца: ";
cin >> month;
if (0 < month && month <= 12)
cout << "Это " << pmn[month] << endl;
else
cout << pmn[0] << endl;
system("pause");
return 0;  }
Описание слайда:
Программа «Названия месяцев» #include <iostream> #include <clocale> #include <cstdlib> using namespace std; int main() { setlocale(LC_ALL, "Russian"); char* pmn[] = { // Массив указателей "Неверный номер месяца", "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь " }; int month; // Номер месяца cout << "Введите номер месяца: "; cin >> month; if (0 < month && month <= 12) cout << "Это " << pmn[month] << endl; else cout << pmn[0] << endl; system("pause"); return 0; }

Слайд 31





Программа «Ввод и сортировка строк»
#include <iostream>
#include <clocale>
#include <cstdlib>     
using namespace std;
int main()
{    
	setlocale(LC_ALL, "Russian");
	char* pmn[100];    // Массив указателей на строки
	char tmp [100];    // текущая  строка
	int n=0;     // Количество строк
	while(!cin.eof())  // Пока не конец потока
	{
		cin.getline(tmp,100); // Считываем текущую строку
		pmn[n]=new char [strlen(tmp)+1]; // Выделяем память под новую строку
		strcpy(pmn[n],tmp); // Копирум строку в массив
		n++;  // Увеличиваем количество строк
	}
	for(int i=0;i<n-1; i++) //Сортировка
		for (int j=i+1;j<n;j++)
			if (strcmp(pmn[i],pmn[j])>0)
			{ 
				char *c=pmn[i];
				pmn[i]=pmn[j];
				pmn[j]=c;
			}
	for (int i=0;i<n;i++) // Вывод отсортированных строк
		cout<<pmn[i]<<endl;
	system("pause");
	return 0;
}
Описание слайда:
Программа «Ввод и сортировка строк» #include <iostream> #include <clocale> #include <cstdlib> using namespace std; int main() { setlocale(LC_ALL, "Russian"); char* pmn[100]; // Массив указателей на строки char tmp [100]; // текущая строка int n=0; // Количество строк while(!cin.eof()) // Пока не конец потока { cin.getline(tmp,100); // Считываем текущую строку pmn[n]=new char [strlen(tmp)+1]; // Выделяем память под новую строку strcpy(pmn[n],tmp); // Копирум строку в массив n++; // Увеличиваем количество строк } for(int i=0;i<n-1; i++) //Сортировка for (int j=i+1;j<n;j++) if (strcmp(pmn[i],pmn[j])>0) { char *c=pmn[i]; pmn[i]=pmn[j]; pmn[j]=c; } for (int i=0;i<n;i++) // Вывод отсортированных строк cout<<pmn[i]<<endl; system("pause"); return 0; }

Слайд 32





Программа «Суммирование матриц»
#include <iostream>
#include <clocale>
#include <cstdlib>     
using namespace std;
// Создание и заполнение матрицы (Используя оператор [])
int** scanMatrix (int n, int m)
{ 	int **a=new int *[n];
	for (int i=0;i<n;i++)
		a[i]=new int[m];
	cout<<"Ведите элементы матрицы "<<n<<" на "<<m<<endl; 
	for (int i=0;i<n;i++)
		for (int j=0; j<m; j++)
			cin>>a[i][j];
	return a;}
// Вывод матрицы (Используя указатели)
void printMatrix(int **a, int n, int m)
{	for (int i=0;i<n;i++)
	{
		for (int j=0; j<m; j++)
			cout<<*(*(a+i)+j)<<'\t';
		cout<<endl;
	}
}
// Удаление матрицы (Используя указатели)
void deleteMatrix(int **a, int n)
{	for (int i=0;i<n;i++)
		delete [] *(a+i);
	delete [] a;
}
Описание слайда:
Программа «Суммирование матриц» #include <iostream> #include <clocale> #include <cstdlib> using namespace std; // Создание и заполнение матрицы (Используя оператор []) int** scanMatrix (int n, int m) { int **a=new int *[n]; for (int i=0;i<n;i++) a[i]=new int[m]; cout<<"Ведите элементы матрицы "<<n<<" на "<<m<<endl; for (int i=0;i<n;i++) for (int j=0; j<m; j++) cin>>a[i][j]; return a;} // Вывод матрицы (Используя указатели) void printMatrix(int **a, int n, int m) { for (int i=0;i<n;i++) { for (int j=0; j<m; j++) cout<<*(*(a+i)+j)<<'\t'; cout<<endl; } } // Удаление матрицы (Используя указатели) void deleteMatrix(int **a, int n) { for (int i=0;i<n;i++) delete [] *(a+i); delete [] a; }



Похожие презентации
Mypresentation.ru
Загрузить презентацию