Перейти к основному содержимому

Указатель

Введение

Этот документ объясняет, как использовать указатели в Wave. Wave — это язык, поддерживающий низкоуровневое системное программирование, который предоставляет функциональность указателей для явного манипулирования адресами памяти. Указатель — это переменная, указывающая на адрес памяти конкретного типа, что позволяет напрямую получить доступ к значению и изменить его.


Объявление указателя

В Wave указатель объявляется в формате ptr<тип>. Например, указатель на целое число можно объявить следующим образом:

var p: ptr<i32>; 

Это объявление создает указатель p, указывающий на значение типа i32.


Инициализация указателя

Указатель можно инициализировать с помощью оператора &, указывающего адрес переменной:

var a: i32 = 10;
var p: ptr<i32> = &a;

Здесь &a означает адрес памяти переменной a, и p становится указателем на этот адрес.


Деференцирование указателя

Чтобы прочитать или изменить значение, на которое указывает указатель, используется ключевое слово deref. Это называется деференцированием:

var a: i32 = 10;
var p: ptr<i32> = &a;

println("{}", deref p); // выводит 10

deref p = 20;
println("{}", a); // выводит 20

NULL указатель

В Wave NULL указатель представлен ключевым словом null. Указатель может быть инициализирован значением null, в таком случае он не указывает ни на какую действительную память:

var p: ptr<i32> = null; 

Попытка деференцировать NULL указатель приводит к ошибке компиляции.


Множественный указатель

Wave поддерживает множественные указатели. Указатели могут быть вложены на несколько уровней и использованы:

var x: i32 = 1;
var p1: ptr<i32> = &x;
var p2: ptr<ptr<i32>> = &p1;
var p3: ptr<ptr<ptr<i32>>> = &p2;

println("{}", deref p1); // выводит 1
println("{}", deref deref p2); // выводит 1
println("{}", deref deref deref p3); // выводит 1

Массив и указатель

Указатель также может указывать на элементы массива или на сам массив.

Указатель, указывающий на элементы массива

var a: i32 = 10;
var b: i32 = 20;
var arr: array<ptr<i32>, 2> = [&a, &b];

println("deref arr[0] = {}, deref arr[1] = {}", deref arr[0], deref arr[1]); // выводит 10, 20

Указатель, указывающий на весь массив

var arr: ptr<array<i32, 3>> = &[1, 2, 3];
println("{}", arr); // выводит адрес памяти

Безопасность и владение

Wave внедряет систему владения и времени жизни, схожую с Rust, чтобы обеспечить безопасное использование указателей. Поэтому тщательно проверяются операции, чтобы избежать проблем с недействительными указателями, двойным освобождением и висячими указателями.

веселье main() {
пусть х: i32 = 42;
пусть р: ptr<i32> = &x;

печатайте("x = {}", разыменовать р);

разыменовать р = 99;
печатайте("x = {}", х);
}

Вывод:

х = 42
х = 99

Вывод

Указатели являются одной из ключевых функций, позволяющих высокопроизводительное программирование низкого уровня в Wave. Это чрезвычайно полезно для разработки систем, требующих прямого управления памятью, нативных библиотек, управления оборудованием и т.д. Благодаря безопасной структуре компилятора Wave, потенциальные опасности, которые могут возникнуть при использовании указателей, эффективно предотвращаются.