Бублик Володимир ВасильовичПроцедурне програмування C/C++Лекція 4. Базові поняття програмування.Указники і відсилки


The Presentation inside:

Slide 0

Бублик Володимир Васильович Процедурне програмування C/C++ Лекція 4. Базові поняття програмування. Указники і відсилки Лекції для студентів 2 курсу Nurnberg, Burg


Slide 1

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 2 (38) Призначення указників Указник (pointer) набуває значеннями адреси пам'яті, а також особливе нульове значення, з яким не зв'язана жодна адреса Динамічне виділення і звільнення пам'яті: створення масивів; створення динамічних структур даних (списків, дерев, тощо)


Slide 2

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 3 (38) Типізація указників Кожному указнику приписано його тип: указник цілого; указник символу; указник дійсного, тощо. З одним указником можна зв'язати цілий агрегат даних одного й того ж типу, розміщених одне за одним, починаючи з місця, позначеного указником


Slide 3

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 4 (38) Визначення указника int *ptrI; float *px, y, z; float *px, *py, *pz; Визначення без ініціалізації приводять до заповнення пам'яті сміттям. Засмічені указники (dangling pointer) небезпечні! float x, *px; сміття сміття некоректні дані некоректна адреса


Slide 4

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 5 (38) Pointer vs. goto Указники приводять до тих же проблем в структурах даних, до яких приводять оператори переходу в структурах керування. Скрізь, де можна, уникаємо указників. Якщо вживаємо, то дотримуємось суворої дисципліни! Якщо значення указника невідоме, ініціалізуємо його нулем float *px = 0; Якщо значення указника не нуль, то з ним зв'язані два елементи пам'яті!


Slide 5

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 6 (38) Операція адресування x=0.25; px = &x; & одномісна операція адресування lvalue(px) rvalue(px) == lvalue (x) == rvalue(&x)


Slide 6

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 7 (38) Операція розіменування cout<< *px; * одномісна операція розіменування rvalue(px) == lvalue(x) rvalue(*px) == rvalue(x)


Slide 7

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 8 (38) Адресування і розіменування Взаємна оберненість операцій над пам'яттю &(*px) == px px == *(&px)


Slide 8

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 9 (38) Динамічне виділення пам'яті float *p = new float; new операція виділення нового елемента пам'яті, його адреса зберігається в p, значення *p заповнено сміттям px = new float; if (px == 0) // вільної пам’яті немає сміття


Slide 9

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 10 (38) Нестача пам'яті Стандартна реакція: виникнення аварійної ситуації bad_alloc Обробка засобами системи програмування (аварійне припинення виконання програми) Програмна обробка переривання (оператор catch в блоці випробувань try – буде далі) Замовна реакція: повернення нульового указника Формат виклику new (nothrow) Приклад double *px = new (nothrow) double [bigAmount]; if (px==0) //Вільної пам'яті не вистачило


Slide 10

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 11 (38) Динамічне виділення і ініціалізація пам'яті float *p = new float (0.333333); Тепер значення *p коректне


Slide 11

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 12 (38) Правило гарного тону Якщо ви виділили динамічну пам’ять за допомогою команди new не забудьте своєчасно звільнити її командою delete та обнулити указник float *p = new float (0.333333); // робіть все, що вам потрібно delete p; // потурбуйтесь про захист від завислих указників p = 0;


Slide 12

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 13 (38) Звільнення памяті double *pd = new double (5.2); cout<<pd<<endl; // 0x004419B0 cout<<*pd<<endl; //5.2 delete pd; cout<<pd<<endl; // 0x004419B0 cout<<*pd<<endl; //-1.45682e+144 double *new_pd = new double; cout<<new_pd<<endl; // 0x004419B0 cout<<*pd<<endl; //-6.27744t+066 cout<<*new_pd<<endl;


Slide 13

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 14 (38) Звільнення памяті double *pd = new double (5.2); cout<<pd<<endl; // 0x004419B0 cout<<*pd<<endl; //5.2 delete pd; // Правило гарного тону pd = 0;


Slide 14

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 15 (38) Висновок про управління пам'яттю Кожному new свій delete Перевіряйте наявність вільної пам'яті Слідкуйте за тривалістю життя динамічних об'єктів у пам'яті


Slide 15

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 16 (38) Сталі величини і указники Указник сталої const float pi = 3.14159; const float *piPtr = &pi ; //*piPtr = 4; ERROR! // float *piNonConstPtr =&pi; теж ERROR


Slide 16

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 17 (38) Права указника сталої float x = 1; const float* px = &x; x =3; cout<<*px<<endl; //*px = 4; як і раніше ERROR! Указнику сталої не надано права змінювати об'єкт, але безпосередня зміна об'єкту, якщо він не сталий, і надалі можлива


Slide 17

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 18 (38) Сталі величини і указники Сталий указник float x = 0.25; float *const px = &x; // Сталий указник не можна перемістити // px = &y; ERROR!


Slide 18

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 19 (38) Сталі величини і указники Сталий указник сталої const float pi = 3.14159; const float *const piPtr = &pi; //*piPtr = 4; ERROR! //piPtr = &nAvogadro; ERROR!


