|
Администратор |
|
Сообщения: 273 Откуда: Россия
|
Массив без размера Zorko писал(а): Олеж, а как у нас сейчас обрабатывается случай объявления типа массива без размера? Код: "OBERON" TYPE TheClocks = ARRAY OF BYTE; CONST AnimClockData = TheClocks (0040, 00070);
Спрашиваю потому что ещё не тестил твой код и потому что нужно обсудить как будет вообще более правильно реагировать на такое описание: спустить его на тормозах, вычисляя размер массива по количеству заданных значений, либо же ткнуть юзеру, что надо указать размер явно? Мы уже обсуждали что-то подобное и сошлись, вроде бы, на том, что явное указание количества байтов, слов или каких-то иных элементов в структуре данных чаще всего полезно, т.к. вводит дополнительный контроль. Например, пусть у нас в игре 3 комнаты, данные для которых задаются как Код: "OBERON" CONST MaxRoom = 3; TYPE Rooms = ARRAY MaxRoom*6*8 OF BYTE; CONST RoomData = Rooms ( 3,12,0,0,5,2,1,100, (* Room 1*) 33,14,0,0,15,2,1,10, 3,12,0,0,5,2,1,100, 33,14,0,0,15,2,1,10, 3,12,0,0,5,2,1,100, 33,14,0,0,15,2,1,10, ... (* Room 2*) ... (* Room 3*) );
Теперь, чтобы добавить еще одну комнату, необходимо изменить CONST MaxRoom = 4; и добавить числа в конец массива RoomData. Если мы добавим данные для комнаты, а константу изменить забудем или наоборот (константу изменим, а байты не добавим или какое-то число пропустим), то компилятор это заметит и выдаст ошибку. И очень хорошо, что есть такой контроль. Да и контроль не слишком обременителен, потому что константы типа MaxRoom всё равно,обычно, где-то в программе используются. Но это хорошо для данных, где каждый элемент имеет одинаковую длину. Что будет, если данные для комнаты состоят из разного числа байтов? Код: "OBERON" CONST MaxRoom = 3; LenRoom1 = 6*8; LenRoom2 = 6*8+5; LenRoom3 = 3*7+10; LenRoomData = LenRoom1+LenRoom2+LenRoom3; TYPE Rooms = ARRAY LenRoomData OF BYTE; CONST RoomData = Rooms ( 3,12,0,0,5,2,1,100, (* Room 1*) 33,14,0,0,15,2,1,10, 3,12,0,0,5,2,1,100, 33,14,0,0,15,2,1,10, 3,12,0,0,5,2,1,100, 33,14,0,0,15,2,1,10, ... (* Room 2*) ... (* Room 3*) );
Тут нужно кроме изменения константы MaxRoom и добавления байтов в массив RoomData ещё ввести новую константу LenRoomX, и записать её в сумму LenRoomData. Какой-то контроль и тут сохраняется - компилятор заметит, если мы добавим байты в массив ,но забудем изменить LenRoomData. Однако, стало труднее, потому что необходимо подсчитать число байтов и изменить программу в нескольких местах. А если бы можно было не указывать количество байтов и написать просто TYPE Rooms = ARRAY OF BYTE;? В этом случае компилятор не сможет проконтролировать правильность количества данных и должен полагаться на программиста. Но зато не заставит их пересчитывать. И это тоже мы обсуждали и согласились, что иногда контроль ничего хорошего не даёт и удобство важнее. Заметим, что в обоих случаях количество элементов самого константного массива CONST RoomData = Rooms (31, 7, 123, ...); задано количеством константных выражений в скобках. Просто в одном случае оно же задаётся дополнительно и в описании массивового типа, поэтому у компилятора есть возможность проконтролировать соответствие. Поэтому, думаю, возможность опускать размер массива будет полезна. Ведь никакой современный компилятор ЯВУ (и даже ассемблер) не заставляет для строковой константы явно указывать её длину -мы просто перечисляем символы в кавычках. А если бы нужно было писать 5"Hello" или 0"", насколько бы это стало сложнее! Если размер каждого элемента фиксирован и программисту не составит труда его указать, то лучше указать в типе явно. А если длина элементов плавает или неизвестна, а пересчитывать пальцем лень, то можно и не указывать. Конечно, кто-то не будет указывать никогда, но это уже вопрос стиля и грамотности. По реализации. Пока возможность опускать указание размера не сделана и обрабатывается как ошибка. Для реализации нужно решить вопрос с хранением элементов. Если массив имеет фиксированный размер, то мы сначала выделяем один кусок памяти для хранения всех его элементов, а затем в процессе чтения заполняем. Если размер заранее неизвестен, то придется выделять память связанными в список кусками некоторого стандартного размера (на 100, 1024 или 4*1024 элемента, например). А если очередной кусок кончился, то выделить следующий и подсоединить его к списку. Размер куска (лучше наверно задавать его не в количестве элементов, а в КБ) можно установить в константах Ofront или даже в par-файле.
|
|