понедельник, 3 января 2022 г.

Указатели и ссылки

  1. Ссылка и указатель на самом деле ничем не отличаются, кроме того, что ссылка инициализируется один раз и её нельзя переоределить + синтаксис другой. Например, если ссылка на класс, то для обращения к членам используется точка . вместо ->


Так, на пальцах:


Вот у Вас есть переменная int a

Это такая буковка, с помощью которой компилятор умеет определить, о чём Вы ему говорите. 

Он знает, что за буковкой a кроется значение в памяти, расположенное по какому-то адресу (адрес в памяти — это число). 

Ну, Вы же понимаете, что переменная — это такая штука, чтобы удобно по имени обращаться к данным, записанным в определённом участке памяти.

Так вот, указатель — это, тупо, то самое число, тот самый адрес. 

Т.е. &a равно именно в точности адресу в памяти, по которому хранится значение. 

Чтобы избежать невнятных проблем, тип «указатель на int (или на любой другой тип) — int*» — это такой совершенно отдельный тип.

Итак есть два волшебных оператора: * и &

Второй по данной переменной узнаёт её адрес в памяти. 

Первый по данному адресу (который, как мы помним, хранится в переменной типа int*) возвращает собственно данные, расположенные по этому адресу.


Что-то Вы, видимо, не то читали… Обычно в книжках крайне понятно излагают…

Так, на пальцах:


Вот у Вас есть переменная int a. Это такая буковка, с помощью которой компилятор умеет определить, о чём Вы ему говорите. Он знает, что за буковкой a кроется значение в памяти, расположенное по какому-то адресу (адрес в памяти — это число). Ну, Вы же понимаете, что переменная — это такая штука, чтобы удобно по имени обращаться к данным, записанным в определённом участке памяти.

Так вот, указатель — это, тупо, то самое число, тот самый адрес. Т.е. &a равно именно в точности адресу в памяти, по которому хранится значение. Чтобы избежать невнятных проблем, тип «указатель на int (или на любой другой тип) — int*» — это такой совершенно отдельный тип.

Итак есть два волшебных оператора: * и &. Второй по данной переменной узнаёт её адрес в памяти. Первый по данному адресу (который, как мы помним, хранится в переменной типа int*) возвращает собственно данные, расположенные по этому адресу.

int a = 566;
// Завели переменную. Число 566 записалось в память по какому-то адресу

// &a — адрес, по которому записалось число

int *p;
// Переменная типа «указатель на int»
// На самом деле понятно, что все указатели на все типы — одна малина. Это просто
// 32-битные числа. Но C++ строго типизированный язык, потому нельзя непосредственно
// присвоить char* к int*

// Зато можно присвоить int* к int*
p = &a; // Как мы помним, &a возвращает адрес в памяти

int b = *p;
// Теперь в переменной b лежит ЗНАЧЕНИЕ, которое находится по адресу, на который
// указывает p (а как мы знаем, p указыает туда, где лежит значение a)

b == a;
// Это верно

// На данный момент у нас в переменных a и b лежит одно и то же число.

int *p2 = &b;
// Теперь p указывает на a, а p2 — на b.
// a=566, b=566, *p=566, *p2=566

*p2 = 777;
// По адресу, на который указывает p2, положили число 777. Как мы помним, p2
// указывает туда, где лежит значение b. Значит теперь b = 777.

p = &b;
// Теперь оба указателя указывают на одну и ту же ячейку в памяти.

Комментариев нет:

Отправить комментарий

Паттерн 'Репозиторий' в ASP.NET

  Последнее обновление: 1.11.2015         Одним из наиболее часто используемых паттернов при работе с данными является паттерн 'Репозито...