Принять массив неизвестного размера в процедуре RPG

Я пытаюсь создать процедуру, которая будет принимать массив и возвращать количество использованных элементов (почему это не BIF ??). Я изо всех сил пытаюсь найти способ передать в мою процедуру массив неизвестного размера.

Что-то вроде...

P count         B
D count         PI              3  0 
D  array                         *
D  size                        10  0
D  elems                        3  0
 *
D ct            S               3  0
 /free
  // find the first blank or zero element and return 
 /end-free
P count         E

Очевидно, я новичок в этом, поэтому у меня есть пара вопросов:

  1. Есть ли способ передать элементы size и max в качестве параметров (или, может быть, способ передать своего рода пакет заголовка с подробной информацией о данных)?
  2. Есть ли способ определить, к какому типу относятся данные? (чтобы я знал, искать ли * НУЛИ или * ПРОБЕЛЫ)
  3. Мне не хватает другого, лучшего подхода к этой проблеме?

Я знаю, что могу сохранить отдельную переменную счетчика, которая увеличивается каждый раз, когда я устанавливаю элемент в массиве, но мне бы очень хотелось найти лучшее решение ... спасибо за чтение.


person Sarah Kemp    schedule 04.03.2014    source источник


Ответы (2)


Я программировал на RPG ... ну, очень давно. Замечательно видеть нового программиста RPG, и вдвойне чудесно видеть, как современные концепции кодирования используются с самого начала.

РПГ начала жизнь с фиксированного размера всего. Строки фиксированного размера, числа фиксированного размера и массивы фиксированного размера. Поскольку это был строго типизированный язык, основанный на перфокартах, все это имело смысл. Конечно, современные компьютерные требования, как правило, требуют строк, чисел и массивов разного размера. RPG по-прежнему строго типизирован, поэтому данная переменная может быть только строкой или числом; он никогда не может переключать типы. Это также означает, что у компилятора нет средств для определения типа переменной во время выполнения - тип переменной неизменен, и программист и компилятор знают, что это за тип. Ну что ж.

Что касается вашего массива переменной длины, на это есть некоторая надежда. У Михаэля Шмидта есть служебная программа под названием ArrayList, которая может удовлетворить многие из ваших потребностей.

person Buck Calabro    schedule 05.03.2014
comment
Согласовано - по сути, все элементы в массиве «используются», даже если вы еще ничего в него не поместили ... а что, если 0 или пробел являются допустимым фрагментом данных? Как и в Java для примитивных массивов, вы получаете значение по умолчанию .... IIRC. Написание собственного массива с динамическим изменением размера в медленный день было забавным - это был мой первый раз, когда я возился с математикой указателей, и никто не сказал мне, что я не могу наступать на другие процессы ... Кроме хотя однажды я его тестировал, он так и не использовался. - person Clockwork-Muse; 05.03.2014
comment
На самом деле я вчера настроил ArrayList - мне было очень трудно сосредоточить свой мозг на фиксированной длине всего. Я рад видеть, что не разочаровал вас своими многочисленными вопросами, на которые трудно ответить. Для конкретных массивов, которые я хочу подсчитать, нулевые и пустые и НЕ действительные данные, поскольку я использую их только для определения того, сколько различных значений у меня есть. Я отказался от ArrayList, потому что при отладке очень трудно увидеть данные, но сегодня я сделаю еще один шанс. Спасибо за ваш ответ. - person Sarah Kemp; 05.03.2014
comment
Для отладки вы можете использовать грубую силу с помощью кода операции RPG DUMP. Это создаст буферный файл для каждой переменной в программе в момент ее выполнения. Для более тонкой работы я использую отладчик SEP с Rational Developer for i. RDi - отличная IDE с редактором, проводником и отладчиком. - person Buck Calabro; 05.03.2014
comment
Я не пробовал DUMP, я использовал SEP с WDSC 7. Я могу «контролировать память», но я не могу сказать, на что я смотрю с помощью ArrayLists ... просто выглядит тарабарщиной независимо от того, какой вариант я выберу. Я посмотрю на DUMP, спасибо. - person Sarah Kemp; 05.03.2014
comment
«Выражение монитора» может быть вам полезнее, чем «память монитора». - person Buck Calabro; 05.03.2014

