основе типа int* создает новую структуру int, а потом на основе нового типа int создает структуру int* ?
P.s. Если нет, то как тогда реализуются тип указателей на указатель, указывающий на ещё один указатель и тд...
Все что делает инструкция int* a; - объявляет переменную a типа int* Кусок int в int* означает лишь то, что при разыменовании получается int Никаких "структур int" не существует. int*** a значит что при разыменовании а получается int**. При разыменовании int** получается int*. Потом int. По сути хранишь адрес на адрес на адрес на int.
Чë чë чë? Помедленнее, я записываю...
Рассматривай указатель как число
Минуточку забыл
Указатель - адрес ячейки памяти где что то лежит ( поэтому и нельзя взять указатель на регистр процессора )
int * a; объявляет указатель (можно сказать переменную с именем “a”, в которой можно сохранить адрес ячейки памяти. В этой ячейке памяти можно сохранить число, имеющее тип int. Если ты просто напечатаешь указатель на экран, то будет выведено какое то число, это адрес. (Компьютер сам знает какая ячейка памяти может быть использована , ты сам адрес не задаёшь переменной указателю- это проблемы операционной системы где конкретно можно в этот момент времени выделить свободную ячейку памяти. К переменной-указатель таким образом привязывается этот адрес свободней ячейки. В неё потом можно уже сохранить какое то полезное значение типа int (допустим число тысяча ), для надо использовать так называемое разыменование. Для этого опять надо использовать звездочку! Чтоб сохранить тысячу в ячейку, адрес , которой есть в указателе надо написать вот так *a = 1000; точно также и можно прочитать (тоже впереди переменной - указателя поставить звездочку ).int k = *a; Указатель может быть и на другое типы данных. Ты сам объявляешь на какой тип данных тебе нужен указатель. Иногда указатель указывает только на начало данных - бывают случаи , когда полезных данных много и они не помещаются в одну ячейку,например массив данных. Тогда , если разыменовать указатель ты можешь прочитать (или записать )значение в эту начальную ячейку данных. А чтоб перейти к следующей ячейке надо сам указатель сместить на следующую ячейку через команду ++ ( а++). Иногда если тип данных занимает не строго одну ячейку, адрес следующей ячейки после ++ будет не обязательно больше именно на единицу (но это нас не особо интересует какой именно адрес записан в указателе - нам важно , что мы можем через звездочку добраться до этого участка памяти и записать или считать значение. Какой именно адрес был записан в переменной -указателе практического смысла особо не имеет. Если только ради интереса посмотреть как работает адресная арифметика (можно напечатать адрес ячейки до операции ++ и после, и посмотреть какой именно адрес получился после ++). Что же касается двух звёздочек при объявлении - как например , int ** prt ; тут принцип такой же - мы объявляем указатель prt, в котором можно сохранить полезное значение (но в данном случае полезным значением будет не само число int, а адрес другой ячейки памяти , то есть при разыменовании указателя ptr мы сможем прочитать число -адрес другой ячейки , которая хранится в ячейке по указателю ptr). Чтоб попасть уже туда надо просто поставить ещё одну звездочку (мы сначала как бы считываем значение ячейки памяти ptr, и сразу же разыменовываем уже этот считанный адрес , и тогда пропадаем в конце концов в ячейку, где может храниться само число int. То есть вот так можно записать тысячу один туда **ptr = 1001;
Адрес НЕ ЧИСЛО! И int туда нельзя записать. Можно порой ИНТЕРПРЕТИРОВАТЬ данные адреса как число, и его таким образом распечатать. Но это не всегда.
А разве адрес не номер конкретного байта по определению? А номер это число
В примитивном понимании - да. Это так в учебниках можно и нужно объяснять. Линейное адресное пространство, одинаковые ячейки в нём, и номера от 0 до N. В техническом плане всё может быть совсем не так.
А, вы про страничную организацию? Тип что на самом деле у нас есть страницы, в страницах строки и столбцы. И на самом деле указатель - это не число, а соединённые вместе номер страницы, номер строки и тд
И откуда вы все это берете
Страничная организация памяти прозрачна для программных средств. И там как раз всё хорошо - плоская модель памяти, все дела, и розовые пони. Но вот что на всех на свете процессорах всё именно так же - я не брался бы утверждать.
Начнем с того, что у абстрактной машины С++ указатели на объекты, а не на память...
Я до плюсов ещё не дошел) Пока на Си
всё ещё strict aliasing и прочие фичи
Так это... а разве в Си тоже не всё подряд объектами зовётся?
А объекты где лежат ? Указатель на объект определяет арифметику указателей в соответствии с типом объекта.
это больше про примеры template <typename T> void foo(T& t) { t.~T(); new (std::addressof(t)) T(); } int bar() { int x = 0; int * y = &x; foo(x); return *y; //до C++20 нельзя, в 20 вроде можно уже }
потому что автопрачечной еще нет)
До 20 надо возвращать результат placement new из foo и разыменовывать его, угу
Обсуждают сегодня