FreeBasic
Главная
Вход
Регистрация
Среда, 09.10.2024, 10:37Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Массив
RoloverДата: Вторник, 09.07.2013, 23:50 | Сообщение # 1
Лейтенант
Группа: Пользователи
Сообщений: 45
Репутация: 0
Статус: Offline
Возможно это и банальный вопрос для знающих.. но для не особо знакомых с типизацией переменных ... это как-то привело в недоумение.

И так
Код
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 и как к примеру определить истинный размер массива? Ну чтобы в цикле можно было перебрать.


Объяснив другому, поймешь, что понял сам.
 
haavДата: Среда, 10.07.2013, 08:25 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Я конечно не вникал во все тонкости того, как выделяется память для массивов, но расскажу как мне представляется все это.

Есть области видимости, для которых в сумме выделяется память в размере 1 мб  по умолчанию. Каждая область видимости получает определенный кусок памяти из этой суммы. Скорее всего для одной единственной области видимости выделятся вся сумма. Но мы возьмем для примера 100 кб для одной области видимости. Когда мы в нашей программе создаем массив, он входит в этот кусок памяти и поскольку у нас есть права писать в этот кусок, мы легко можем написать и a(10), a(20), поскольку это не вылезает за рамки области видимости.

Обращение к массиву идет от его начального адреса + индекс*размер типа

То есть к примеру:

Нам под область видимости выделен кусок от 300000 до 300100
Стартовый адрес массива a(0) пусть будет 300000
a(20) = 300080
300000+20*4 (для типа Integer) - допустимо. Но если мы попробуем записать a(150), то скорее всего будет крах программы.

Мы можем записать a(20) без всяких последствий, пока у нас только одно хранилище(массив, переменная). Конечно же, если мы объявим еще один массив в этой области видимости, и будем так беспардонно лезть за его рамки, то один будет затирать второй. Для того и создали макросы

LBOUND - начальная рамка массива
UBOUND - конечная рамка массива

Вот этот пример как раз покажет затирание данных:

Код
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

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


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
ПавелДата: Пятница, 12.07.2013, 11:01 | Сообщение # 3
Сержант
Группа: Пользователи
Сообщений: 21
Репутация: 0
Статус: Offline
в цикле перебирать массив так

for a = lbound(m) to ubound(m)
............
next
 
SZotov1973Дата: Воскресенье, 14.07.2013, 17:56 | Сообщение # 4
Рядовой
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
Цитата (haav)
Конечно вопрос уместен в плане того, что компиль должен запрещать обращение к несуществующим ячейкам, но видно в парсер данная возможность не заложена.

Я всегда компилирую с опцией -exx. Там подобные ошибки отображаются.
 
RoloverДата: Воскресенье, 04.08.2013, 22:55 | Сообщение # 5
Лейтенант
Группа: Пользователи
Сообщений: 45
Репутация: 0
Статус: Offline
Только что на такие грабли наступил!!! prof
Но хорошо что нашел. Короче посчитал кол-во спрайтов  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)

1244648    =>(20)
1244652    =>(21)
1244656    =>(22)
1244660    =>(23)
.....

и не пересекаются  я про объекты и про спрайты. А вот не работает
Теперь цикл на занесение фигур в память
кто будет пробовать картинки создавать нужно ))) 28 шт или циклы менять
меня заинтересовал один нюанс
? f(i+ii)
?@ f(i+ii)

эти 2 строки ..ну вторая  выводит те строки, что описаны выше
а вот первый вариант выводит
цифры типа
22180064
22189728
22199408
......
ну это, что... Это типа то что им ImageCreate возвращает?

В общем я к чему это все, ошибку тяжело выловил такую
Компилирование с -exx
это тоже не помогло ))) перепроверил потом ..

Меня интересует как такого рода ошибки можно отлавливать???


Объяснив другому, поймешь, что понял сам.

Сообщение отредактировал Rolover - Воскресенье, 04.08.2013, 23:04
 
haavДата: Понедельник, 05.08.2013, 08:16 | Сообщение # 6
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Цитата (Rolover)
меня заинтересовал один нюанс? f(i+ii)
?@ f(i+ii)
эти 2 строки ..ну вторая выводит те строки, что описаны выше
а вот первый вариант выводит
цифры типа
22180064
22189728
22199408
......
ну это, что... Это типа то что им ImageCreate возвращает?

Да, это указатели на объекты изображений.

Цитата (Rolover)
В общем я к чему это все, ошибку тяжело выловил такуюКомпилирование с -exx
это тоже не помогло ))) перепроверил потом ..

Меня интересует как такого рода ошибки можно отлавливать???

В данном случае, вся ответственность за ошибки ложится на программиста. Компилятор не может все предусмотреть. Не вылезать за рамки массива можно способом, предложенным Павлом выше.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
RoloverДата: Среда, 23.10.2013, 18:01 | Сообщение # 7
Лейтенант
Группа: Пользователи
Сообщений: 45
Репутация: 0
Статус: Offline
подскажите пожалуйста .....
Вот можно же объявить массив с  отрицательными индексами

ну например
Код
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
 
haavДата: Четверг, 24.10.2013, 19:16 | Сообщение # 8
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Цитата
Так вот вопрос .. как можно с экономить память если например нужно объявить массив (-50 to 50) но при этом хранить в отрицательной части использовать например только с индексами (-50) и (-49)
а все остальное в отрицательных индексах не нужно .. а в положительных потом остальное (1), (2).....(50)


С массивом не получится. Если уж выделил 100 ячеек, то 100 и будет. Если нужна экономия, может стоит присмотреться к связанному списку? А вообще конечно, если уж так хочется или удобно использовать массивы, то наверно надо пересмотреть логику программы, потому как из-за двух ячеек выделять несколько десятков или даже сотен ячеек - плохой подход.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
RoloverДата: Четверг, 24.10.2013, 22:14 | Сообщение # 9
Лейтенант
Группа: Пользователи
Сообщений: 45
Репутация: 0
Статус: Offline
Связанный список?
А разве с ним можно работать как с двумерным массивом??
ну чтобы можно было например  сделать  так
Код
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 .......
Курсор тут выводится по координатам из массива, накладывается сверху с прозрачным фоном, и как бы очерчивает тайл  по границам

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


Объяснив другому, поймешь, что понял сам.
 
haavДата: Пятница, 25.10.2013, 18:57 | Сообщение # 10
Генералиссимус
Группа: Администраторы
Сообщений: 1363
Репутация: 49
Статус: Offline
Цитата
Связанный список?
А разве с ним можно работать как с двумерным массивом??
ну чтобы можно было например сделать так


Создать структуру с координатами и заносить в связанный список указатель на нее. Конечно в варианте с связанным списком коду будет несравненно больше.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
  • Страница 1 из 1
  • 1
Поиск: