Разделы презентаций


Программирование

Содержание

УказателиУказатель – это переменная, хранящая адрес некоторой ячейки памяти.Указатели являются типизированными:int i = 3; // переменная типа intint * p = 0; // указатель на переменную типа intНулевому указателю (которому присвоено

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

Слайд 1Программирование
Лекция 3. Указатели. Использование указателей. Динамическая память.

ПрограммированиеЛекция 3. Указатели. Использование указателей. Динамическая память.

Слайд 2Указатели
Указатель – это переменная, хранящая адрес некоторой ячейки памяти.
Указатели являются

типизированными:
int i = 3; // переменная типа int
int * p

= 0; // указатель на переменную типа int
Нулевому указателю (которому присвоено значение 0) не соответствует никакая ячейка памяти.
Существует 2 оператора при работе с указателями:
1) Оператор взятия адреса переменной &
2) Оператор разыменования *.
p = &i; // указатель p указывает на переменную i (в данном случае в указатель p записывается адрес переменной i)
*p = 10; // изменяется ячейка по адресу p, т.е. i (то есть i будет равно 10, а не 3)


УказателиУказатель – это переменная, хранящая адрес некоторой ячейки памяти.Указатели являются типизированными:int i = 3; // переменная типа

Слайд 3Передача параметров по указателю
Использование указателей позволяет реализовывать функции, которые меняют

свои аргументы.
Допустим, мы хотим написать функцию, которая будет менять

значения переменных местами.

int main () {
int k = 10, m = 20;
swap (k, m);
cout << k << “ “ << m << endl; // 10 20
return 0;
}
void swap (int a, int b) { // функция работает с локальными копиями // переменных
int t = a;
a = b;
b = t;
}

Значения k и m не поменялись местами!

Передача параметров по указателюИспользование указателей позволяет реализовывать функции, которые меняют свои аргументы. Допустим, мы хотим написать функцию,

Слайд 4Передача параметров по указателю
Для того, чтобы это исправить, будем передавать

не значения типа int, а указатели на эти значения.
int main

() {
int k = 10, m = 20;
swap (&k, &m); // передаем адреса
cout << k << “ “ << m << endl; // 20 10
return 0;
}
void swap (int * a, int * b) { // функция работает с //адресами переменных
int t = *a;
*a = *b;
*b = t;
}

Меняются значения, на которые указывают аргументы функции

Передача параметров по указателюДля того, чтобы это исправить, будем передавать не значения типа int, а указатели на

Слайд 5Еще раз о массивах
Массивы – это набор однотипных элементов, расположенных

в памяти друг за другом, доступ к которым осуществляется по

индексу.
// массив 1 2 3 4 5 0 0 0 0 0
int m[10] = {1, 2, 3, 4, 5}; // инициализация массива
Индексация массива начинается с 0, последний элемент массива длины n имеет индекс (n-1)
for (int i = 0; i < 10; i++)
cout << m[i] << “ “;
cout << endl;

Массивы часто используются в циклах

Еще раз о массивахМассивы – это набор однотипных элементов, расположенных в памяти друг за другом, доступ к

Слайд 6Связь массивов и указателей
Массивы тесно связаны с указателями.
Указатели позволяют передвигаться

по массивам.
Для этого используется арифметика указателей:
int m[10] = {1, 2,

3, 4, 5};
int * p = &m[0]; // адрес начала массива
int * q = &m[9]; // адрес последнего элемента массива
(p+k) – сдвиг на k ячеек типа int вправо
(p-k) – сдвиг на k ячеек типа int влево
(q-p) – количество ячеек между указателями
p[k] эквивалентно *(p+k)

Связь массивов и указателейМассивы тесно связаны с указателями.Указатели позволяют передвигаться по массивам.Для этого используется арифметика указателей:int m[10]

Слайд 7Примеры
Заполнение массива при помощи указателя:

Передача массива в функцию:
указатель на начало

массива
Работаем с m, как будто это массив. Сначала max –

это первый элемент массива
ПримерыЗаполнение массива при помощи указателя:Передача массива в функцию:указатель на начало массиваРаботаем с m, как будто это массив.

