Возможно это и банальный вопрос для знающих.. но для не особо знакомых с типизацией переменных ... это как-то привело в недоумение.
И так
Код
Dim as integer a(2) 'Вроде как объявили массив на 3 значения a(0)=1 a(1)=2 a(2)=3 'И казалось бы этим должно закончиться, а нет a(3)=4 a(4)=5
? a(3) ' Результат 4 здорово!!!
? Ubound (a) 'Результат 2
А как же тогда типы данных и изначальное определение размера, причем вот засада, по Ubound (a) все равно получим 2 и как к примеру определить истинный размер массива? Ну чтобы в цикле можно было перебрать. Объяснив другому, поймешь, что понял сам.
Я конечно не вникал во все тонкости того, как выделяется память для массивов, но расскажу как мне представляется все это.
Есть области видимости, для которых в сумме выделяется память в размере 1 мб по умолчанию. Каждая область видимости получает определенный кусок памяти из этой суммы. Скорее всего для одной единственной области видимости выделятся вся сумма. Но мы возьмем для примера 100 кб для одной области видимости. Когда мы в нашей программе создаем массив, он входит в этот кусок памяти и поскольку у нас есть права писать в этот кусок, мы легко можем написать и a(10), a(20), поскольку это не вылезает за рамки области видимости.
Обращение к массиву идет от его начального адреса + индекс*размер типа
То есть к примеру:
Нам под область видимости выделен кусок от 300000 до 300100 Стартовый адрес массива a(0) пусть будет 300000 a(20) = 300080 300000+20*4 (для типа Integer) - допустимо. Но если мы попробуем записать a(150), то скорее всего будет крах программы.
Мы можем записать a(20) без всяких последствий, пока у нас только одно хранилище(массив, переменная). Конечно же, если мы объявим еще один массив в этой области видимости, и будем так беспардонно лезть за его рамки, то один будет затирать второй. Для того и создали макросы
Dim as integer a(2) 'Вроде как объявили массив на 3 значения Dim as integer b(5) For i As Integer = 0 To 80 a(i) = i Next For i As Integer = 0 To 80 b(i) = i+100 Next
For i As Integer = 0 To 80 ? a(i); Next Print Print For i As Integer = 0 To 80 ? b(i); Next sleep
Если четко на вопрос:
Цитата
и как к примеру определить истинный размер массива?
То должно быть понятно, что кол-во ячеек в массиве будет равно:
UBound(a)-LBound(a)+1
Конечно вопрос уместен в плане того, что компиль должен запрещать обращение к несуществующим ячейкам, но видно в парсер данная возможность не заложена. Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
Конечно вопрос уместен в плане того, что компиль должен запрещать обращение к несуществующим ячейкам, но видно в парсер данная возможность не заложена.
Я всегда компилирую с опцией -exx. Там подобные ошибки отображаются.
Только что на такие грабли наступил!!! Но хорошо что нашел. Короче посчитал кол-во спрайтов 28. НО сами спрайты про именованы так 10.bmp 11.bmp 12.bmp ... это один вид...дальше 20.bmp 21.bmp .........
короче каждый вид спрайта в своей декаде декад 7 по 4 файла типа чтобы не путаться ну и так вот 28 ))) файлов
ну и соответственно открыл массив
Код
Dim f(28) As Any Pointer ' а присваивать значения начал ключ элемента массива ' ' ' соответствует имени '........ '........ f(30)=
'..... f(70)= 'ну это все в цикле 'и массив объектов Dim Figura(1 to 7) as Figury Pointer
Ну в общем 2 массива
Не ну про размер мы говорили сколько объявил столько и заполни .. это я точно помню. А вот про индексацию не говорили, что она тоже учитывается.... наверное..? Просто когда проверяю указатели они на разные ячейки памяти красиво по 4 байта шаг, ну и между декадами 28 1244608 => (10) 1244612 =>(11) 1244616 =>(12) 1244620 =>(13)
и не пересекаются я про объекты и про спрайты. А вот не работает Теперь цикл на занесение фигур в память кто будет пробовать картинки создавать нужно ))) 28 шт или циклы менять
Dim f(80) as any pointer
ScreenSet 1
'эабиваем фигуры в память, причем под разные фигуры резервируем разные размеры For i as integer=10 to 70 step 10 For ii as integer = 0 to 3 'номера от 10....53
IF (i+ii) < 60 and ((i+ii) Mod 2) = 0 THEN 'получаем индекс например f(45)=.. и получаем имя файла типа "pic/f45.bmp" и элемент массива f(i+ii)=ImageCreate(60,40) : Bload("pic/f" & (i+ii) &".bmp",f(i+ii)) ELSEIF (i+ii) < 60 THEN f(i+ii)=ImageCreate(40,60) : Bload("pic/f" & (i+ii) &".bmp",f(i+ii)) END IF
? f(i+ii) ?@ f(i+ii)
'номера от 60...63 IF (i+ii)>=60 and (i+ii) <=70 THEN f(i+ii)=ImageCreate(40,40) : Bload("pic/f" & (i+ii) &".bmp",f(i+ii))
'номера от 70...73 IF(i+ii)>=70 and ((i+ii) Mod 2) =0 THEN f(i+ii)=ImageCreate(80,20) : Bload("pic/f" & (i+ii) &".bmp",f(i+ii)) ELSEIF (i+ii)>=70 THEN f(i+ii)=ImageCreate(20,80) : Bload("pic/f" & (i+ii) &".bmp",f(i+ii)) END IF next next
меня заинтересовал один нюанс ? f(i+ii) ?@ f(i+ii) эти 2 строки ..ну вторая выводит те строки, что описаны выше а вот первый вариант выводит цифры типа 22180064 22189728 22199408 ...... ну это, что... Это типа то что им ImageCreate возвращает?
В общем я к чему это все, ошибку тяжело выловил такую Компилирование с -exx это тоже не помогло ))) перепроверил потом ..
Меня интересует как такого рода ошибки можно отлавливать??? Объяснив другому, поймешь, что понял сам.
Сообщение отредактировал Rolover - Воскресенье, 04.08.2013, 23:04
меня заинтересовал один нюанс? f(i+ii) ?@ f(i+ii) эти 2 строки ..ну вторая выводит те строки, что описаны выше а вот первый вариант выводит цифры типа 22180064 22189728 22199408 ...... ну это, что... Это типа то что им ImageCreate возвращает?
Да, это указатели на объекты изображений.
Цитата (Rolover)
В общем я к чему это все, ошибку тяжело выловил такуюКомпилирование с -exx это тоже не помогло ))) перепроверил потом ..
Меня интересует как такого рода ошибки можно отлавливать???
В данном случае, вся ответственность за ошибки ложится на программиста. Компилятор не может все предусмотреть. Не вылезать за рамки массива можно способом, предложенным Павлом выше. Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
подскажите пожалуйста ..... Вот можно же объявить массив с отрицательными индексами
ну например
Код
Dim as Byte array(- 5 to 5 )
Так вот вопрос .. как можно с экономить память если например нужно объявить массив (-50 to 50) но при этом хранить в отрицательной части использовать например только с индексами (-50) и (-49) а все остальное в отрицательных индексах не нужно .. а в положительных потом остальное (1), (2).....(50)
Код
Dim as Byte array(-50 to 50)
array(-50) = 88 array(-49) = 77
array(1) = 2 array(3) = 4 ....... array(50) = 16
просто в данном варианте Byte да это по сути фигня... а если например Short и массив от (-500 to 500) и при этом не все индексы используются ???
Индексы формируются на лету ))) зависят от положения курсора и при этом по сформированным индексам нужно делать выборку.
Или еще лучше если используется массив объектов где куча свойств и методов то как можно с экономить на памяти?? использовать не все элементы???
З.Ы Но по сути не важно какой массив главное что в этом массиве есть неиспользуемые элементы от которых нужно как-то избавиться.. Объяснив другому, поймешь, что понял сам.
Сообщение отредактировал Rolover - Среда, 23.10.2013, 18:06
Так вот вопрос .. как можно с экономить память если например нужно объявить массив (-50 to 50) но при этом хранить в отрицательной части использовать например только с индексами (-50) и (-49) а все остальное в отрицательных индексах не нужно .. а в положительных потом остальное (1), (2).....(50)
С массивом не получится. Если уж выделил 100 ячеек, то 100 и будет. Если нужна экономия, может стоит присмотреться к связанному списку? А вообще конечно, если уж так хочется или удобно использовать массивы, то наверно надо пересмотреть логику программы, потому как из-за двух ячеек выделять несколько десятков или даже сотен ячеек - плохой подход. Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
Связанный список? А разве с ним можно работать как с двумерным массивом?? ну чтобы можно было например сделать так
Код
Do .................................. 'расчет индексов для массива в зависимости от положения курсора мышки X и Y
i = x/w + y/h j = y/h - x/w
Put (tyli(i , j)->x, tyli(i, j)->y),Kursor, Trans Loop .......
Курсор тут выводится по координатам из массива, накладывается сверху с прозрачным фоном, и как бы очерчивает тайл по границам
В общем я понял нужно думать дальше . Просто думал сначала динамический массив... так он же тоже только размер меняет и ни как не индексацию.. ))) Объяснив другому, поймешь, что понял сам.
Связанный список? А разве с ним можно работать как с двумерным массивом?? ну чтобы можно было например сделать так
Создать структуру с координатами и заносить в связанный список указатель на нее. Конечно в варианте с связанным списком коду будет несравненно больше. Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…