Slide 19

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 20 (38) Безтипові указники void *voidPtr; //Що б це значило? voidPtr char * str “\nabcdefghij”


Slide 20

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 21 (38) Безтипові указники void *voidPtr; //Що б це значило? voidPtr Якби це був Бейсик “abcdefghij”


Slide 21

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 22 (38) Безтипові указники void *voidPtr; //Що б це значило? voidPtr short int * i 24842


Slide 22

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 23 (38) Безтипові указники void *voidPtr; //Що б це значило? voidPtr float * x 4.17596e+021


Slide 23

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 24 (38) Безтипові указники void *voidPtr; //Що б це значило? voidPtr int * k 1667391754


Slide 24

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 25 (38) Безтипові указники void *voidPtr; //Що б це значило? float *pf = new float (3.1); double *pd = new double (5.2); voidPtr = pf; cout<<voidPtr<<endl; // 0x004419F0 // cout<<*voidPtr<<endl; розіменування неможливе voidPtr = pd; cout<<voidPtr<<endl; // 0x004419B0


Slide 25

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 26 (38) Символьний указник Поганий указник char *c = new char; cout<<*c<<endl; Ініціалізований указник char *cc = new char ('a'); cout<<*cc<<endl; Особливість ініціалізації рядків // char *str = new char(“String?“); char *str = "Operation New is not needed"; cout<<str<<endl;


Slide 26

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 27 (38) Операцій над указниками float *p1= new float (1), *p2= new float (2); cout<<p2; //0x004418F0 Порівняння на рівність або нерівність p1 == p2; p1 > p2;… if(p2>p1) cout<<"p2>p1"<<endl; else cout<<"p1>p2"<<endl; Присвоєння і ініціалізація p1 = p2; p1 =&x; p1 = new float (3); char *pc = new char [100]; Збільшення, зменшення p1++; ++p1; p1--;--p1; p1+10; p1-10; cout<<p2+1; //0x004418F4


Slide 27

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 28 (38) Відсилка (псевдонім) (reference) Відсилка або псевдонім — це альтернативне ім’я об’єкта, яке позначає об’єкт на рівних правах з його основним іменем. При створенні псевдонім зв'язується зі своїм об'єктом (відсилає до нього) і ця відсилка дійсна протягом усього життя псевдоніму. Для чого? Для того, щоб у різних частинах програми іменувати одну й ту ж область пам'яті зручним і зрозумілим для цієї частини іменем


Slide 28

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 29 (38) Відсилка (псевдонім) (reference) float x = 1.024; //визначення змінної х float &xRef = x; //визначення її псевдоніму xRef *= 2; // x == xRef == 2.048


Slide 29

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 30 (38) Копіювання float x = 1,024; //визначення змінної x float xCopy = x; //визначення її копії xCopy += x; //подвоєння xCopy, x незмінний


Slide 30

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 31 (38) Порівняння відсилок і указників Визначення указника float x = 1,024; //визначення змінної х float *px = &x; //визначення указника на неї


Slide 31

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 32 (38) Порівняння відсилок і указників Перенаправлення указника px = new float (3.33333); // x == 1,024; *px == 3.33333 //Зв’язок між px і x розірвано


Slide 32

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 33 (38) Порівняння відсилок і указників Указнику p відповідає два елементи пам'яті, кожен з яких має власне значення. Зміна значення p розриває наявний зв’язок між елементами пам'яті, наприклад, px = 0;


Slide 33

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 34 (38) Відсилка і сталий указник float x = 1.024; //визначення змінної х float *const px = &x; //сталий указник на неї //схожість до відсилки: зв’язок нерозривний //відмінність: наявність двох елементів пам'яті


Slide 34

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 35 (38) Стала відсилка const float pi = 3.14159; const float &piRef = pi; // float &piNonConstRef = pi; ERROR


Slide 35

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 36 (38) Стала відсилка Що б це значило? float x = 1; const float & rx = x; x =2; cout<<rx<<endl; Якщо псевдонім сталий, то він не має права змінити об'єкт, але безпосередня зміна об'єкту, якщо він не сталий можлива


Slide 36

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 37 (38) Указники указників double **ppd = new double*; *ppd = new double (5); cout<<ppd<<endl; cout<<*ppd<<endl; cout<<**ppd<<endl; Використання указників на указники ? розповсюджена техніка програмування у “чистому” С. Проблеми управління пам'яттю при цьому зростають, бо необхідно слідкувати за обома поверхами указника. Вживати ще обережніше, ніж звичайні.


Slide 37

© 2006 Бублик В.В. Процедурне програмування. Лекція 4. Указники і відсилки 38 (38) Висновки Крім безпосередніх операцій з пам'яттю указники використовуються для передачі змінних параметрів при програмуванні на “чистому” С, а указники другого рівня для передачі змінних указників В сучасному програмуванні на С++ замість передачі указників використовується передача змінних параметрів відсилками


×

HTML:





Ссылка: