Summary Files Commits Branches @commit @diff @stats
path: root / src / teaching / upp-2023 / week5 / revision.md
diff options
context:
space:
mode:
1 files changed, 83 insertions, 0 deletions
-rw-r--r--src/teaching/upp-2023/week5/revision.md83
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'`.