Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Форум группы: Vingrad Delphi - Voluntary Writers Group > Это нужно знать |
Автор: THandle 23.3.2008, 20:08 | ||||||
Приветствую всех свободны писателей этой группы!!! ![]() У новичков очень часто бывают залблуждения относительно вопросов программирования на Делфи. В данной теме мы попробуем создать список наиболее часто встречающихся заблуждений и написть по ним небольшой рассказ от имени молодого "диверсанта" взявшегося постигать глубины Дефли. На пути у него будет много сложностей(как раз это и есть наш список заблуждений), и он будет их решать, и что самое удивительное, всегда будет решать неверно. После такого "обучения" он придет на сей славный форум и начнет советовать другим свои неверные решения. Наши доблестные ребята укажут ему в чем он не прав и помогут ему с его неверным кодом, исправят, объяснят, и вскоре наш "диверсант" поймет всю правду правду жизни и встанет на верный путь. Вот такой вот вкратце сюжет нашего рассказа. Писать его я берусь(не получится - сформулируем по-другому ![]() Тут можно представлять как уже готовые заблуждения(красиво написанные, прозаичные и тд.), а можно просто давать код, к которому напишем объяснение и тд. Значит так, нашел пока только следующее, тороплюсь, завтра еще выложу: Циклы работы со строками начинай с нуля, а заканчивай длиной строки минус 1:
А циклы со списками начинай с 1 до List.Count:
Сейчас поищу, что то наверное папку с этими заблууждениями удалил ![]() За флуд в данной теме всем будут выставлены минус!!! Так что не флудим товарищи(на всякий случай). Добавлено через 13 минут и 36 секунд Конструктор объекта надо вызывать в блоке try..finally..end;
|
Автор: SneG0K 23.3.2008, 20:31 | ||||||||
Оператор with..do Изучая дельфи по Фленову, я узнал много, много, чего даже не стоит знать) И только благодаря Thandle я стал на путь истинный! Так, что лучше купить Пачеко, чем Фленова. Так вот, из всего того я не знал про оператор with..do... И в многих примерах пугался его и переписывал! Давай создадим некую структуру
Как бы мы заполняли эту структуру?
Но можно сделать это немножко в меньше кода
Вообщем надеюсь суть понятна. Оператор with..do позволяет получить доступ к переменным какой-либо структуры или юнита, без указания такового) Разницы то в общем нет, но иногда юнит или структура имеет такое "красивое" название... Так же можно делать так
Что позволит получить доступ к переменным Structure1 и structure2.... Вообщем ничего сложного) |
Автор: THandle 24.3.2008, 13:34 |
Значит так, вот еще пара штук: 1. Не стоит удалять динамически созданные объяекты, Делфи умный, он сам их удалит, лучше заняться чем-нибудь более интересным. 2. Чем больше кода ты запихнешь в Synchronize своей дополнительной нити, тем быстрее она будет работать. |
Автор: THandle 28.3.2008, 12:10 | ||||
Начало почти готово Думаю в понедельник вторник выложу. ![]() Вот еще: Создавать объект надо так:
а не так:
Напомню, что все советы тут являются довольно таки вредными, и понимать их надо буквально наооборот. ![]() И народ, давайте чтоли уже поактивнее ![]() |
Автор: SneG0K 28.3.2008, 12:54 | ||||||
Некий прикол с if..then Если мы напишем
ТО это будет абсолютно аналогично
Но не будет аналогично
|
Автор: THandle 30.3.2008, 16:23 | ||
Никакого прикола собсно и нету)) Вот еще одно: Уничтожаем объект в своем же обработчике. Например:
|
Автор: SneG0K 31.3.2008, 15:13 | ||||||||
Приложение с параметрами Все параметры, с которыми приложение было запущено содержатся в
Добавлено через 3 минуты и 41 секунду Забыл сказать отсчет параметров начинается с 0, а не с 1. Но это не значит, что cmd.exe, php.exe, perl.exe и другие получает весь код в параметрах ![]() ![]() |
Автор: THandle 31.3.2008, 16:07 | ||
SneG0K, все это не относится к обсуждаемой теме, и описано в DRKB, а может даже и тут, где - нибудь в факе. Поищи поиском и наищешь искомое. |
Автор: SneG0K 31.3.2008, 23:47 | ||
Обьясняю, в строках первый символ содержит длину всей строки. Поэтому правильная длинна строки будет length(строка)-1 |
Автор: THandle 5.4.2008, 21:20 |
Значит так, у Len ничего написать не получилось поэтому взялся я ![]() Вот вступление: Жил-был один человек, звали его допустим Иван. Было ему от роду 16 годков. Жил он не бедно – не богато, учился в школе, на двойки. Одеваться любил он модно, был высокого роста и имел гладкие светлые волосы. Жил он себе припеваючи, играл в игры компьютерные, пиво пил с девчонками на дискотеках, в общем был Ваня самым обычным нормальным парнем. Был у Ивана друг, крутой программист и хакер. Хвастался он перед Иванушкой нашим, хвастался. И как иконку в трей запуздырить показывал, и как программку в 30 килобайт забабахать. И говорил этот друг что все это братец, мол, Делфи, круто оно, возьмись, изучай. Задумался тут Иван. Будучи по натуре своей человеком любознательным решил он попробовать поучится работать с этой программой. Взял он у друга дистрибутив, установил и сидит, смотрит. Кнопочки какие-то, надписи не русские. Среди всего этого выделялась красивая кнопочка с изображенным зеленым треугольничком. Решил Иван – тыкну её, будь что будет. И тыкнул. Результат был ужасный - появилось окошко, ну прям как у друга, надпись на нем – Form1, если мышом взять за верхушку – поползет, поползет – берегись - улетит! Обрадовался наш герой, побыстрее выключил компьютер, побежал всем хвастаться что программу написал. И решил с этого момента Ваня твердо – стать программистом, и дело с концом. Вернувшись вечером домой включил он компьютер, полез в Интернет, нашел там книжки по Делфи и стал усердно изучать их. Далее поведаем мы вам сказ о том, какие трудности встали на пути Ивана, и как он их преодолел. |
Автор: THandle 15.4.2008, 20:54 | ||||||||||
Всё времени никак не хватает написать... думаю либо в конце этой, либо в начале следующей недели будет продолжение ![]() И на всякий случай, для некоторых, напоминаю, все советы приведенные тут, являются вредными, то есть понимать их нужно прямо наоборот. Например:
Надо понимать так: Циклы работы со строками начинай с 1, а заканчивай длиной строки length(string).
А циклы работы со списками начинай с 0 и заканчивай List.Count - 1.
|
Автор: THandle 23.4.2008, 20:23 | ||||||||
Оказалась не легким делом писать все это. Но уже многое готово ![]() Вот еще одна ошибка, которая вызывает у новичков недоумение: Почему компилятор ругается на безобидный цикл for?
Ответ: Да патамучта нильзя в цикле for менять значение переменной счетчика. А вот и еще одно: В таком цикле:
Будет очень много раз вызываться функция length, что сделает программу очень медленной. На самом деле это не так. Начальное и конечное значение цикла for расчитывается только один раз, при начале его выполнения. Поэтому выносить длину строки в отдельную переменную глупо:
Поэтому стоит быть очень осторожным, когда в таком цикле удаляется часть строки, например: Эта процедура по идее должна удалять пробелы:
Однако же все пробелы она не удалит как раз по причине единичного расчета значений цикла. Подробнее об этом я писал тут: http://forum.vingrad.ru/forum/topic-206543.html Ну и ребят, кто тут бывает, поактивнее предлагайте "заблуждения". Проект не заброшен и заброшенным быть не собирается. ![]() |
Автор: SneG0K 29.4.2008, 23:30 | ||||||
THandle ток не ругай меня ![]() Так-с... Может нижеописанное и не относится к начинающим программистам, но это относится к начинающим WinSOCK'ерам. У меня с самого начала изучения дельфи как-то появилась мания использовать стринговые переменные, что иногда очень удобно, а иногда является источником всех бед. Так вот, моя первая сетевая программа ничем необычным не отличалась, она просто передавала какие-либо данные от клиента, к серверу и обратно. Вообщем все просто. В качестве буфера я использовал стринговую переменную. И получал в неё данные как в буфер.
Но я не остановился и решил понять почему текст в стринговой переменной превращается в неизвестно что... Понять почему я так и не смог. Наверно кодировки тут сыграли свою роль. Или переменные... Вообщем неизвестно. Но
Внимание! Это из дневника Грозного Ивана... |
Автор: THandle 30.4.2008, 16:01 |
SneG0K, Иваном будешь? ![]() Твой пример вполне подойдет, если использовать его для объяснения работы со строками. Если сможешь оформить в виде рассказика с объяснением что как и куда использовать - то буду очень рад ![]() Вобщем список заблуждений сейчас такой: 1. Работа со строками в цикле. Почему с 1, а не с 0. 2. Работа со списками. Почему с 0, а не с 1. 3. Почему конструктор надо вызывать не как обычный метод? 4. Почему конструктор надо вызывать до try..finally..end? 5. Почему нельзя уничтожить объект в своем же обработчике? 6. Почему надо вызывать не Destroy, а Free? 7. Почему в цикле for нельзя менять значение переменной-счетчика этого же цикла? 8. Эквивалентны ли записи if b = true then и if b then? 9. Почему в цикле for со строками не надо вводить еще одну переменную в которую будет перед циклом заносится длина строки, и эта переменная будет являться конечным значением цикла? 10. Почему в цикле for 0т 1 до длины некоторой строки и удалении некоторых знаков из этой строки, удаляются не все знаки? Вот. Пока 10 штук. Почти все уже готовы. |
Автор: SneG0K 30.4.2008, 23:25 |
И заблуждение №11. 11)Почему юзать Дельфи, а не что-то другое? Ответ:Потомушто ДЕЛЬФИ РУЛИТ!!!! ![]() ![]() ![]() Ссори за ![]() |
Автор: THandle 4.5.2008, 14:41 | ||||||||||||||||||
Из записок Ивана: 12 ноября. Решил вести дневник. Пусть будущее поколение знает как герои изучали Delphi. Сегодня ознакомился с интерфейсом. Классная вещь вам скажу. Скачал учебник. Читаю. 16 ноября. Прочитал учебник. Теперь мне многое понятно. Надо написать какую-нибудь программку. И я даже знаю какую... 28 ноября. Узнал сегодня что со строками можно работать как с массивом. Я был ваще в шоке. Стал переделывать все. Чтоб круче было. И возникла одна маленькая проблемка:
Почему-то код вызывает ошибку:( почему не понимаю. Видимо из за глюков в Delphi. Вообще если так вот посмотреть с проффесианальной точки зрения ошибок очень много. Абсолютно непонятно чем не понравился мой код этому компелятору? Ведь строка же это массив символов, который наченается с нуля. Последним элементом является длина этого массива вычисляемая очень полезной функцией Length, которую я случайно обнаружил и благодаря опытам установил что она возвращает длину строки. Ладно, не будем работать со строками как с массивом, раз они не хотят... 8 декабря. Случайно прочитал сегодня где-то в интернете, что строка начинается с 1, а в нулевом элементе хранится её длина. А заканчивается строка её длиной(странно по моему, ну пусть будет так, раз по другому не смогли сделать). Переделал свой код. И правда работает. Как я сам не догадался?
11 декабря. Обнаружил сегодня интересный класс: Tstringlist. Очень полезная вещь для работы с файлами. 14 декабря. Класс оказался неправильный какой-то. Не работает:( Представляете, запустил в цикле добавление всех строк из моего StringList'а в Memo, а получилось так что первый элемент он игнорирует, а потом еще и ошибку выбрасывает:(
Очень подозрительно, согласитесь? 19 декабря. Да уж. Предыдущий опыт со строками должен был научить меня тому что в Delphi и в программировании вообще(я же теперь еще и Assembler отлично знаю, пишу сайты на PHP и собираюсь браться за C++, чтобы разрабатывать 3Д-игры). Оказывается что во всех таких классах нумерация элементов идет не как в строках, а с 0, а заканчивается, видите ли, числом Count — 1. Потому что начальное значение Count = 1, а начинается список элементов с 0. Интересно кто такое придумал? Повесить его надо. Не поянтности какие то делают. Ужас полный. Вот в общем мой код. Прикиньте, работает:
А вообще в одной хорошей сатейке в интернете, кстати на том же сайте на котором я узнал и про строки, нашел еще то что оказывается у класса TstringList есть такая процедура AddStrings(там было написано что это метод, но что такое метод я не знаю почему-то, хотя учебник прочитал). В общем он неслабо упрощает мою задачу:
Добавляет все строчки без проблем вообще. Я со спокойной душой начинаю праздновать новый год. 18 января. Ну вот, отлично отпраздновал новый год. Теперь вот вспомнил что у меня программа недописанная лежит. Решил сесть подумать что дальше делать. Полазил по нету. Удалось установить что к элементам списка строк можно обращаться прямо как массиву, а не через Strings. Объяснено это было тем что Strings объявлено с какой-то там директивой default. Ну да ладно. Пусть объявлено. Главное — работает. Мой прошлый код я модифицировал в вот что:
Работает супер. 20 января. Где то прочитал что объекты надо уничтожать деструктором. Переделал свой код:
Почему-то при повторном нажатии на кнопку выскакивает ошибка:( Destroy убираю — всё нормально. Статья видимо не правильная была. 26 января. Прочитал где-то что нужно освобождать память за объектами не Destroy'м, а неким Free. Попробовал — ошибок нет, хотя результат тот же что и без него. Ну да ладно, пускай будет. Вот мой новый код:
29 января. Сегодня абсолютно случайно обнаружил что у меня в программе можно и не использовать TstringList, так как в сам Memo можно точно так же загружать файл. Теперь мой код выглядит так:
|
Автор: THandle 4.5.2008, 16:37 |
Естественно в конце, после всего этого дневника Вани последует подробное объяснение чего не так и тд. ![]() |
Автор: Wedafl 24.5.2008, 03:06 | ||
На тему конструктора, лично я часто пишу так
И не понимаю чем это плохо. |
Автор: THandle 26.5.2008, 08:15 |
Wedafl, обработку исключений конструктора лучше оставлять обработчику более высокого уровня, нежели try..finally..end; |
Автор: Bose 4.6.2008, 17:13 | ||||
Вот ещё совет-грабли, - уже раз n-дцать на них наступал. Надо к примеру нам подчистить какой-нибудь списочек. Пример покажу на TStringList. Предположим что нам нужно удалить пустые строки из файла.
А вот ещё кстати частая ошибка
|
Автор: THandle 5.6.2008, 07:54 |
Bose, ну хоть кто-то наконец то что-то предложил ![]() Буду дописывать. ![]() ![]() |
Автор: Bose 5.6.2008, 14:05 | ||||||||
Этот пример получился слишком замороченный, но у меня не раз возникали такие проблемы: Предположим, что Иван узнал что формы можно создавать динамически, и даже стал использовать оператор assign. Дано: Все переменные форм объявлены как глобальные(по умолчанию дельфи так и делает).
При создании форм Иван проверяет, не была ли эта форма уже создана. Пример
А потом Иван узнал что глобальные переменные - это зло и решил сделать все глобальные переменные локальными:
И стал получать Access Violation, ибо неициализированные локальные переменные, не равны nil, так что условие not assigned(Form1) никогда не срабатывает. Добавлено @ 14:09 А вот ещё вредный совет, на этот раз ООП-шный:
Если мы перегружаем какой-либо метод в наследнике, не в коем случае не используем директиву override ![]() |
Автор: THandle 10.6.2008, 10:36 | ||||||||||||||
Это то же самое что и со строками, загоню в один "раздел" их ![]() Про строки я имел ввиду вот это:
Хороший пример ![]()
Ага ![]() Вообще постараюсь по-чуть чуть писать, но так как времени не много то быстро не получится ![]() А вы пока предлагайте новые идеи. Надо хотя бы не меньше 20 пунктов сделать а пока только 12: 1. Работа со строками в цикле. Почему с 1, а не с 0. 2. Работа со списками. Почему с 0, а не с 1. 3. Почему конструктор надо вызывать не как обычный метод? 4. Почему конструктор надо вызывать до try..finally..end? 5. Почему нельзя уничтожить объект в своем же обработчике? 6. Почему надо вызывать не Destroy, а Free? 7. Почему в цикле for нельзя менять значение переменной-счетчика этого же цикла? 8. Эквивалентны ли записи if b = true then и if b then? 9. Почему в цикле for со строками не надо вводить еще одну переменную в которую будет перед циклом заносится длина строки, и эта переменная будет являться конечным значением цикла? 10. Почему в цикле for 0т 1 до длины некоторой строки и удалении некоторых знаков из этой строки, удаляются не все знаки? То же самое относится и к удалению строк в TStringList. 11. Локальные переменные, которые при not Assigned выкидывают AV. 12. Override в перекрытом методе в наследнике какого-то класса. Буду постепенно писать. Всем удачи!!! |
Автор: Bose 11.6.2008, 12:59 | ||
Корректура:
THandle, дальше код идёт, и там тоже i с 0 по length-1. Опечатка по ходу =) |
Автор: THandle 11.6.2008, 14:51 | ||
Ага ![]() ![]() |
Автор: THandle 25.10.2008, 15:12 |
Решил в свободное время возобновить работу над проектом. Если есть еще предложения - пишите. |
Автор: bems 27.1.2009, 21:54 | ||
это ж только про шортстринги! Добавлено через 8 минут и 8 секунд
на самом деле, даже если бы конечное значение и ращитывалось на каждой итерации, то ничего страшного все равно бы не случилось. Эта страшилка с длиной строки растет из сей, где для нахождения длины строки люди сканировали ее в поисках нуля. Это делало алгоритм квадратичным. А дельфовая функция length благополучно проверяет поле длины строки по отрицательному смещению от первого символа, поэтому ее можно использовать и в условиях для цикла while без присваивания переменной |
Автор: roschinspb 18.2.2010, 19:14 | ||||
На тему дэльфовых заблуждений: Всегда надо делать так:
Ни в коем случае не так:
|