Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 | 3 |

 

  Вопрос: Как работает функция IsMissing, на практике... Добавлено: 11.07.06 21:45  

Автор вопроса:  Nj | ICQ: 223663115 
Я понял, что функц. ИсМиссинг возвращает истину если мы не передали опциональный аргумент... но она не работает у меня:
Есть функция
Function Rnd2(Optional ByVal Min As Integer, Optional ByVal Max As Integer) As Integer
Static Max2 As Integer, Min2 As Integer

If IsMissing(Min) = False Then Min2 = Min
If IsMissing(Max) = False Then Max2 = Max

Rnd2 = CInt(Rnd * (Max2 - Min2)) + Min2
End Function
Идея в том, чтобы после первого вызова, можно было бы обращаться к ней без задачи аргументов.
Пример:
msg=rnd2(100,120)
for x=1 to 50
msg=msg & vbnewline & rnd2
next x
msgbox msg
Жаль, но принцип не работает - не понимаю почему?

Ответить

  Ответы Всего ответов: 36  

Номер ответа: 1
Автор ответа:
 Victor



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #1
Добавлено: 12.07.06 00:02
По тому, что IsMissing работает только на аргументах типа Variant

Ответить

Номер ответа: 2
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #2 Добавлено: 12.07.06 01:19
логику я непойму твою...

Optional ByVal Min As Integer, Optional ByVal Max As Integer...

т.е. их можно не передавать, если их не передвать - они равны нулю...

If IsMissing(Min) = False Then Min2 = Min '<<< Min = 0 если ничего не передали
If IsMissing(Max) = False Then Max2 = Max 'аналогично

Ответить

Номер ответа: 3
Автор ответа:
 AndreyMp



ICQ: 237822510 

Вопросов: 28
Ответов: 1182
 Профиль | | #3 Добавлено: 12.07.06 09:16

If IsMissing(Min) = False Then ...

Мягко говоря - ... (промолчу).
Я бы по крайней мере написал
If Not IsMissing(Min) Then ...

Ответить

Номер ответа: 4
Автор ответа:
 Nj



ICQ: 223663115 

Вопросов: 21
Ответов: 285
 Профиль | | #4 Добавлено: 12.07.06 17:37
2 Victor Спасибо, теперь ясно!!!
2 HACKER - а если надо передать 0 как Min? в то м-то и проблема
2 AndreyMp
промолчу).
Я бы по крайней мере написал
Это одно и тоже и на скорость компайлера это не влияет.. так, к сведению

Ответить

Номер ответа: 5
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #5 Добавлено: 15.07.06 05:51
2 HACKER - а если надо передать 0 как Min? в то м-то и проблема

Или ты меня не поймешь, или я тебя...

ну передаешь ты Min как ноль...

If IsMissing(Min) = False Then Min2 = Min


чтобы не возвращала, чтобы не делала функция IsMissing (кроме как изменяла само Min) Min2 в любом случае будет 0.

С этим ты согласен?

Ответить

Номер ответа: 6
Автор ответа:
 Nj



ICQ: 223663115 

Вопросов: 21
Ответов: 285
 Профиль | | #6 Добавлено: 15.07.06 19:18
Смотри, вот что задумывается:
Пользователь может передать минимум и максимум, а может не передать.
Если пользователь не передаст параметры, то тогда
функция должна будет использовать старые, статичные значения. Идея в том, чтобы вызвать функцию с параметрами только в первый, к примеру раз, а потом, без необходимости параметры не задавать... Я нагородил много текста, щас попробую на примере:
i=rnd2(100,120)'Функция загадывает значения от 100 до 120, даже если её теперь вызывать без параметров
т.е. теперь
i2=rnd2 'вернет также значение от 100 до 120, а не от 0 до 0, ведь пропуск аргументов не означает их равенство нулю! Т.е. не должен означать... - пропуск означает, что их не надо перезадавать, т.е. пусть сохраняются предыдущие установки
i3=rnd2(0,50) 'А вот теперь мы захотели загадывать от 0 до 50
i4=rnd2(7) 'А теперь загадали от 7 до 50 (а не от 7 до 0)
Я не уверен, что хорошо объяснил... Но как сменил As Integer на As Variant все заработало как надо!

Ответить

Номер ответа: 7
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #7 Добавлено: 15.07.06 19:52
а.. понял, х.з. как проверить, но Variant это не выход...

а вообще имхо нах ненадо, ты только запутаешся... Какой смысл во всём этом? Ускорить? Variant в раза 3 скорость снизит. Удобство? Это запоминать/проверять что передавали в прошлый раз...

удобства тоже нет

Ответить

Номер ответа: 8
Автор ответа:
 ENIX



ICQ: 238819245 

Вопросов: 9
Ответов: 76
 Профиль | | #8 Добавлено: 17.07.06 03:05

Function Rnd2(Optional ByVal Min As Integer = 0, Optional ByVal Max As Integer = 0) As Integer
  Static Max2 As Integer, Min2 As Integer
  Min2 = IIf(Min = 0, Min2, Min)
  Max2 = IIf(Max = 0, Max2, Max)  
  Rnd2 = CInt(Rnd * (Max2 - Min2)) + Min2