Непонятно, какие операции вы хотите выполнять с массивами неизвестного размера. Возможно, какой-нибудь пример кода может стать отправной точкой, и что-то можно будет добавлять или уточнять по мере продвижения. Итак, для банального примера:

 h dftactgrp( *NO )

 D tmp_Ary1        s             10i 0
 D tmp_Ary2        s             10

 d chk_Arrays      pr
 d  ary1                               like( tmp_Ary1 ) dim( 99 ) const
 d  ary2                               like( tmp_Ary2 ) dim( 99 ) const

 D ary1            s                   like( tmp_Ary1 ) dim( 50 )
 D ary2            s                   like( tmp_Ary2 ) dim( 50 )
  /free
        ary1( 1 ) = 12345 ;
        ary2( 1 ) = 'Some value' ;

        callP chk_Arrays ( ary1 : ary2 ) ;

        *inlr = '1';
  /end-free

 P chk_Arrays      b
 d                 pi
 d  ary1                               like( tmp_Ary1 ) dim( 99 ) const
 d  ary2                               like( tmp_Ary2 ) dim( 99 ) const

 d  foundElems     s             10i 0
  /free

   foundElems = 99 ;

   return;
  /end-Free
 p                 E

Процедура chk_Arrays () ожидает два массива: один dim (99) с 10-байтовыми символьными элементами, а другой dim (99) для целочисленных элементов. Но процедура вызывается с массивами, которые оба определены как dim (50), и в каждый массив заполняется только один элемент.

У процедуры есть только один исполняемый оператор. По большей части, единственная причина, по которой существует этот оператор, - это указать известное место для точки останова отладки. Скомпилируйте и запустите отладку и отобразите два массива при срабатывании точки останова.

Оттуда будет полезно описание того, что еще нужно.

person user2338816    schedule 17.04.2014
comment
Я хочу иметь возможность подсчитывать количество используемых элементов в любом массиве (любого типа данных, любой длины), просто кодируя что-то вроде myCount = countElems(myArr); - честно говоря, это должен быть BIF ... - person Sarah Kemp; 17.04.2014
comment
В примере кода myCount может быть (99), (50) или (1). Какое значение вы ожидаете получить от countElems ()? - person user2338816; 18.04.2014
comment
myCount должен быть (1) - person Sarah Kemp; 18.04.2014
comment
Это означает, что некоторое качество элементов должно быть обнаружено, чтобы указать, что вызывающий абонент изменен, а не инициализирован по умолчанию / вызывающий. Вряд ли когда-либо будет% BIF () из-за ILE. Вызывающим легко может быть ILE CL, COBOL, C или даже точка выхода из DB2 или системы. Итак, это зависит от интерфейса, который вы устанавливаете для своей процедуры. Ваш начальный пример показывает указатель по ссылке, что говорит компилятору, что нет необходимости в дополнительной помощи системы / компилятора. Мы можем предположить, что вы не обязательно ожидали такого кодирования, но его можно исключить как область помощи компилятору. Есть какие-нибудь новые подсказки для нас? - person user2338816; 19.04.2014
comment
Новые подсказки? Я не понимаю вопроса ... Идея состоит в том, что любое значение, установленное на ноль, пустое или нулевое значение, не будет учитываться. В идеале все неустановленные элементы массива должны быть нулевыми независимо от типа массива, но я думаю, что это невозможно. Проблема, по сути, решается программой ArrayList Service, упомянутой в принятом ответе. - person Sarah Kemp; 21.04.2014
comment
@SarahKemp Под «подсказкой» я подразумеваю лишь некоторый дополнительный способ, которым мы можем определить, используется ли элемент или нет. В моем примере кода мы можем сказать, что используется только ary1 (1), потому что все остальные 98 элементов равны нулю, даже если передано только 50 элементов. И мы знаем, что используется только ary2 (1), потому что все остальные 98 элементов пусты. Вот как все работает при использовании CONST для параметра с DIM () и несоответствии между измерениями в сочетании с инициализациями по умолчанию. По крайней мере, когда и вызывающий, и вызываемый являются RPG. Если другой язык вызывает процедуру, все может быть иначе. - person user2338816; 24.04.2014