На этом шаге мы рассмотрим использование указателей на указатели.
В языке C# мы можем создавать указатели на указатели. Другими словами, мы можем объявить указатель, значением которого является адрес другого указателя, в который записывается адрес обычной переменой. Допускается создание и более глубоких цепочек указателей, но на практике это используется не так часто.
Чтобы понять, как объявляется указатель на указатель, следует учесть, что при объявлении указателя с использованием идентификатора типа, на значение которого может ссылаться указатель, указывается звездочка *. Например, инструкция int* используется при объявлении указателя на переменную типа int. Тогда при объявлении указателя на указатель на значение типа int используется идентификатор int**. Как иллюстрацию к использованию указателей на указатели рассмотрим программу ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr214_1 { // Главный класс: class Program { // Главный метод: unsafe static void Main() { // Целочисленные переменные: int A, B; // Указатель на целочисленную переменную: int* p; // Указатель на указатель на целочисленную // переменную: int** q; // Значение указателя на указатель: q = &p; // Значение указателя: p = &A; // Переменной A присваивается значение // (через указатель на указатель): **q = 123; // Проверка значения переменной A: Console.WriteLine(A); // Новое значение указателя: *q = &B; // Переменной B присваивается значение // (через указатель): *p = 321; // Проверка значения переменной B: Console.WriteLine(B); } } }
Ниже показано, каким будет результат выполнения программы:
Рис.1. Результат выполнения программы
В программе мы объявляем переменные A и B типа int, указатель p на значение типа int, а командой
int** q;
Командой
q = &p;
p = &A; .
**q = 123;
А вот когда выполняется команда
*q = &B; ,
*р = 321;
На следующем шаге мы рассмотрим массивы указателей.