С Новым годом! Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
6 / 3 / 3
Регистрация: 25.06.2018
Сообщений: 24
1

Задать тип массива через переменную

30.10.2019, 00:08. Показов 431. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Народ, нужна ваша помощь. В общем, ситуация такая: В зависимости от условий, необходимо проинициализировать массив как byte, word, longword или как uint64. Создать 4 разных массива не катит. Нужно, чтобы получилось что-то на подобии:

Pascal
1
2
var z1 : тип данных;
var z2 : array of z1;
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.10.2019, 00:08
Ответы с готовыми решениями:

Как задать размер массива через переменную?
Каким образом можно создать массив объектов, если его размер можно определить только по ходу...

Задать размер динамического массива через переменную, обявленную как extern
Привет народ, скажите, почему не компилирует: #include"stdafx.h" #include"iostream" using...

Как задать style через переменную?
В прорисовке формы, как сделать, чтобы цвет бордюра можно было менять в зависимости от условия?...

Задать свойство объекта через переменную
Добрый день. Есть такой код: $('.sliderBlock .textInput').on("blur", function() { ...

5
2351 / 1454 / 526
Регистрация: 07.04.2017
Сообщений: 4,791
30.10.2019, 00:53 2
Назовите изначальную задачу. Записать разные типы массивов в 1 переменную можно, но точно не так как вы показали в том псевдокоде.
0
6 / 3 / 3
Регистрация: 25.06.2018
Сообщений: 24
30.10.2019, 01:08  [ТС] 3
Задача не в том, чтобы записать разные типы массивов в какую-либо переменную, а в том, чтобы 1 единственный одномерный массив, в зависимости от условий, имел тип данных либо byte, либо word, либо longword, либо uint64. То есть этот массив должен 1 раз проинициализироваться, став массивом того типа данных, который мне нужен.
0
2351 / 1454 / 526
Регистрация: 07.04.2017
Сообщений: 4,791
30.10.2019, 01:39 4
Нет, я спрашивал не это. Вы говорите о решении (использовании переменной в которую можно записать разные типы массивов) которое вы додумали сами. А в чём состоит задача для которой вы решили что такое необходимо?

Цитата Сообщение от Anaglyph Посмотреть сообщение
Задача не в том, чтобы записать разные типы массивов в какую-либо переменную, а в том, чтобы 1 единственный одномерный массив, в зависимости от условий, имел тип данных
"Не масло а масляное". В данном языке строгая типизация, то есть если вы объявили переменную как byte - в неё не записать значение типа string. А array of byte и array of word - это совершенно разные типы. Поэтому вопрос сводиться к тому как создать переменную, в которую всё же можно будет записать 2 и более разных типов массивов.

А возможно это только через наследование.

У всех типов есть базовый класс object.
Однако если присвоить переменной типа object массив - работать с ним можно будет только при каждом действии проверяя, каким типом массива он является. Это довольно много кода и чуток медленно.

Так же все массивы наследуют от типа System.Array. И у него уже есть абстрактные методы для чтения и записи элементов.
Но чтоб у него получить/записать элемент через System.Array - его надо сначала запаковать в object, а потом распаковать. А так как у вас все типы элементов - записи (а точнее числа на 8 16 32 и 64 бит) - это будет чрезвычайно затратная операция.

Лучше сделать свою обёртку для массивов, как то так:
Pascal
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
38
39
40
41
42
type
  ArrDataBase = abstract class
    
    procedure DoThing; abstract;
    
  end;
  
  ArrData8 = sealed class(ArrDataBase)
    a: array of byte;
    
    constructor(l: integer) :=
    self.a := new byte[l];
    
    procedure DoThing; override;
    begin
      writeln(a.GetType);
    end;
    
  end;
  ArrData16 = sealed class(ArrDataBase)
    a: array of word;
    
    constructor(l: integer) :=
    self.a := new word[l];
    
    procedure DoThing; override;
    begin
      writeln(a.GetType);
    end;
    
  end;
  
begin
  var a: ArrDataBase;
  
  case ReadInteger('8: byte'#10'16: word'#10'>') of
    8: a := new ArrData8(ReadInteger('l ='));
    16: a := new ArrData16(ReadInteger('l ='));
  end;
  
  a.DoThing;
end.
Но, ещё раз, вы явно додумали себе какую то фигню, поэтому озвучьте изначальную задачу, чтоб можно было дать вам нормальное решение.
1
6 / 3 / 3
Регистрация: 25.06.2018
Сообщений: 24
30.10.2019, 02:16  [ТС] 5
Изначальная задача такая: пишу интерпретатор языка brainf*ck, в котором можно выбрать битность ячейки. 8, 16, 32 и 64 бит соответственно. И я бы особо и не парился, создал бы массив uint64 и в зависимости от выбранной битности просто бы обнулял значение ячейки при достижении максимального значения + 1 для выбранной битности, но я подумал, что можно все решить по красоте и просто проинициализировать массив, чтобы его ячейки были такой битности, которой мне нужны. Ну раз в pascal abc net нет тривиального способа это сделать, то просто сделаю так, как описал выше. Но тем не менее, спасибо за помощь.
0
2351 / 1454 / 526
Регистрация: 07.04.2017
Сообщений: 4,791
30.10.2019, 11:48 6
В таком случае имеет смысл делать неуправляемой памятью. Ей вообще без разницы каким типом данных считать её байты. И скорость доступа довольно большая.

Так же, в брейнфаке типа как бесконечный объём памяти, но в реальности так не работает. Поэтому выделять память надо по мере надобности. В примере ниже я поставил 4 килобайта.
Но вообще это рандомно взятое с головы значение. Точнее это объём ячейки памяти на большинстве SSD дисков. То есть если вы будете сбрасывать память на диск - будет очень быстро и удобно, правда я вообще хз зачем)).
Но, главное чтоб это число делилось на 8 (потому что размер uint64) и было не меньше 8 (опять же, чтоб uint64 помещалось). А так - можете ставить там какое то своё число.

А вот и сам пример. Реализовал я не всё, движение вправо и чтение делается по аналогии с тем что уже есть. Ну а увеличение значения ячейки - это по сути Write(Read+1).

И если что - то что при чтении/записи данные передаются как 64-битное число, это вообще не проблема, ни скорости не памяти.
Память на стеке по сути бесконечная (если не насиловать его рекурсией).
А скорость, если у вас конечно не 32-битный процессор - 64-битные числа будут обрабатываться не медленнее 32-битных.
И точно быстрее 8 битных, потому что для сложения 2 значений типа byte - процессор всё равно преобразовывает их в integer.
Pascal
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
uses System;
 
type
  MemoryBlock = sealed class
    private const data_size = 4096; // Сколько байт в 1 выделяемом блоке памяти
    private data: IntPtr; // указатель на сам блок памяти
    private l_bl, r_bl: MemoryBlock; // точки связи для связного списка из блоков
    private unit_size: integer; // кол-во байт в 1 единице памяти. То есть 1, 2, 4 или 8
    private pos: integer; // позиция (в байтах) указателя в этом блоке (если указатель в другом блоке - значение тут по сути мусор)
    
    static procedure RtlZeroMemory(ptr: IntPtr; length: integer);
    external 'kernel32.dll';
    
    public constructor(unit_size: integer; l_bl, r_bl: MemoryBlock);
    begin
      self.unit_size := unit_size;
      self.l_bl := l_bl; if l_bl<>nil then l_bl.r_bl := self;
      self.r_bl := r_bl; if r_bl<>nil then r_bl.l_bl := self;
      self.data := System.Runtime.InteropServices.Marshal.AllocHGlobal(data_size);
      RtlZeroMemory(data, data_size); // обнуляем все байты
    end;
    
    protected procedure Finalize; override :=
    System.Runtime.InteropServices.Marshal.FreeHGlobal(data); // неуправляемые данные всегда надо освобождать при удалении объекта MemoryBlock, а то будет утечка памяти
    
    // возвращаемое значение будет не текущим блоком если точка памяти вышла за текущий блок
    // использование подразумевается как "текущий_блок := текущий_блок.MoveLeft"
    public function MoveLeft: MemoryBlock;
    begin
      pos -= unit_size;
      // если память закончилась - выделяем новый блок и скрепляем в связный список с текущим блоком
      if pos<0 then
      begin
        // если левый блок уже есть - надо только переключиться на него. Иначе создаём новый
        Result := self.l_bl=nil ? new MemoryBlock(unit_size, nil, self) : self.l_bl;
        Result.pos := data_size-unit_size; // позиция считаеться с 0, поэтому надо отойти на 1 юнит от конца, чтоб не читать/записывать мимо памяти
      end else
        Result := self;
    end;
    
    public procedure SetVal(v: uint64);
    begin
      var ptr := pointer(data + pos);
      case unit_size of
        1: PByte(ptr)^     := v; // лишние биты v обрежет автоматически из за присвоения другому типу, на данной строчке запишет только 8 младших бит
        2: PWord(ptr)^     := v;
        4: PLongint(ptr)^  := v;
        8: PUInt64(ptr)^   := v;
      end;
    end;
    
  end;
  
begin end.
P.S. А цензурить название языка не к чему, из песни слов не вырежешь)))
1
30.10.2019, 11:48
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.10.2019, 11:48
Помогаю со студенческими работами здесь

Задать цвет Label через переменную
Допустим, у меня есть стринговая переменная TextColor, которая может быть равна какому-то...

Задать сетевой путь через переменную
Снова нубо вопрос.. ) как правильно задать сетевой путь? Через пуск - выполнить - 18.234.54.437...

Задать ширину блока через переменную
Необходимо задать ширину при помощи переменной $size = 200; &lt;div style=&quot;height: 200px; width:...

Как задать размеры агрегируемого через переменную?
Вот пример: class child{ public: string surname; string address; char gender;...

Задать цвет заливки при действии через переменную
В CastomControl нужно добавить ещё одну кисть, которая будет закрашивать фон кнопки при наведении....

Задать имя поля в таблице через переменную в процедуре Акцесс
Всем привет! Прошу помощи. Есть таблица поля которой отображают компоненты сырья, а строки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
Что такое NullReferenceEx­ception и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее: На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru