[Autumn Series] Указатели

Аватар
Autumn Shade
Извън линия
Потребител
Потребител
Мнения: 269
Регистриран на: 14 Мар 2019, 13:20
Се отблагодари: 48 пъти
Получена благодарност: 150 пъти

[Autumn Series] Указатели

Мнение от Autumn Shade » 10 Окт 2019, 14:03

Съдържание:
  • Какво е указател?
  • Символните низове като указатели
  • Дереференциране
  • Упражнение
  • Какво следва?

Какво е указател?
Указателят по същество е просто променлива от тип цяло число, която в себе си съдържа адрес от паметта, който сочи към стойност. Указателят държи този адрес, който сочи към вече съществуваща стойност, вместо да съдържа в себе си самата стойност.

Компютърната памет запазва последователно информацията си и указателят сочи към една специфична част от тази памет. Нашата програма може да използва указателите по такъв начин, че те да сочат към една голяма част от паметта, в зависимост от колко ще използваме оттук нататък.

Указателите също са променливи и играят доста важна роля в цялото програмиране на C++ или C. Те биват използвани поради няколко причини, като:
  • Символни низове
  • Динамично заделяне на памет
  • Изпращане на параметри на функция по адрес
  • Указатели към функции
  • Изграждане на специални структурни данни като Tree, Trie, Vector, List и други..

Символните низове като указатели

Вече сме обсъждали символните низове или string-овете, затова тук ще видим как точно работят и ще разберете какво точно представлява символният низ. Тези символни низове направени чрез указатели се наричат C-String-ове, за да се различават от тези в C++ std::string.

Нека видим един пример:
char* name = "Autumn Shade";

Този пример прави следните неща:
  • Заделя памет за новата ни локална променлива наречена name, която е указател към първият символ от текста. (Тоест към A)
  • Кара символният низ Autumn Shade да се появи някъде из паметта на програмата (след като се компилира и изпълни, разбира се)
  • Аргументът name си задава начална стойност да сочи там, където е заделен символа A (който след това е последван от останалата част от символният низ)
Ако се опитаме да достъпим променливата name като масив, ще се получи и ще върне порядъчната стойност на A, тъй като променливата ни name сочи точно към началото на символният низ.

След като знаем, че паметта е последователна, можем да направим заключение, че ако се преместим напред в паметта към следващият символ, ще получим следващият символ в низа, докато не стигнем края му, маркиран с нулев разделител, наричан null terminator. (Символът с порядъчна стойност 0, означаващ се като \0)

Дереференциране
Дереференцирането е някакъв фалшив превод от Dereferencing, защото аз по друг начин не можех да си го обясня, за жалост, на родният ми език. То представлява действие на посочване на мястото, където сочи указателят, вместо адреса в паметта. Ние вече сме използвали тази техника в масивите, но не знаехме тогава. Квадратните скоби, например [0], достъпват първият елемент на масива. И след като масивите реално са указатели, достъпването на първият елемент в масива е същото като дереференцирането на указател.

Дереференцирането на указател се прави чрез оператора звезда. (*)

Ако искаме да създадем масив, който да сочи към друга променлива в нашата памет, тогава можем да го направим по следният начин:

Код за потвърждение: Избери целия код

#include <iostream>

using namespace std;

int main() {
	/*! Дефинираме си локална променлива с името a */
	int number = 5;
	
	/*! Дефинираме си указател и го насочваме накъде да сочи чрез оператора & */
	int* ptrToNumber= &number;
	
	cout << "Stoinostta na number e " << a;
	cout << "Stoinostta na ukazatelq kum number sushto e " << *ptrToNumber;
}
Забележете, че използвахме оператора &, за да насочим указателя да сочи към нашата променлива, която си създадохме.Тогава ги свързахме чрез дереференциране. Дерефернцирането позволява промяната на стойността на променливата към, която сочи указателят директно през указателя.

Как така? Нека видим един пример:

Код за потвърждение: Избери целия код

#include <iostream>

using namespace std;

int main() {
	int number = 5;
	int* ptrToNumber = &number;
	
	/*! Променяме стойността на променливата като нарастне с единица и стане 6 */
	number++;
	
	/*! Променяме още веднъж стойността на променлива чрез указателя като нарастне с единица и стане 7 */
	ptrToNumber++;
	
	/*! Тук ще изпише 7 */
	cout << "Stoinostta na number e " << number;
}

Упражнение
Направете си калкулатор като използвате указатели към променливите ви вместо самите променливи.

Какво следва?
В следващият пост ще преминем към указатели.

  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Системно Програмиране”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 10 госта