Массив ссылок си шарп
Кроме указателей на простые типы можно использовать указатели на структуры. А для доступа к полям структуры, на которую указывает указатель, используется операция ->:
unsafe < Point point = new Point(0, 0); Console.WriteLine(point); // X: 0 Y: 0 Point* p = &point; p->X = 30; Console.WriteLine(p->X); // 30 // разыменовывание указателя (*p).Y = 180; Console.WriteLine((*p).Y); // 180 Console.WriteLine(point); // X: 30 Y: 180 > struct Point < public int X < get; set; >public int Y < get; set; >public Point(int x, int y) < X = x; Y = y; >public override string ToString() => $"X: Y: "; >
Обращаясь к указателю p->X = 30; мы можем получить или установить значение свойства структуры, на которую указывает указатель. Обратите внимание, что просто написать p.X=30 мы не можем, так как p — это не структура Point, а указатель на структуру.
Альтернативой служит операция разыменования: (*p).X = 30;
Стоит отметить, что указатель может указывать только на те структуры, которые не имеют полей ссылочных типов (в том числе полей, которые генерируются компилятором автоматически для автосвойств).
Указатели на массивы и stackalloc
С помощью ключевого слова stackalloc можно выделить память под массив в стеке. Смысл выделения памяти в стеке в повышении быстродействия кода. Посмотрим на примере вычисления квадратов чисел:
Оператор stackalloc принимает после себя массив, на который будет указывать указатель. int* square = stackalloc int[size]; .
Для манипуляций с массивом создаем указатель p: int* p = square; , который указывает на первый элемент массива, в котором всего 7 элементов. То есть с помощью указателя p мы сможем перемещаться по массиву square.
Далее в цикле происходит подсчет квадратов чисел от 1 до 7. В цикле для установки значения (квадрата числа — i * i) по адресу, который хранит указатель, выполняется выражение:
Затем происходит инкремент указателя p++ , и указатель p смещается вперед на следующий элемент в массиве square.
Чуть более сложный пример — вычисление факториала:
Также с помощью оператора stackalloc выделяется память для 7 элементов массива. И также для манипуляций с массивом создаем указатель p: int* p = factorial; , который указывает на первый элемент массива, в котором всего 7 элементов
Далее начинаются уже сами операции с указателем и подсчет факториала. Так как факториал 1 равен 1, то присваиваем первому элементу, на который указывает указатель p, единицу с помощью операции разыменования: *(p++)= 1;
Для установки некоторого значения по адресу указателя применяется выражение: *p=1 . Но кроме этого тут происходит также инкремент указателя p++ . То есть сначала первому элементу массива присваивается единица, потом указатель p смещается и начинает указывать уже на второй элемент. Мы могли бы написать это так:
Чтобы получить предыдущий элемент и сместиться назад, можно использовать операцию декремента: Console.WriteLine(*(—p)); . Обратите внимание, что операции *(—p) и *(p—) различаются, так как в первом случае сначала идет смещение указателя, а затем его разыменовывание. А во втором случае — наоборот.
Затем вычисляем факториал всех остальных шести чисел: *p = p[-1] *i; . Обращение к указателям как к массивам представляет альтернативу операции разыменовывания для получения значения. В данном случае мы получаем значение предыдущего элемента.
И в заключении, используя указатель factorial, выводим факториалы всех семи чисел.
Оператор fixed и закрепление указателей
Ранее мы посмотрели, как создавать указатели на типы значений, например, int или структуры. Однако кроме структур в C# есть еще и классы, которые в отличие от типов значений, помещают все связанные значения в куче. И в работу данных классов может в любой момент вмешаться сборщик мусора, периодически очищающий кучу. Чтобы фиксировать на все время работы указатели на объекты классов используется оператор fixed .
Допустим, у нас есть класс Point:
Зафиксируем указатель с помощью оператора fixed:
unsafe < Point point = new Point(); // блок фиксации указателя fixed (int* pX = &point.x) < *pX = 30; >fixed (int* pY = &point.y) < *pY = 150; >// можно совместить оба блока /*fixed (int* pX = &point.x, pY = &point.y) < *pX = 30; *pY = 150; >*/ Console.WriteLine(point); // x: 30 y: 150 >
Оператор fixed создает блок, в котором фиксируется указатель на поле объекта person. После завершения блока fixed закрепление с переменных снимается, и они могут быть подвержены сборке мусора.
Кроме адреса переменной можно также инициализировать указатель, используя массив, строку или буфер фиксированного размера:
unsafe < int[] nums = < 0, 1, 2, 3, 7, 88 >; string str = "Привет мир"; fixed(int* p = nums) < int third = *(p+2); // получим третий элемент Console.WriteLine(third); // 2 >fixed(char* p = str) < char forth = *(p + 3); // получим четвертый элемент Console.WriteLine(forth); // в >>
При инициализации указателей на строку следует учитывать, что указатель должен иметь тип char* .
Передача массива в функцию
Если в си шарп массивы передаются по ссылке, почему после функции init «а» не указывает на новую область?
Передача массива в функцию
Здравствуйте, столкнулся с проблемой передачи массива в функцию. Проблема в том, что в функции z1.
Передача массива в функцию
Здравствуйте. Возник вопрос по передаче массивов в функцию.. Вот код: class Arr < //.
Передача массива в функцию
Здравствуйте! Подскажите, пожалуйста, как правильно сделать инициализацию и вывод массива двумя.
передача массива в функцию
есть массив double a = new double; double b = new double; как правильно вызвать? .
static void init(out int[] a)
Я не уверен, но вроде когда вы в метод передаёте массив, то для этого метода создаётся копия этого массива(типа локального массива для этого метода). В результате что бы вы не делали с массивом внутри метода, на оригинальный массив никак не действует
Добавлено через 40 секунд
Так же и с обычными переменными.
Сообщение было отмечено amaralikyr как решение
Решение
Сообщение от amaralikyr
Если в си шарп массивы передаются по ссылке, почему после функции init «а» не указывает на новую область?
Сообщение от amaralikyr
для передачи «ссылки по ссылке», используйте ключовое слово ref
Добавлено через 9 минут
Сообщение от Roma12
Я не уверен, но вроде когда вы в метод передаёте массив, то для этого метода создаётся копия этого массива(типа локального массива для этого метода). В результате что бы вы не делали с массивом внутри метода, на оригинальный массив никак не действует
Добавлено через 40 секунд
Так же и с обычными переменными.
«обычные переменные», как вы выразились, являються типами значений, массив же являеться ссылочным типом.
При передаче массива в метод, происходит передача копии ссылки из стека, сам же массив храниться в куче.
Автор же в статическом методе создает новый массив, и присваивает этой копии ссылки этот новый массив. При выходе из метода, стек очищаеться, все ссылки на новый массив удаляються, в следствии чего массив будет подчищен GC.
Для того, что б все это с массивом работало, как с «обычными переменными», надо передать через ref
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static void init(ref int[] a) { a = new[] { 1, 2, 3 }; } static void Main() { int[] a = { 3, 2, 1 }; init(ref a); Console.WriteLine(a[0]); Console.WriteLine(a[1]); Console.WriteLine(a[2]); //вывод 1 2 3 }
Массив из ссылок
Массив ссылок
Для проверки определить массив ссылок на абстрактный класс, которым присваиваются адреса различных.
Массив из ссылок
есть меню состоящее из ссылок как мне создать массив из этих ссылок используя.
Массив ссылок на jquery
Приветствую ребята! Подскажите как на jquery реализовать массив ссылок? То есть много ссылок на.
Редактировать массив ссылок
у меня есть массив ссылок, вида: ./i2018i217.html Мне нужно на все такие ссылки попереходить. Но.
Ладно, лучше проясню истинную проблему.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
public class ADX_Configurations { public ADX_Configurations(Listint> _Period, ListMaType> _Ma_Type) { Periods = _Period; Ma_Types = _Ma_Type; } public Listint> Periods { get; private set; } public ListMaType> Ma_Types { get; private set; } public ADX[] Get_ADX_Array() { ADX[] result = new ADX[Periods.Count * Ma_Types.Count]; int i = 0; foreach (var _Period in Periods) foreach (var _Ma_Type in Ma_Types) result[i++] = new ADX(_Period, _Ma_Type); return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13
var Robot_Settings = Tuple.Create ( // TF0 Tuple.Create ( (new ADX_Configurations(new Listint> { 2, 3 }, new ListMaType> { MaType.Simple })).Get_ADX_Array() ), // TF1 Tuple.Create ( (new ADX_Configurations(new Listint> { 5 }, new ListMaType> { MaType.Exponential, MaType.Simple })).Get_ADX_Array() ) );
TimeFrame_class[] tf = new TimeFrame_class[2];
В этом классе хранится экземпляр класса ADX, который мы добавляем из Robot_Settings
Нужно составить массив комбинаций, вида:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
combos [ 0 [ tf0 [ ADX0 ], tf1 [ ADX0 ] ], 1 [ tf0 [ ADX0 ], tf1 [ ADX1 ] ], 2 [ tf0 [ ADX0 ], tf1 [ ADX2 ] ], . ]
,
То есть массив вида combo[].tf[].adx[]
Но, не создавать кучу экземпляров tf[].adx[], ссылаться на экземпляры из Robot_Settings
А если вместо массива комбинаций сделать, например, класс, который будет однозначно идентифицировать себя с определёнными параметрами из заданного набора?
Fleder, этим классом как раз является TimeFrame_class
Просто, если расплодить так 100 классов, то памяти будет уходить в 100 раз больше, нежели если мы будем делать всё в одном месте, просто брать оттуда нужные комбинации параметров.
а зачем что-то создавать? 2 цикла не спасут отца русской демократии? ведь создание этого нечто и поддержание его в актуальном состоянии тоже требуются затраты, да и считывание упрется в те же 2 цикла
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
public partial class TimeFrame_class { public TimeSpan Period { get; private set; } public ListCandle> Buffer { get; private set; } public MA[][] all_ma { get; private set; } // это вместо ADX предыдущего примера public MA[] ma { get; set; } public int Combos_Count { get; private set; } public TimeFrame_class(int _Period_Seconds) { Period = TimeSpan.FromSeconds(_Period_Seconds); Buffer = new ListCandle>(); } // Установка индикаторов в текущем ТФ public void Set_Indicators(ListMA[]> _mas) { all_ma = _mas.ToArray(); // Считаем количество комбинаций Combos_Count = all_ma.Select(inds => inds.Length).Aggregate((p, x) => p *= x); } . }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
tf[0].Set_Indicators ( // MAs _mas: new ListMA[]> { // MA[0] Get_MA_Combos(new Listint> { 2, 3 }, new ListMaType> { MaType.Simple }, new ListCalculationType> { CalculationType.Close, CalculationType.Median }), // MA[1] Get_MA_Combos(new Listint> { 1 }, new ListMaType> { MaType.Simple }, new ListCalculationType> { CalculationType.Close, CalculationType.Median }) } ); tf[1].Set_Indicators ( // MAs _mas: new ListMA[]> { // MA[0] Get_MA_Combos(new Listint> { 4 }, new ListMaType> { MaType.Simple }, new ListCalculationType> { CalculationType.Close, CalculationType.Median }), } );
i`й элемент массива all_ma содержит комбинации класса MA для i`й элемента массива ma
Есть функция MyLovelyFunc, которую нужно вызывать для каждой новой комбинации для массива tf[]
Diamante, если делать через foreach или другие циклы, то для 2 экземпляров TimeFrame_class по 3 индикатора (наподобие MA) будет 6 циклов) Один раз уже кое-кто пробовал, вот, что получилось