Слайд 8Чтение строк
Для начала вам нужно подключить библиотеку string. «String» –

это строка как последовательность символов, а «line» – последовательность символов,

оканчивающаяся переводом строки.
Решим такую задачу: пользователь вводит свое имя, а программа здоровается с ним. 

Сложение строк

Чтение строкДля начала вам нужно подключить библиотеку string. «String» – это строка как последовательность символов, а «line»

Слайд 9Чтение строк
При использовании cin чтение будет происходить по словам. Например,

если нам понадобится считать два слова, это можно сделать, считав

с помощью cin две переменные типа string. Слова могут быть разделены любым количеством пробелов, табуляций и переводом строк, но в переменных окажутся только непробельные символы.
Чтение строкПри использовании cin чтение будет происходить по словам. Например, если нам понадобится считать два слова, это

Слайд 10Чтение строк
Часто возникает необходимость считать строку (в понимании line) целиком,

а не пословно. Для этого есть специальная функция getline(cin, s).

Первый параметр в этой функции указывает на поток ввода (cin), а второй – на строку, в которую нужно считывать.
Чтение строкЧасто возникает необходимость считать строку (в понимании line) целиком, а не пословно. Для этого есть специальная

Слайд 11Коды символов
В компьютере всё, в том числе и строки, хранится

в виде чисел (строка — набор чисел, которыми кодируются символы).

Для хранения одного символа используется тип char (от слова character, символ).
Можно обращаться к отдельным символам строки, написав после её имени в квадратных скобках номер символа. Нумерация символов в строке начинается с нуля, так же как и в векторах. Узнать длину строки можно с помощью метода size.

Когда мы выводим переменную типа char, то выводится символ. Хотя на самом деле char – числовая переменная и обозначает номер символа в кодовой таблице. Вывод кода символа выглядит так:

