Lektsia_S__Massivy_stroki_ukazateli_i_ikh_vza.ppt
- Количество слайдов: 29
МАССИВЫ, СТРОКИ, УКАЗАТЕЛИ И ИХ ВЗАИМОСВЯЗЬ
Понятие массива n Массив: n n n последовательность данных одного типа, расположенных в соседних ячейках памяти, именованных общим идентификатором. Элементы массива нумеруются последовательно, начиная с 0. Номер элемента называется индексом. Доступ к элементам массива происходит по индексу. Выход за границу массива не контролируется.
Описание массива тип_элем идентификатор[кол-во_элем]; тип_элем идентификатор [кол-во_элем]= {нач_знач_элем}; тип_элем идентификатор [ ]= {нач_знач_элем}; //количество элементов массива определяется на основе списка инициализации
Доступ к элементам массива идентификатор[индекс]
Пример массива int a[5]={-4, 8, 1, 0, 2}; 0 1 2 3 4 -4 8 1 0 2 printf(“%i”, a[3]); 0_
Массив для строки n n не существует специального типа «строка» для описания строки используется массив символов элемент содержащий код ‘ ’ – конец строки работать со строкой можно как с массивом и с использованием функций стандартной библиотеки С++ string. h
Пример строки char str[4]={‘a’, ‘b’, ‘c’, 0}; 0 1 2 3 ‘a’ ‘b’ ‘c’ ‘ ’ printf(“%sn”, str); scanf(“%s”, str); //макс. 3 симв. str[0]=‘b’; printf(“%s”, str); abc 123 b 23
Альтернативная инициализация строки char s[]=“Гриб”; 0 1 2 3 4 ‘Г’ ‘р’ ‘и’ ‘б’ ‘ ’
Многомерный массив int m[4][3]={{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}; m 1 2 3 4 5 6 7 8 9 3 7 1 2 m 2 1 Размещение в памяти: 1 0 cout<
Указатель указатель p 0 x 0013 ff 07 … 0 x 0013 ff 07 ‘r’
Описание указателя тип *имя_указателя; тип *имя_указателя=нач_знач; char c=‘r’; char *p=&c;
Инициализация указателей n Пустой указатель NULL n n Адрес переменной n n int j; int *k=&j; Адресное выражение n n int *k=NULL; char str[]=“Привет”; char *pstr=&str[0]+1; Адрес-константа n int *p=((int *) 0 xb 8000000);
Операции с указателями n Косвенная адресация * int k=7; int *p=&k; printf(“%pn%i”, p, *p); 0013 FA 10 7
Операции с указателями n Инкремент, декремент char str[]=“Привет”; char *pstr=&str[0]; pstr++; printf(“%c”, *pstr); pstr--; printf(“%c”, *pstr); р. П
Операции с указателями n Сложение и вычитание адреса и индекса char str[]=“Привет”; char *pstr=&str[0]; pstr=pstr+4; printf(“%c”, *pstr); pstr-=2; printf(“%c”, *pstr); еи
Операции с указателями n Разность адресов char str[]=“Привет”; char *pstr 1=&str[0], *pstr 2=&str[3]; printf(“%i”, pstr 2 -pstr 1); 3
Особенность аддитивных операций с указателями int a[5]={1, 2, 3, 4, 5}; int *p 1=&a[1], *p 2=&a[2]; printf(“%p|%pn”, p 1, p 2); printf(“%i”, p 2 -p 1); 0013 FF 70|0013 FF 74 1 0 1 2 3 4 5
Особенность аддитивных операций с указателями int a[5]={1, 2, 3, 4, 5}; int *p 1=&a[0], *p 2=p 1+1; printf(“%p|%p”, p 1, p 2); 0013 FF 70|0013 FF 74
Операции с указателями n Присваивание указателей n тип указателей присваивании должен совпадать (можно использовать операцию явного преобразования типа) int i=0 x 0013 ff 70; int *pi=&i; char *pc=(char *)pi;
Операции с указателями n тип void * - указатель на объект любого типа n n указателю void * можно присваивать указатели любых типов int *pi=&i; char *pc=&c; void *pv=pi; pv=pc; указатель void * при разыменовывании или присваивании другим указателям (кроме void*) необходимо привести к непустому типу pi=(int *)pv; printf(“%i”, *(int *)pv);
Связь массива и указателя n Имя массива является константным указателем на первый элемент массива int a[2]={5, 1}; int *p=a; printf(“%i %i”, *p, *a); 55
Связь массива и указателя n Операция индексации аналогична сложению указателя и индекса a[k] *(a+k) int a[3]={1, 2, 3}; 22 int *p=a; printf(“%i %i”, p[1], *(a+1));
Сложные конструкции на базе указателей n Массив указателей элементами массива являются указатели char *pstr[]={“ 123”, “ 456”, NULL}; n 0 x 0013 ff 70 0 x 0013 fff 1 0 x 0000 ‘ 4’ ‘ 5’ ‘ 6’ 0 ‘ 1’ ‘ 2’ ‘ 3’ 0
Сложные конструкции на базе указателей n Указатель на указатель тип **имя=адрес_указателя; char ch=‘a’; char *pch=&ch; char **ppch=&pch; ch ‘a’ pch 0 x 0013 ff 80 ppch 0 x 0013 ff 90
Указатель на функцию int f 1(){} //описание функции int f 2(){} //описание функции void f 3(int k){} //описание функции void main() { int (*pf)(); //описание указателя на функцию pf=f 1; //присваивание указателя pf(); // вызов функции через указатель pf=f 2; pf(); void (*pf 2)(int); //описание указателя на функцию pf 2(5); }
Работа с динамической областью памяти n n n Можно выделить память под переменную непосредственно в процессе работы программы Память выделяется из области памяти, называемой кучей Для выделения памяти используется оператор new Оператор new возвращает адрес выделенной области памяти, который следует запомнить в переменной-указателе для последующей работы с динамической переменной После использования память должна быть освобождена оператором delete
Оператор выделения динамической памяти new тип[кол-во] Выделяется место под переменную указанного типа (массив переменных, указанного размера) int *p=new int; *p=5; *p+=8; char *str=new char[5]; scanf(“%s”, str); printf(“%c”, str[2]);
Оператор освобождения динамической памяти delete [] адрес освобождается выделенная ранее память по указанному адресу. [] обязательны, если был выделен массив. int *p=new int; char *str=new char[5]; delete p; delete [] str;
Ошибочные ситуации с указателями n n n Разыменовывание пустого указателя Некорректный адрес освобождаемого участка памяти (повторное освобождение) Возвращение функцией адреса локальной переменной