Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ПИ Программирование на С# _Хотов.docx
Скачиваний:
11
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆
        1. Указатель на другой указатель

Объявление и использование указателя на указатель:

static void Main(string[] args)

{

unsafe

{

int* x; // определение указателя

int y = 10; // определяем переменную

x = &y; // указатель x теперь указывает на адрес переменной y

int** z = &x; // указатель z теперь указывает на адрес, который указывает и указатель x

**z = **z + 40; // изменение указателя z повлечет изменение переменной y

Console.WriteLine(y); // переменная y=50

Console.WriteLine(**z); // переменная **z=50

}

Console.ReadLine();

}

      1. Указатели на структуры, члены классов и массивы

        1. Указатели на типы и операция ->

Кроме указателей на простые типы можно использовать указатели на структуры. А для доступа к полям структуры, на которую указывает указатель, используется операция ->:

class Program

{

static void Main(string[] args)

{

unsafe

{

Person person;

person.age = 29;

person.height = 176;

Person* p = &person;

p->age = 30;

Console.WriteLine(p->age);

// разыменовывание указателя

(*p).height = 180;

Console.WriteLine((*p).height);

}

}

}

public struct Person

{

public int age;

public int height;

}

Обращаясь к указателю p->age = 30; мы можем получить или установить значение свойства структуры, на которую указывает указатель. Обратите внимание, что просто написать p.age=30 мы не можем, так как p - это не структура Person, а указатель на структуру.

Альтернативой служит операция разыменования: (*p).height = 180;

        1. Указатели на массивы и stackaloc

С помощью ключевого слова stackaloc можно выделить память под массив в стеке. Смысл выделения памяти в стеке в повышении быстродействия кода. Посмотрим на примере вычисления факториала:

unsafe

{

const int size = 7;

int* factorial = stackalloc int[size]; // выделяем память в стеке под семь объектов int

int* p = factorial;

*(p++)= 1; // присваиваем первой ячейке значение 1 и

// увеличиваем указатель на 1

for (int i = 2; i <= size; i++, p++)

{

// считаем факториал числа

*p = p[-1] *i;

}

for (int i = 1; i <= size; ++i)

{

Console.WriteLine(factorial[i-1]);

}

}

Оператор stackalloc принимает после себя массив, на который будет указывать указатель. int* factorial = stackalloc int[size];.

Для манипуляций с массивом создаем указатель p: int* p = factorial;, который указывает на первый элемент массива, в котором всего 7 элементов

Далее начинаются уже сами операции с указателем и подсчет факториала. Так как факториал 1 равен 1, то присваиваем первому элементу, на который указывает указатель p, единицу с помощью операции разыменования: *(p++)= 1;

Из прошлой темы мы узнали, что чтобы вложить некоторое значение по адресу, который хранит указатель, надо использовать выражение: *p=1. Но кроме этого тут происходит также инкремент указателя p++. То есть сначала первому элементу массива присваивается единица, потом указатель p смещается и начинает указывать уже на второй элемент. Мы могли бы написать это так:

*p= 1;

p++;

Чтобы получить предыдущий элемент и сместиться назад, можно использовать операцию декремента: Console.WriteLine(*(--p));. Обратите внимание, что операции *(--p) и *(p--) различаются, так как в первом случае сначала идет смещение указателя, а затем его разыменовывание. А во втором случае - наоборот.

Затем вычисляем факториал всех остальных шести чисел: *p = p[-1] *i;. Обращение к указателям как к массивам представляет альтернативу операции разыменовывания для получения значения. В данном случае мы получаем значение предыдущего элемента.

И в заключении, используя указатель factorial, выводим факториалы всех семи чисел.