Лекция 5 Адресные типы. Указатели адрес (размещение в памяти) объекта Массивы последовательность однотипных данных Ссылки альтернативное имя объекта.

Презентация:



Advertisements
Похожие презентации
Лекция 7 Приведение типов. Классификация типов Типы С++ Пользовательские Встроенные (Фундаментальные) Адресные Арифтметические void Указатели Ссылки Массивы.
Advertisements

Основы информатики Лекция. Массивы. Указатели. Заикин Олег Сергеевич
Лекция 9 Приведение типов. Классификация типов Типы С++ Пользовательские Встроенные (Фундаментальные) Адресные Арифтметические void Указатели Ссылки Массивы.
УКАЗАТЕЛИ. Переменная - это именованная область памяти с заданным типом. [=значение]; int a; //Переменная типа integer с именем a int b=2;// Переменная.
Основы информатики Массивы. Указатели. Заикин Олег Сергеевич
МАССИВЫ 4 Определение 4 Описание 4 Обращение к элементам массива 4 Связь массивов с указателями 4 Примеры программ.
ФГОБУ ВПО "СибГУТИ" Кафедра вычислительных систем УКАЗАТЕЛИ Преподаватель: Доцент Кафедры ВС, к.т.н. Поляков Артем Юрьевич © Кафедра вычислительных систем.
Выражения языка Си(ч.2). Операции Лекция 3. Основные классы операций арифметические логические поразрядные операции сравнения.
Лекция 10 ОбъектыЛекция 10 ОбъектыООП Инкапсуляция Возможность совместного хранения данных и кода для их обработки Наследование Возможность расширять существующие.
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Лекция 3. Одномерные массивы, указатели и ссылки Красс Александр СПбГУ ИТМО, 2008.
Введение в язык программирования С++. Элементы языка общие с С. Полиморфизм. Инкапсуляция.
Лекция 6 1. Обработка массивов. Объявление одномерного массива Синтаксис: [ ] Пример: int a[10]; Определяет массив a размера 10, т. е. блок из 10 последо-
Лекция 9 Функции. Массивы-параметры функции Передача массива в функцию Пример: void array_enter(int a[], int size) { int i; for (i = 0; i < size; i++)
Массивы и строки Лекция 5. Одномерные массивы. Объявление. Общая форма объявления: тип имя_переменной[размер]; Пример: double balance[100]; balance[3]
Лекция 8 Область видимости Время жизни. Область видимости Область видимости – характеристика именованного объекта Область видимости - часть текста программы,
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
СИМВОЛЬНЫЕ СТРОКИ С++. ОБЪЯВЛЕНИЕ СИМВОЛЬНЫХ СТРОК В ПРОГРАММАХ В C++ символьные строки хранятся в массиве типа char, который заканчивается символом NULL.
Информационные технологии Классы памяти auto static extern register Автоматические переменные создаются при входе в функцию и уничтожаются при.
Транксрипт:

Лекция 5 Адресные типы

Указатели адрес (размещение в памяти) объекта Массивы последовательность однотипных данных Ссылки альтернативное имя объекта

Указатели Для каждого типа T тип T* является указателем на тип T, т.е. переменная типа T* содержит адрес переменной типа T int n ; int * pn ; int ** ppn ; char * pc ; float * pf ; void * p ; enum Day { Mon, Tue, Wed }; Day * pday ; int n ; int * pn ; int ** ppn ; char * pc ; float * pf ; void * p ; enum Day { Mon, Tue, Wed }; Day * pday ; int n ; int * pn ; typedef int * pint ; pint m ; // pint эквивалентен int* int n ; int * pn ; typedef int * pint ; pint m ; // pint эквивалентен int*

Инициализация и взятие адреса Переменная типа «указатель» может быть проинициализирована : численным значением адреса адресом существующей переменной (с помощью оператора взятия адреса) Оператор & применяется только к lvalue int n = 7 ; int * pv = 0 ; int * px = NULL ; int n = 7 ; int * pv = 0 ; int * px = NULL ; int n = 7 ; int * pv = &n ; int n = 7 ; int * pv = &n ; float f = 9 ; float * pg = &f ; float f = 9 ; float * pg = &f ; // Можно int * pv = &n ; // Можно int * pv = &n ; // Нельзя!!! int * pv = &7 ; // Нельзя!!! int * pv = &7 ;

Разыменование Чтобы обратиться к переменной, адрес которой хранится в указателе, используют оператор разыменования *. Результатом разыменования является lvalue int n = 7 ; int m = 8 ; int * pn = &n ; int **ppn = &pn ; n = 9 ; // n = 9 *pn = 12 ; // n = 12 *ppn = &m ;// pn = &m *pn = 7 ; // m = 7 int n = 7 ; int m = 8 ; int * pn = &n ; int **ppn = &pn ; n = 9 ; // n = 9 *pn = 12 ; // n = 12 *ppn = &m ;// pn = &m *pn = 7 ; // m = 7 nm pn ppn

Указатель на void Переменные типа void* нельзя разыменовывать Указатель на любой объект можно присвоить переменной типа void* Переменную типа void* можно присвоить другой переменной типа void* Две переменных типа void* можно сравнивать на равенство и неравенство void* можно явно преобразовать в другой тип int n = 0 ; int * pn = &n ; *pn = 7 ; // Можно void * pv = pn ; *pv = 9 ; // Нельзя! float * pf = pv ; float * pq = pn ; float * pr = (float)pv; int n = 0 ; int * pn = &n ; *pn = 7 ; // Можно void * pv = pn ; *pv = 9 ; // Нельзя! float * pf = pv ; float * pq = pn ; float * pr = (float)pv;

Массивы Для каждого типа T тип T[size] является массивом объектов типа T. Переменная типа T[size] содержит неразрывный набор объек- тов типа T, индексированных от 0 до size-1 Размер массива должен быть константным выражением int n [10]; char pn [12]; float c[1]; void f[20]; int n [10]; char pn [12]; float c[1]; void f[20]; int n ; int an[7] ; typedef int aint7[7]; aint7 am ; int n ; int an[7] ; typedef int aint7[7]; aint7 am ;

Инициализаторы массивов Массив инициализируется списком значений Если количество значений меньше размера массива, его остальным элементам присваивается 0 Указание большего чем размер массива количества значений является ошибкой В случае, если указан список инициализации, можно явно не указывать размер массива Не существует оператора присваивания, идентичной инициализации int n [4] = {1,2,3,4}; int m [6] = {1,2,3,4}; // {1,2,3,4,0,0} int n [4] = {1,2,3,4,5,6}; // Ошибка! int n [] = {1,2,3,4}; // int n[4] = n = {1,2,3,4}; // Ошибка

Строки и строковые литералы Строковым литералом является последовательность символов, заключенная в кавычки. Тип строкового литерала – массив с достаточным количеством символов (с учетом концевого нуля) Могут быть инициализатором массива Используют модификатор L в том же смысле, что и символьные литералы. "Hello world" sizeof("Hello) == 6 ; // const char[6]; char c[] = "Hello" ; char d[] = {'H', 'e', 'l', 'l', 'o', 0 }; char c[] = "Hello" ; char d[] = {'H', 'e', 'l', 'l', 'o', 0 }; "Hello" ; // const char[6] L"Hello" ; // const wchar_t[6] "Hello" ; // const char[6] L"Hello" ; // const wchar_t[6]

Строковые литералы Могут быть присвоены переменной типа char* (Не рекомендуется) Память под строковые литералы выделяется статически Могут быть заданы в несколько строк char s1[] = "Hello world" ; // Ошибка char s2[] = "Hello\nworld ; // Строка с переносом char s3[] = "Hello "World ; // Многострочное задание char s1[] = "Hello world" ; // Ошибка char s2[] = "Hello\nworld ; // Строка с переносом char s3[] = "Hello "World ; // Многострочное задание

Арифметика указателей Размер указателя = разрядность системы sizeof(T*)=sizeof(size_t) Разность указателей sizeof(T*-T*)=sizeof(diff_ptr) Сумма/разность указателя и интегрального типа Операции сравнения int * pnpn+1

Двойственность указателей и массивов Имя массива может быть использовано как указатель на первый элемент массива int v[] = {1,2,3,4,5}; v[3] = 7 ; int * p1 = v ; // p1 указывает на v[0] int * p2 = &v[2]; // p2 указывает на v[2] int * p3 = v + 3 ; // p3 указывает на v[3] *(v+1) = 12 ; // v[1] = 12 p1[4] = 15 ; // v[4] = 15 3[p1] = 7 ; // v[3] = 7 // p1[3] eq *(p1+3) eq 3[p1] int v[] = {1,2,3,4,5}; v[3] = 7 ; int * p1 = v ; // p1 указывает на v[0] int * p2 = &v[2]; // p2 указывает на v[2] int * p3 = v + 3 ; // p3 указывает на v[3] *(v+1) = 12 ; // v[1] = 12 p1[4] = 15 ; // v[4] = 15 3[p1] = 7 ; // v[3] = 7 // p1[3] eq *(p1+3) eq 3[p1]

Ссылки Являются альтернативным именем объекта Обязательно инициализируются «опорным» (реферальным) объектом, на который они ссылаются. Не могут быть изменены в процессе программы. Любое изменение ссылки применяется к реферальному объекту. int n = 3 ; int & cn = n ; cn = 7 ; // n = 7 ; float & cf ; // Ошибка! int n = 3 ; int & cn = n ; cn = 7 ; // n = 7 ; float & cf ; // Ошибка!

Двойственность указателей и ссылок Ссылки, по сути, это неизменяемые указатели с неявным разыменованием. int n = 7 ; int & cn = n ; int * const pn = & n ; cn = 8 ; // n = 8 *pn = 9 ; // n = 9 int n = 7 ; int & cn = n ; int * const pn = & n ; cn = 8 ; // n = 8 *pn = 9 ; // n = 9

Модификатор const Означает, что значение переменной данного типа не может изменяться. Применим к массивам ссылкам int n = 7 ; // Изменяемая переменная const int m = 9 ; // Неизменяемая переменная int const q = 8 ; // То же самое const int p ; // Ошибка! Нет инициализатора n = 11 ; // Нормально q = 6 ; // Ошибка! Константный объект int n = 7 ; // Изменяемая переменная const int m = 9 ; // Неизменяемая переменная int const q = 8 ; // То же самое const int p ; // Ошибка! Нет инициализатора n = 11 ; // Нормально q = 6 ; // Ошибка! Константный объект const int v[] = {1,2,3}; // Все эл-ты константны const int u[]; // Ошибка! Нет инициализатора const int &c = n ; // Ссылка на константу int const *d = n ; // Указатель на константу char const & q ; // Ошибка! Нет инициализатора const int v[] = {1,2,3}; // Все эл-ты константны const int u[]; // Ошибка! Нет инициализатора const int &c = n ; // Ссылка на константу int const *d = n ; // Указатель на константу char const & q ; // Ошибка! Нет инициализатора

Тонкости константных объектов Указатель или ссылку на константный объект можно инициализировать неконстантным объектом, но не наоборот. На константность самого объекта такая инициализация не влияет. int n = 7 ; // Изменяемая переменная const int m = 9 ; // Неизменяемая переменная const int & ccm = m ; // Можно const int & ccn = n ; // Можно по правилу int & cn = n ; // Можно int & cm = m ; // Ошибка! m - константа cn = 7 ; // Можно ccn = 7 ; // Ошибка! ссn – ссылка на конст. int const * cpn = &n ; // Можно по правилу int const * cpm = &m ; // Можно int * pm = &m ; // Ошибка! m - константа int n = 7 ; // Изменяемая переменная const int m = 9 ; // Неизменяемая переменная const int & ccm = m ; // Можно const int & ccn = n ; // Можно по правилу int & cn = n ; // Можно int & cm = m ; // Ошибка! m - константа cn = 7 ; // Можно ccn = 7 ; // Ошибка! ссn – ссылка на конст. int const * cpn = &n ; // Можно по правилу int const * cpm = &m ; // Можно int * pm = &m ; // Ошибка! m - константа

Константные указатели Помимо оператора объявления * есть оператор *const, означающий неизменяемый (константный) указатель. int * p ; // указатель на целое const int * p ; // указатель на константу int const * p ; // указатель на константу int * const p ; // константный указатель int const * const p ; // константный указатель на // константу const int const * const p ; // перебор int * p ; // указатель на целое const int * p ; // указатель на константу int const * p ; // указатель на константу int * const p ; // константный указатель int const * const p ; // константный указатель на // константу const int const * const p ; // перебор

Множественные объявления Модификаторы типа действуют на все переменные во множественном определении, операторы определения ( *, *const, & [], () ) только на те переменные, которым принадлежат. int * n = 7, c = 9 ; // * относbтся к объекту // c – типа int int const * const a, b ; // b – типа const int int k, &l = k, *p = &k ; // k - int // l – int & // p – int * int * n = 7, c = 9 ; // * относbтся к объекту // c – типа int int const * const a, b ; // b – типа const int int k, &l = k, *p = &k ; // k - int // l – int & // p – int *

Составные типы Многомерный массив int a[2][3] = {{1,2,3},{4,5,6}}; Указатели на указатели int ** p int *const* q Массивы указателей int * m[10] Указатели на массивы int (*pm)[10] Ссылка на указатель int *& p; Указатель на ссылку не бывает!