diff options
1 files changed, 83 insertions, 0 deletions
| -rw-r--r-- | src/teaching/upp-2023/week5/revision.md | 83 |
diff --git a/src/teaching/upp-2023/week5/revision.md b/src/teaching/upp-2023/week5/revision.md new file mode 100644 index 0000000..4356848 --- /dev/null +++ b/src/teaching/upp-2023/week5/revision.md @@ -0,0 +1,83 @@ +# Преговор - УПП, Седмица 5, 03.11.2023 + +## Указатели + +Всяка променлива се съдържа някъде в паметта. +За да можем да определим къде дадено нещо е запазено, всяка клетка в паметта си има "адрес". +Адресът е едно цяло положително число. + +Можем да вземем адреса на дадена променлива с оператора `&`: + +```cpp +double a = 3.14159; +std::cout << (&a) << std::endl; +``` + +Tази програма ще върне адресът на променлива `a`. + +След като имаме адрес, бихме искали да работим със стойността на този адрес. +Това го правим с дерефериращия оператор `*`: + +```cpp +double a = 3.14159; +std::cout << (*(&a)) << std::endl; +``` + +Тази програма връща стойността на адреса на променлива `a`. + +Променливи, които съдържат адреси се наричат указатели. +Синтаксисът на един указател е: + +```cpp +<ТИП НА СТОЙНОСТТА> * <ИМЕ> = <АДРЕС>; +``` + +Тоест примерно: + +```cpp +double a = 3.14159; +double * pointer = &a; +``` + +Звездата може да бъде долепена до типа или името на указателя: + +```cpp +double* pointer1 = &a; +double *pointer2 = &a; +``` + +## Масиви + +Ако искаме да запазим няколко последователни стойности, можем да използваме масиви. +Идеята е, че запазваме няколко адреса в паметта един след друг и запазваме само първия адрес. +Така първия елемент се намира на първия адрес, втория елемент се намира на първия адрес + 1 и так. нат. + +Дефинираме масиви с контантна дължина така: + +```cpp +<ТИП> <ИМЕ>[] = { <СТОЙНОСТ 1>, <СТОЙНОСТ 2>, ..., <СТОЙНОСТ N> }; // масив с N елемента +<ТИП> <ИМЕ>[N]; // само ги дефинираме, обаче не ги инициализираме +<ТИП> <ИМЕ>[N] = { <СТОЙНОСТ> }; // дефинира всички N елементи със <СТОЙНОСТ> +<ТИП> <ИМЕ>[N] = { <СТОЙНОСТ 1>, <СТОЙНОСТ 2>, ..., <СТОЙНОСТ M> }; // където M <= N +``` + +Самото `<ИМЕ>` е указател, така че може да достъпваме стойности чрез указателна аритметика: + +```cpp +int arr[2] = { 83, 18 }; +std::cout << (*(arr + 1)) << std::endl; +``` + +Връща втория елемент, `18`. + +Или чрез по-приятния синтаксис с квадратни скоби: + +```cpp +int arr[2] = { 83, 18 }; +std::cout << (arr[1]) << std::endl; +``` + +Двете неща са еквивалентни, тоест `name[x]` е еквивалентно на `*(name + x)`. + +Когато един масив съдържа букви, наричаме го "низ" (string). +За да не трябва да следим дължината на един низ в друга променлива и да трябва да я подаваме, винаги завършваме нашия низ на "терминаращата нула" - `'\0'`. |