Коды символовВ компьютере всё, в том числе и строки, хранится в виде чисел (строка — набор чисел,

Слайд 12Выделение цифр числа
Задача: получим из html-кода страницы информацию о курсах

акций, чтобы заработать на их колебаниях кучу денег. Первым делом

нужно выделить из строки только цифры. Мы будем считать, что в строке есть только одно целое число и его и нужно получить. Для решения этой задачи мы будем проходить по всей строке и, если символ – цифра, будем её печатать.

string s; getline(cin, s); for (auto c : s) { // тип char     if (c >= '0' && c <= '9') {         cout << c;     } }

В этой программе мы проходим по всем символам строки (так же, по всем элементам вектора). Узнать код конкретного символа – для этого нужно записать этот символ в одинарных кавычках. Если код очередного символа лежит в пределах от 0 до 9, то этот символ – цифра.

Выделение цифр числаЗадача: получим из html-кода страницы информацию о курсах акций, чтобы заработать на их колебаниях кучу

Слайд 13Поиск подстроки в строке
Пусть в скачанном нами файле содержится много

строк, но нам интересна только та, где есть название компании,

акциями которой мы хотим торговать. Например, это «Рога и копыта» с кодом на бирже rkpt. Дальше наша задача усложняется: среди N строк нужно найти ту, которая содержит подстроку rkpt (то есть где-то внутри строки встречается эта последовательность символов) и вывести число, записанное в этой строке.

int n; // кол-во строк cin >> n; string s; getline(cin, s); for (int i = 0; i < n; i++) {     getline(cin, s);     if (s.find("rkpt") != -1) {         for (auto c : s) {             if (c >= '0' && c <= '9') {                 cout << c;             }         }     } }

Метод find работает следующим образом: если подстрока нашлась, то она возвращает число, равное номеру символа, с которого началось первое вхождение подстроки в строку. А если подстроки не нашлось, то этот метод возвращает -1.
Обратите внимание на getline перед циклом. Он необходим, потому что после считывания числа в этой строке остается еще и символ перевода строки. Так что когда мы сделаем первый getline, то он считает пустую строку (ведь до перевода строки ничего не осталось).


Слайд 14Изменение регистра символа
int n; // кол-во строк cin >> n; string s; getline(cin,

s);
for (int i = 0; i < n; i++) {  

  getline(cin, s);
string s2 = “”;
for (auto c : s) { // изменение регистра
if (c >= ‘a’ && c <= ‘z’) {
int al_num = c – ‘a’; // номер буквы в алфавите
s2 += ‘A’ + al_num;
}
else
s2 += c;

}     if (s2.find(“RKPT") != -1) { // поиск подходящей строки         for (auto c : s2) { // s2 – теперь заглавные буквы             if (c >= '0' && c <= '9') {                 cout << c;             }         }     } }

Допустим, название компании может быть написано как большими, так и маленькими буквами или даже вперемешку. А значит нам нужно научиться определять регистр. 

Изменение регистра символаint n; // кол-во строк cin >> n; string s; getline(cin, s); for (int i

Слайд 15Задача
Необходимо вывести символы между первым и вторым знаком препинания.

ЗадачаНеобходимо вывести символы между первым и вторым знаком препинания.

Слайд 16Два способа передачи массива
*p - указатель на начало массива
Второй способ

быстрее!
Так как m[i] это *(m+i)

Два способа передачи массива*p - указатель на начало массиваВторой способ быстрее!Так как m[i] это *(m+i)

Слайд 17Возврат указателя из функции
// первый элемент массива
// возвращаем само значение

макс. элемента
начало массива

Возврат указателя из функции// первый элемент массива// возвращаем само значение макс. элементаначало массива

Слайд 18Возврат указателя из функции
Но можно вернуть также и место в

массиве, на котором находится макс. элемент. То есть указатель на

макс. элемент. Эту информацию в дальнейшем можно использовать, например, чтобы переставить макс. элемент в начало.

возвращается указатель!

// меняем указатель на макс. элемент

значение макс. элемента

// получаем адрес макс. элемента и его значение

Возврат указателя из функцииНо можно вернуть также и место в массиве, на котором находится макс. элемент. То

Слайд 19Возврат значения через указатель
Если функции передали пустой массив, то функция

будет сигнализировать об этом.
новый параметр – указатель на результат

Возврат значения через указательЕсли функции передали пустой массив, то функция будет сигнализировать об этом. новый параметр –

Слайд 20Недостатки указателей
оператор разыменования и взятия адреса
указатели на указатели
если объявлен указатель,

но не проинициализирован, то там хранится какой-то адрес
обращение к неинициализированному

указателю – ошибка.
обращение к нулевому указателю – это ошибка.

например, выйти за границы массива

Недостатки указателейоператор разыменования и взятия адресауказатели на указателиесли объявлен указатель, но не проинициализирован, то там хранится какой-то

Слайд 21Ссылки
это ссылки
На самом деле в функции используются не локальные переменные,

а ссылки на эти переменные
Внутри ссылок «зашиты» указатели, но

синтаксически код выглядит чище, не нужно использовать оператор *.
Ссылкиэто ссылкиНа самом деле в функции используются не локальные переменные, а ссылки на эти переменные Внутри ссылок

Слайд 22Различия ссылок и указателей
для ссылок всегда нужно указывать инициализирующее значение
не

нужна проверка на 0

Различия ссылок и указателейдля ссылок всегда нужно указывать инициализирующее значениене нужна проверка на 0

Слайд 23Различия ссылок и указателей
Ссылки представляют идею «синонимов»

Различия ссылок и указателейСсылки представляют идею «синонимов»

Слайд 24lvalue и rvalue
тернарный оператор
= m[a/2]=5

lvalue и rvalueтернарный оператор= m[a/2]=5

Слайд 25Время жизни переменной
foo возвращает указатель на переменную. Но a –

это локальная переменная. При выходе из функции переменная a перестанет

существовать.

Может так случиться, что указатель или ссылка в программе указывает на переменную, которая уже не существует

p указывает на переменную, которая не существует

bar возвращает ссылку на локальную переменную.

дальнейшее обращение к l будет некорректно

Время жизни переменнойfoo возвращает указатель на переменную. Но a – это локальная переменная. При выходе из функции

Слайд 26Стек вызовов

Стек вызовов

Слайд 27Устройство стека

Устройство стека

Слайд 28Устройство стека

Устройство стека

Слайд 29Устройство стека

Устройство стека

Слайд 30Устройство стека

Устройство стека

Слайд 31Устройство стека

Устройство стека

Слайд 32Устройство стека

Устройство стека

Слайд 33Вызов функции
Счетчики:
(вершина стека)
(начало данных текущей функции)

Вызов функцииСчетчики:(вершина стека)(начало данных текущей функции)

Слайд 34Вызов функции
(аргументы)

Вызов функции(аргументы)

Слайд 35Вызов функции
адрес возврата
(регистры процессора)
Возвр. значение

Вызов функцииадрес возврата(регистры процессора)Возвр. значение

Слайд 36Вызов функции
Управление передается функции foo()
Счетчик перемещается (для адресации лок. переменых)

Вызов функцииУправление передается функции foo()Счетчик перемещается (для адресации лок. переменых)

Слайд 37Вызов функции
Временное значение

Вызов функцииВременное значение

Слайд 38Вызов функции
Вычисляются значения d и h
Условное выражение вида
"условие" ?

"выражение 1" : "выражение 2"

Вызов функцииВычисляются значения d и hУсловное выражение вида

Слайд 39Вызов функции
Записывается возвр. значение

Вызов функцииЗаписывается возвр. значение

Слайд 40Вызов функции
Функция foo () закончила свое выполнение, лок. переменные удалены

Вызов функцииФункция foo () закончила свое выполнение, лок. переменные удалены

Слайд 41Вызов функции
Изменяем значение x и избавляемся от всех доп. данных

Вызов функцииИзменяем значение x и избавляемся от всех доп. данных

Слайд 42Вызов функции
Зависит от компилятора

Вызов функцииЗависит от компилятора

Слайд 43Динамическая память
Это способ выделения дополнительных областей памяти для хранения данных.
Зачем

нужна динамическая память?
Массив будет уничтожен при выходе из функции

Динамическая памятьЭто способ выделения дополнительных областей памяти для хранения данных.Зачем нужна динамическая память?Массив будет уничтожен при выходе

Слайд 44Выделение памяти в стиле С (самостоятельно)

Выделение памяти в стиле С (самостоятельно)

Слайд 45Выделение памяти в стиле С (самостоятельно)

Выделение памяти в стиле С (самостоятельно)

Слайд 46Выделение памяти в стиле С (самостоятельно)
Чтобы указатель m не указывал

на какую-то область памяти

Выделение памяти в стиле С (самостоятельно)Чтобы указатель m не указывал на какую-то область памяти

Слайд 47Выделение памяти в стиле С++

Выделение памяти в стиле С++

Слайд 48Типичные проблемы при работе с динамической памятью
Память занята неравномерно

Типичные проблемы при работе с динамической памятьюПамять занята неравномерно

Слайд 49Типичные проблемы при работе с динамической памятью
Программа отработает нормально

Типичные проблемы при работе с динамической памятьюПрограмма отработает нормально

Слайд 50Вопросы
1) В чем разница между статической памятью и динамической? 2) Назначение

указателя. 3) Что означает символ & перед переменной. 4) Что такое двойной

указатель 5) Приведите пример инициализации двухмерного массива.
Вопросы1) В чем разница между статической памятью и динамической? 2) Назначение указателя. 3) Что означает символ &

Слайд 51Задание
#include  using namespace std; int main() { int a = 5;  int *p = &a; //объявляем указатель. cout

*p

<< endl; //выведет ? *p = 7; cout << a << ' ' << *p << endl; //выведет ?   int b = 8;  int *p = &b; cout << b << ' ' << *p << endl; //выведет ? a = 9; cout << b << ' ' << *p << endl; //выведет ? *p = 10; cout << b << ' ' << *p << endl; //выведет ? return 0; }
Задание#include  using namespace std; int main() { int a = 5;  int *p = &a; //объявляем указатель. cout

Слайд 52Решение

Решение

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика