Бублик Володимир ВасильовичПрограмування - 2 Лекція 3. Базові поняття програмування. Сталі та змінні Лекції для студентів 2 курсу
2.
Літерали Літерал (з латинського literal — буквальний) — це найпростіший об’єкт, що позначає сам себе. Цілі літерали 100 //десятковий запис 0144 //вісімковий ( o ctal ) 0х64 //шістнадцятковий ( hexadecimal , he x ) Вісімковими і шістнадцятковими константами варто користуватися лише для типів без знаку, інакше на комп’ютерах з доповняльним кодом можна зіткнутися із несподіванками типу значення –1 для константи 0xffffffff
3.
Літерали Уточнення типу числового літералу U, L або UL 2147483648U 2147483648L 2147483648UL F або L 1.0F 3.1415926535897932 L
Літерали Символьні літерали // вісімкові коди ’ \77’ // символ ’?’ ’ \144’ // символ ’f’ ’ \365’ // символ ’ї’ ( з точністю до кодової таблиці ) ’ \11’ // символ табуляції ’ \12’ // символ нового рядка ’ \14’ // символ нової сторінки
6.
Літерали Символьні літерали // шістнадцяткові коди ’ \x3f’ // символ ’?’ ’ \x66’ // символ ’f’ ’ \x10’ // символ нового рядка
7.
Літерали Символьні літерали // службові символи ’ \t’ // символ табуляції ’ \n’ // символ нового рядка ’ \f’ // символ нової сторінки Як бачимо, деякі з символів можна записати різними рівносильними способами: ’ \x10’, ’\12’ і ’\n’ ’ f’, ’\144’ і ’\x66’
8.
Літерали Багатосимвольні літерали (рядки) ” A” // послідовність, складена з ’A’ і ’\0’ ″ Це константа, складена із символів″ ” This is another string” ” Наступний рядок містить службові символи” ” \n№п/п\tНазва\tКількість\n” Виведеться як № п/п Назва Кількість
9.
Літерали vs. Іменовані об'єкти Літерали не потребують визначення, бо позначають самі себе, а запис літералу однозначно визначає його тип. Іменовані об'єкти вимагають попереднього визначення (створення) або оголошення . Визначення і оголошення визначають ім'я і тип об'єкту. Визначення приводить до створення об'єкту в пам'яті , тоді як оголошення посилається на об'єкт, створений в іншому місці. Визначення звичайно суміщують з ініціалізацією.
10.
Визначення сталих const float pi = 3.14159; const float Avogadro =6.02252e23; const double dpi = 3.141592653589793; const char tab = ‘\t’; const char title[] = ”C++ Programming Language”; const int sample; // сталу необхідно визначити! const int sample = 1756; sample = 456; // значення сталої не можна змінити!
11.
Визначення змінних inti= 1 , j= 1 , k= 1 ; // добре unsinged long counter= 0 ; // змінні корисно ініціювати double a = 0.0 , b= 1.0 ; double eps = 0.000001 ; double x; //визначення з наступним присвоєнням x = 0; //чому не ініціалізація double x = 0; ? double x; //не годиться! Перше присвоєння надто ………… .. x = 0; // далеко від визначення
Арифметичне присвоєння x= e; де x – іменуючий вираз, e – арифметичний вираз Обчислити lvalue (x) Обчислити rvalue (e) Переслати rvalue (e) до lvalue (x) Значенням виразу x = e вважати нове значення value (x) Яке з них lvalue чи rvalue ? ― Залежно від контексту
Приклади присвоєнь s= pi * r * r; i = j+k; Суміщене присвоєння i += k; // i = i+k i >>= k; // i = i>>k Інкремент (декремент) постфіксний // нехай k==1 j=k++ //j=k; k=k+1; // j==1; k==2 (i=++(j=++k))++ ; ??? префіксний // нехай k==1 j=++k //k=k+1; j=k; // j==2; k==2
18.
Композиція присвоєнь u= v = w; читається як u = ( v = w ) ; rvalue (w) ―› lvalue (v) rvalue (v) ―› lvalue (u) (u = v) = w; rvalue (v) ―› lvalue (u) rvalue (w) ―› lvalue (u) // що б це значило?
19.
Зведення типів 1.С (старомодне) week ―› int int (monday) або (int) Monday int ―› week (week) i 2. С++ (новітнє) const_cast, dynamic_cast, static_cast y = static_cast<double>( x ); Дуже обережно! Може з'явитися багато проблем
20.
Указник ( pointer)int * ptrI; float *px, y, z; float *px, *py, *pz; Визначення без ініціалізації приводять до заповнення пам'яті сміттям. Засмічені указники ( dangling pointer) небезпечні ! float x, *px; сміття сміття некоректні дані некоректна адреса
21.
Pointer vs. gotoУказники приводять до тих же проблем в структурах даних, до яких приводять оператори переходу в структурах керування. Скрізь, де можна, уникаємо указників. Якщо вживаємо, то дотримуємось суворої дисципліни! Якщо значення указника невідоме, ініціалізуємо його нулем float *px = 0; Якщо значення указника не нуль, то з ним зв'язані два елементи пам'яті!
22.
Адресування і розіменуванняx=0.25; px = & x; & одномісна операція адресування lvalue(px) rvalue(px) == lvalue (x) == rvalue(&x)
Адресування і розіменуванняcout<< * px; * одномісна операція розіменування rvalue(px) == lvalue(x) rvalue(*px) == rvalue(x)
25.
Динамічне виділення пам'ятіfloat *p = new float; new операція виділення нового елемента пам'яті, його адреса зберігається в p, значення *p заповнено сміттям px = new float; if (px == 0) // вільної пам’яті немає сміття
26.
Динамічне виділення іініціалізація пам'яті float *p = new float(0.333333); Тепер значення *p коректне
27.
Правило гарного тонуЯкщо ви виділили динамічну пам’ять за допомогою команди new не забудьте своєчасно звільнити її командою delete та обнулити указник float *p = new float(0.333333); // робіть все, що вам потрібно delete p; p = 0 ;
Звільнення памяті double*pd = new double(5.2); cout<<pd<<endl; // 0 x00 4419 B0 cout<<*pd<<endl; //5.2 delete pd; // Правило гарного тону pd = 0;
30.
Сталі величини іуказники Указник сталої const float pi = 3.14159; const float *piPtr = &pi ; //*piPtr = 4; ERROR!
31.
Сталі величини іуказники float x = 1; const float* px = &x; x =3; cout<<*px<<endl; //*px = 4; як і раніше ERROR! Указник сталої не має права змінити об'єкт, але безпосередня зміна об'єкту, якщо він не сталий можлива
32.
Сталі величини іуказники Сталий указник float x = 0.25; float *const px = &x ; //px = &y; ERROR!
33.
Сталі величини іуказники Сталий указник сталої const float pi = 3.14159; const float *const piPtr = &pi ; //*piPtr = 4; ERROR! //piPtr = &nAvogadro; ERROR!
34.
Безтипові указники void*voidPtr; //Що б це значило? voidPtr char * str “ \nabcdefghij” 00 A0 69 68 67 66 65 64 63 62 61 0 A
35.
Безтипові указники void*voidPtr; //Що б це значило? voidPtr Якби це був Бейсик “ abcdefghij” 00 A0 69 68 67 66 65 64 63 62 61 0 A
36.
Безтипові указники void*voidPtr; //Що б це значило? voidPtr short int * i 24842 A0 00 69 68 67 66 65 64 63 62 61 0 A
37.
Безтипові указники void*voidPtr; //Що б це значило? voidPtr float * x 4.17596e+021 A0 00 69 68 67 66 65 64 63 62 61 0 A
38.
Безтипові указники void*voidPtr; //Що б це значило? voidPtr int * k 1667391754 A0 00 69 68 67 66 65 64 63 62 61 0 A
39.
Безтипові указники void*voidPtr; //Що б це значило? float *pf = new float(3.1); double *pd = new double(5.2); voidPtr = pf; cout<<voidPtr<<endl; // 0 x00 4419 F0 // cout<<*voidPtr<<endl; розіменування неможливе voidPtr = pd; cout<<voidPtr<<endl; // 0 x00 4419 B0
40.
Символьний указник 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;
41.
Операцій над указниками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
42.
Відсилка (псевдонім) (reference ) Відсилка або псевдонім — це альтернативне ім’я об’єкта, яке позначає об’єкт на рівних правах з його основним іменем. При створенні псевдонім зв'язується зі своїм об'єктом (відсилає до нього) і ця відсилка дійсна протягом усього життя псевдоніму. Для чого? Для того, щоб у різних частинах програми іменувати одну й ту ж область пам'яті зручним і зрозумілим для цієї частини іменем
43.
Відсилка (псевдонім) (reference ) float x = 1.024; //визначення змінної х float &xRef = x; //визначення її псевдоніму xRef *= 2; // x == xRef == 2.048
44.
Копіювання float x= 1,024; //визначення змінної x float xCopy = x; //визначення її копії xCopy += x; //подвоєння xCopy, x незмінний
45.
Відсилка і указникfloat x = 1,024; //визначення змінної х float *px = &x; //визначення указника на неї
46.
Відсилка і указникpx = new float(3.33333); // x == 1,024; *px == 3.33333 //Зв’язок між px і x розірвано
47.
Відсилка і указникУказнику p відповідає два елементи пам'яті, кожен з яких має власне значення. Зміна значення p розриває наявний зв’язок між елементами пам'яті , наприклад, px = 0;
48.
Відсилка і сталийуказник float x = 1.024; //визначення змінної х float *const px = &x; //сталий указник на неї //схожість: зв’язок нерозривний //відмінність: наявність двох елементів пам'яті
Стала відсилка Щоб це значило? float x = 1; const float& rx = x; x =2; cout<<rx<<endl; Якщо псевдонім сталий, то він не має права змінити об'єкт, але безпосередня зміна об'єкту, якщо він не сталий можлива
51.
Указники указників double**ppd = new double*; *ppd = new double(5); cout<<ppd<<endl; cout<<*ppd<<endl; cout<<**ppd<<endl; Використання указників на указники ― р озповсюджена техніка програмування у “чистому” С. Проблеми управління пам'яттю при цьому зростають, бо необхідно слідкувати за обома поверхами указника. Вживати ще обережніше, ніж звичайні.