End Function


Можно походу еще так...сыровато, но вроде работает..да и без типа Variant.

Ответить

Номер ответа: 9
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #9 Добавлено: 17.07.06 04:48
Optional ByVal Min As Integer = 0, Optional ByVal Max As Integer = 0

оригинально :)))

Ответить

Номер ответа: 10
Автор ответа:
 ENIX



ICQ: 238819245 

Вопросов: 9
Ответов: 76
 Профиль | | #10 Добавлено: 17.07.06 16:49
эт точно...и зачем туда я его вставил)))

Ответить

Номер ответа: 11
Автор ответа:
 Nj



ICQ: 223663115 

Вопросов: 21
Ответов: 285
 Профиль | | #11 Добавлено: 18.08.06 19:10
Я так старался объяснить, зачем мне здесь IsMissing а не 0... :)
2 ENIX, сэнкс, но если пользователь захочет задать 0.
Попробую объясниить еще раз, не обижайтесь, если опять не получится:
Пропущенный аргумент не должен быть равен 0!
Т.е. rnd2(), rnd2(0) и rnd2(0,0) - это разные вещи в этой функции, а без Variant эти три вызова функции будут давать одинаковый результат. Rnd2(0,0) говорит о том, что надо загадать число в границах от 0 до 0 (бессмысленно, но так), т.е. изменить старые границы. Rnd2() вернет число, загаданное в старых границах, т.е. такой вызов не изменит придыдущие значения границ, а вот rnd2(0) переустановит нижнюю границу в 0, что может быть необходимо в определенной ситуации. Т.е. 0 тоже нужен как число, а не как индикатор, что пропущен аргумент.
2 Hacker - удобство есть, очень даже. Можно обойтись без лишних переменных, запоминая значения в самой функции, да и не надо каждый раз писать границы, если они одни и теже, особенно, если потом их придется менять, не надо будет просматривать весь код и в каждом вызове их заменять. Можно конечно, константы, но это дело вкуса.

Ответить

Номер ответа: 12
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #12 Добавлено: 19.08.06 13:37
Можно обойтись без лишних переменных, запоминая значения в самой функции

В самой функции иногда даже хуже, в некоторых случаях Static работает медление чем Public переменная...

надо каждый раз писать границы

В таком случае непонятно когда их писать, а когда ненадо :) Всё это только запутает и усложнит алгоритм...

но это дело вкуса

А вот с этого надо было и начинать :) Но вкус меняется, со временем...

Ответить

Номер ответа: 13
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #13 Добавлено: 22.08.06 10:58
Ну так задай дефолтовым значением какое-нибудь возмутительное число, близкое к границе long диапазона. Либо пиши на VB.NET, он поддерживает перегрузку функций.
Насчет Variant - потери при передачи данного типа (не в цикле) будут ничтожны, а если используется позднее связывание - и вовсе неизбежны. Не так уж оно и страшно.

Ответить

Номер ответа: 14
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #14 Добавлено: 23.08.06 04:18
Можно конечно, константы, но это дело вкуса.

Нифига себе вкус, этим ты очень сильно снижаешь понятность твоего кода.

Что делает функция?
Принимает какие-то значения, что-то с ними делает и возвращает результат.
С какой такой радости у обычной функции вдруг появляется внутреннее состояние?
Кто об этом может догадаться?..

Ладно, если б это был класс, тогда внутреннее состояние еще простимо, но в твоем случае...

Далее, что будет если во время работы твоей процедуры какой-то другой вызов изменит эти дефолтные значения? Ты же не будешь об этом никак не оповещен, прогармма полетит к черту, но самое интересное, что явной ошибки выполнения не произойдет, и разбираться в чем проблема тебе прийдется очень долго...

Кому интересно - функция Dir из VB6 имеет внутреннее состояние, в результате с ней практически невозможно работать при использовании рекурсии, так, когда мне нужно было что-то подобное, я, если не ошибаюсь, или вообще забил, или юзал FSO.

Ответить

Номер ответа: 15
Автор ответа:
 Nj



ICQ: 223663115 

Вопросов: 21
Ответов: 285
 Профиль | | #15 Добавлено: 23.08.06 18:22
1. Мне нужна эта функция, константы не подходят - значения меняются, но изредка.
2. Функция уже не обычная, обычная -- это обычное RND. И класс - это не единственная причина создавать статичную функцию. Здесь значение нужно, а насчет Dir - согласен, что не удобно, но можно и циклом.
3. Действительно дельно: если вдруг одновременно эту функцию будут вызывать 2 источника, может выйти неприятность, но если в программе имеется такая вероятность, то можно вызывать границы: их никто не запрещал в моей функции.
4. Да лучше написать границы один раз, если вся программа работает с одинаковым диапозоном чисел.

Проблема уже решена, всем спасибо!!!

Ответить

Страница: 1 | 2 | 3 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам