![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Siberian GRemlin |
![]()
Сообщение
#121
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 533 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Или, вот, скажем, в сях любое условие считается ложным, только если оно ноль/NULL - иначе истина. Здесь есть обратная сторона: попытка изменить строку на «0» (строка с одним символом нуля) приведёт к нежелательным результатам. Иногда можно встретить ошибку в современном ПО, связанную с отсутствием проверки данного случая. В чистом «Си» может такого конечно и нет, но вот в его производных, полагаю, д. б., иначе откуда бы взялась ошибка. |
-=CHE@TER=- |
![]()
Сообщение
#122
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Здесь есть обратная сторона: попытка изменить строку на «0» (строка с одним символом нуля) приведёт к нежелательным результатам. Иногда можно встретить ошибку в современном ПО, связанную с отсутствием проверки данного случая. В чистом «Си» может такого конечно и нет, но вот в его производных, полагаю, д. б., иначе откуда бы взялась ошибка. Если честно, то не совсем понял о чём идёт речь.Смотри, есть такая штука: CODE char sc[20]; // строчка с 20-тью символами char *sp; // указатель на строчку ... /* char всегда один байт, но если изменить на WCHAR, то здесь будет выделено нужное количество символов (а не байт) т.к. умножается на размер одного символа, такой способ выделения памяти универсальный */ sp = malloc(20 * sizeof(sp[0])); /* по твоему вопросу - обе строчки ниже делают строку пустой - "" т.к. это ASCIIZ строка - вполне легальная операция, так и делают */ sc[0] = 0; sp[0] = 0; // можно и так написать: *sc = 0; *sp = 0; free(sp); // а вот это - зануление указателя sp = NULL; /* которое будет, если ошибиться, аналогично вот такому (потому что NULL и 0 для компилятора одно и тоже), т.е. хотели обнулить строчку, а обнулили указатель не неё (это ещё и утечка памяти) */ sp = 0; // это ошибка! - либо sp = NULL, либо *sp = 0; /* проверка существования и не пустоты строки sp - тоже самое, что и (sp != NULL) - т.е. память выделена *sp - это тоже самое, что и (sp[0] != 0) - т.е. строка не начинается с нуля, иными словми - не пустая (там есть хотя бы один символ) также хочу заметить, что sp и *sp нельзя менять местами, парой сообщений выше объяснял почему */ if (sp && *sp) { ... } А так-то, наверное, в любом языке есть конструкции, которые потенциально могут привести к ошибке. Ну, некоторые языки, конечно, в этом смысле достаточно сильно ограничены, но вот, скажем, от ошибок в логике работы - даже самый жёсткий компилятор не защитит, ибо он не знает, а чего, собственно, хотел человек. |
Siberian GRemlin |
![]()
Сообщение
#123
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 533 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Столкнулся с проблемой: «сишные» консольные приложения все 16-иразрядные, а у меня сейчас основная ОС это XP x64, которая не умеет их запустить. Есть ли «мини» компилятор, чтобы перегнать их в 32? Исходники в наличии.
|
-=CHE@TER=- |
![]()
Сообщение
#124
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Столкнулся с проблемой: «сишные» консольные приложения все 16-иразрядные, а у меня сейчас основная ОС это XP x64, которая не умеет их запустить. Есть ли «мини» компилятор, чтобы перегнать их в 32? Исходники в наличии. Самое простое - бери старенький Visual Studio C++ 6.0 и компилируй под ним - плюс в том, что получившиеся программы будут работать под любым Windows и пользователям не нужно будет специальные библиотеки для запуска устанавливать. Или MinGW попробуй, но там есть свои заморочки (DEV-CPP можешь взять - там урезанная версия, безо всяких специфических вещей, однако для компиляции большинства кода её хватает - только бери старую версию, иначе придётся с программами ещё чемодан .dll файлов тащить - в современной версии MinGW свои зависимости).Но главное, с типами разберись, потому что если у тебя DOS-приложение, но 32-х битное (защищённый режим), то всё нормально. А если реальный режим или 16-битный защищённый, то у тебя при компиляции под 32-бита int "2 байта" превратится в int "4 байта", ибо по спецификации языка Си: short <= int <= long Т.е. для 16 имеем: 2 <= 2 <= 4 [16 bits] а для 32 уже вот так: 2 <= 4 <= 4 [32 bits] и для 64 битного компилятора: 2 <= 4 <= 8 [64 bits] Вроде бы так. Поэтому такая простая функция: CODE int x; ... // читаем в x 1 элемент размером 2 байта fread(&x, 2, 1, fl); ... // читаем в buff 1 элеменет размером x байт fread(buff, x, 1, fl); Может уронить программу если "x" не обнуляли, ибо локальные переменные в функциях НЕ инициализируются нулями. Т.е. у тебя там мусор был, например, 0x12345678 и ты из файла прочитал два байта (размер структуры, например, число 8 там) и получил, например, 0x12340008 - т.е. старшие два байта не обнулены и получилось офигенно большое число. И вот такой код: CODE // читаем в x 1 элемент размером sizeof(x) байт fread(&x, sizeof(x), 1, fl); Хотя и полностью заполняет все байты в x, но тоже уронит программу, потому что раньше sizeof(x) == 2, а теперь 4 - т.е. ты читаешь два лишних байта из файла. Короче, скомпилировать программу под 32 бита - это только половина проблемы - нужно ещё проверить логику работы. |
-=CHE@TER=- |
![]()
Сообщение
#125
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Добавил в своё сообщение некоторые изменения:
- теперь неважно в каком подкаталоге проекта лежит скрипт - "%~d0%~p0" решает эту проблему; - добавлен ключ "-X" (X - заглавная), который выкидывает дополнительные атрибуты файлов при добавлении - без этого ключа получившиеся архивы даже на максимальном сжатии (-9) всегда будут жирнее тех .ZIP, что создаёт на максимальном же сжатии WinRAR. |
-=CHE@TER=- |
![]()
Сообщение
#126
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Поставил я тут новый colorer для FAR и моя тачка захлебнулась обрабатывая те PHP скрипты, которые раньше без проблем редактировались. Так что откатился я на colorer version 'freeCraze' за 08.03.2000. Продолжая тему colorer'а.Работает резко, но там косяки были с раскраской у PHP - пришлось вручную дожимать до рабочего состояния. У меня стоят несколько плагинов для FAR Manager, в том числе и Calculator v3.0 by Cail Lomecb © 1998-2001 (calc). Калькулятор этот при всех достоинствах адово часто падает, если в выражении встречается буква "e" (экспоненциальная запись числа). Сам я этой функцией редко пользуюсь, а вот если в шестнадцатеричном числе встретилась такая буква, а после неё ещё и цифра - всё, труба. Что заметил, если запустить FAR и сразу запустить калькулятор вбив туда "9e999", то результат будет "1.#INF" (как и должно). А если сначала открыть любой файл на редактирование (перед этим colorer выводит окно "just wait - i'm realoading..."), то после этого упомянутое выше выражение будет приводить к обвалу калькулятора. Иногда, кстати, и colorer обваливается тоже, но при каких условиях сказать затрудняюсь, ибо это редко происходит. В общем, если кто-то знает как это исправить - с удовольствием выслушаю, ибо задолбало. Исходные коды есть и к colorer и к calc, но они оба на C++, с классами, XML и прочим хламом, так что вызывают зубную боль. Я бегло их просмотрел - явно ошибки не видно и нужно серьёзно дебажиться, либо вникать в код (а его там тонны), чтобы её найти. |
Grom PE |
![]()
Сообщение
#127
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 84 Регистрация: 7-February 08 Из: i@grompe.org.ru Пользователь №: 3,120 Спасибо сказали: 95 раз(а) ![]() |
Калькулятор этот при всех достоинствах адово часто падает [...] А почему бы не заменить этот calc скриптами на Lua? Я в восторге от скриптов.В общем, если кто-то знает как это исправить - с удовольствием выслушаю, ибо задолбало. Сейчас взял и опубликовал свои наработки: http://grompe.org.ru/#far_scripts.zip После установки скриптов можно будет делать так: CODE 0xFF + 14 (Ctrl+Enter на строке)CODE 0xFF + 14=269 Или если нравится, F11 → "Execute Lua on Selection" → "0xFF + 14" введёт в редактор 269. Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#128
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
А почему бы не заменить этот calc скриптами на Lua? У меня Far 1.70 build 2087 - к нему плагин для Lua подойдёт? Вчера попробовал тройку (Far 3) - адово медленно работает, даже если отключить в нём практически всё, то та же смена каталога происходит заметно тормозней. По той же причине не стал ставить новый colorer - с ним работать ну просто невозможно, настолько всё медленно ворочается.После установки скриптов можно будет делать так: А если я структуру файла по F3 изучаю? Мне через Ctrl+Tab переключаться на текстовый файл, чтобы там посчитать, затем назад вернуться и перейти, скажем, по нужному смещению? Много лишних телодвижений получается. К тому же, ещё со времён DOS Navigator, привык я к калькулятору по Ctrl+F6. Кстати говоря, поглядел код калькулятора в исходных кодах DN - в принципе, вытащить его оттуда можно... Но заморачиваться не особо хочется. Разве что копипастнуть в проект на Delphi, но тут опять могут кривые файлы FAR SDK для Delphi/Pascal подвести, плюс Delphi антивирусы не любят. Разве что плагин для себя собрать.CODE 0xFF + 14 (Ctrl+Enter на строке)CODE 0xFF + 14=269 Или если нравится, F11 → "Execute Lua on Selection" → "0xFF + 14" введёт в редактор 269. Я в восторге от скриптов. Сейчас взял и опубликовал свои наработки: http://grompe.org.ru/#far_scripts.zip А я никогда не сомневался, что ты крут!Добавлено: Таки решил проблему с калькулятором - все подробности здесь. |
Grom PE |
![]()
Сообщение
#129
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 84 Регистрация: 7-February 08 Из: i@grompe.org.ru Пользователь №: 3,120 Спасибо сказали: 95 раз(а) ![]() |
У меня Far 1.70 build 2087 - к нему плагин для Lua подойдёт? Вчера попробовал тройку (Far 3) - адово медленно работает По-моему нет, скрипты на Lua — это фича именно Far 3. Странно, а я не замечал тормозов с ним. Colorer чуть медленней, это да, я замечал.QUOTE А если я структуру файла по F3 изучаю? Можно и для просмотрщика макрос написать под удобное сочетание.QUOTE [...] и перейти, скажем, по нужному смещению? Можно именно для этого сочинить макрос, будет типа как в Hiew. Кстати, а ты не используешь Hiew для просмотра бинарных файлов что ли?QUOTE А я никогда не сомневался, что ты крут! Хех, спасибо =) |
-=CHE@TER=- |
![]()
Сообщение
#130
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
По-моему нет, скрипты на Lua — это фича именно Far 3. Странно, а я не замечал тормозов с ним. Colorer чуть медленней, это да, я замечал. У меня компьютер старый. Уже где-то на форуме обсужалось, для работы хватает, обновлять не хочу.Можно и для просмотрщика макрос написать под удобное сочетание. Не, ты не понял - в просмотрщике же нет курсора. Как ты там будешь что-то писать или указывать?Можно именно для этого сочинить макрос, будет типа как в Hiew. Если у тебя все файлы будут одного формата - тогда да. А так-то структура файлов разная.Кстати, а ты не используешь Hiew для просмотра бинарных файлов что ли? Не, HIEW'ом-то я как раз пользуюсь, но только для редактирования файлов, а если быстро нужно что-то посмотреть/проверить, то из FAR никуда не ухожу - открыл файл на просмотр и какой-нибудь текстовичок для записи, а дальше Ctrl+Tab или через F12 переключаюсь. |
Grom PE |
![]()
Сообщение
#131
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 84 Регистрация: 7-February 08 Из: i@grompe.org.ru Пользователь №: 3,120 Спасибо сказали: 95 раз(а) ![]() |
У меня компьютер старый. Уже где-то на форуме обсужалось, для работы хватает, обновлять не хочу. Комп ещё более тормозной, чем мой постоянно перегретый нетбук? Сожалею.Насколько я помню, я перешёл на Far 3 из-за поддержки UTF-8. QUOTE Не, ты не понял - в просмотрщике же нет курсора. Как ты там будешь что-то писать или указывать? Так можно диалогами обойтись, окошком ввода да окошком сообщения результата. Или объединить их.QUOTE Если у тебя все файлы будут одного формата - тогда да. А так-то структура файлов разная. Под какой надо формат, под тот и написать (отредактировать). Я ради интереса написал скрипт для прыжков по 4-байтному смещению в просмотрщике:Viewer_HexJump.lua QUOTE Не, HIEW'ом-то я как раз пользуюсь, но только для редактирования файлов, а если быстро нужно что-то посмотреть/проверить, то из FAR никуда не ухожу - открыл файл на просмотр и какой-нибудь текстовичок для записи, а дальше Ctrl+Tab или через F12 переключаюсь. Я повесил HIEW на Alt+F4 (хех), и использую для просмотра тоже, удобно же. А сейчас только что обнаружил фичу "console detach key" в Far'е, а то всё время грустил, что для заметок нужно второе окно Far'а открывать.Спасибо сказали:
|
-=CHE@TER=- |
![]()
Сообщение
#132
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Комп ещё более тормозной, чем мой постоянно перегретый нетбук? Сожалею. Не стоит, но всё равно спасибо за сочувствие. (*улыбается*)Насколько я помню, я перешёл на Far 3 из-за поддержки UTF-8. Да, но я стараюсь с файлами в этой кодировке не связываться.Я повесил HIEW на Alt+F4 (хех), и использую для просмотра тоже, удобно же. А сейчас только что обнаружил фичу "console detach key" в Far'е, а то всё время грустил, что для заметок нужно второе окно Far'а открывать. Блин, да ты нереально крут! Действительно ConsoleDetachKey CtrlAltTab - единственная проблема, она расположение окна не воспринимает (приходится снова Alt+F9 два раза жать) и срабатывает в HIEW только с 3-4 нажатия (уж не знаю почему). |
-=CHE@TER=- |
![]()
Сообщение
#133
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Давно уже Delphi 7 не использую толком, практически полностью на Си перешёл.
А тут понадобилось быстро склепать GUI-программку для поиска эксперементального значения "a" с некоторым диапазоном погрешности "b" в базе данных, где каждое значение из БД на текущем шаге равно "c". Натолкнулся на офигенный косяк: CODE program d7double; {$APPTYPE CONSOLE} var a, b, c: double; begin a:=56.4; b:=0.2; c:=56.6; if ((c >= (a - b)) and (c <= (a + b))) then writeln('Never get this, because...') else writeln('Delphi 7 float-point types bug!!!'); end. Если подумать, то 56.4 + 0.2 = 56.6, но первый writeln() никогда не выполнится для типов Double, Real и Comp. Причём, первые два типа, на самом деле, один и тот же тип (просто название разное), если переключатель в Real48 не задан. Переписал эту программу на Си (там тип double такой же) и собрал под GCC - всё отлично, первая строка выводится. Более того, если собрать эту программу под DCC32HACK от Grom PE то условие также срабатывает! Походу это косяк какой-то стандартной библиотеки, которая подключается при компиляции программы в обычном Delphi 7. |
Grom PE |
![]()
Сообщение
#134
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 84 Регистрация: 7-February 08 Из: i@grompe.org.ru Пользователь №: 3,120 Спасибо сказали: 95 раз(а) ![]() |
А что ты хотел? Во второй проверке ты сравниваешь 56.6 и 56.6 после сложения, то есть в зависимости от типа и реализации будет либо 56.600000000000001, либо 56.599999999999999. Косяк здесь — точно сравнивать дробные числа.
|
-=CHE@TER=- |
![]()
Сообщение
#135
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Косяк здесь — точно сравнивать дробные числа. Это я уже понял и, т.к. в БД значения хранились с точностью до двух знаков после запятой, то просто выравниваю также введённые значения, а затем всё это перевожу в целое игнорируя точку (типа умножить на 100), а потом уже сравниваю - и быстрее, и проблем меньше.А что ты хотел? А я бы хотел чтобы Delphi 7 без хаков (типа DCC32HACK) работал также как и GCC и прочие компиляторы. Потому что это - косяк, как ни крути. |
-=CHE@TER=- |
![]()
Сообщение
#136
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Зацените прикол.
Ковырялся тут в чужих исходных кодах и обнаружил такую штуку: CODE do { if (! условие1) { break; } // кусок_кода_1 if (! условие2) { break; } // кусок_кода_2 if (! условие3) { break; } // кусок_кода_3 ... } while(0); Думаю: что за фигня, зачем делать цикл, с постусловием, который всего один раз выполнится, ибо условие ложно (0) - можно же, вообще, без цикла обойтись. Тогда зачем? И тут, поглядев на кучу break до меня дошло, что автору кода тупо было лень его структурировать. Выглядеть код, по нормальному, должен был вот так: CODE if (условие1) { // кусок_кода_1 if (условие2) { // кусок_кода_2 if (условие3) { // кусок_кода_3 ... } } } Ибо break выкидывает из цикла на следующую, после его конца, инструкцию. С одной стороны такой финт ушами не запрещён. С другой - непонятно как к нему отнесутся всякие навороченные оптимизирующие компиляторы, которые короткие циклы разворачивают для линейного исполнения, а также всякие статические анализаторы кода. Вроде, с одной стороны метки и goto не используются, так что и поругать не за что, а с другой стороны способ вызывает сомнения и прочие смешанные чувства относительно того стоит ли его применять. |
Grom PE |
![]()
Сообщение
#137
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 84 Регистрация: 7-February 08 Из: i@grompe.org.ru Пользователь №: 3,120 Спасибо сказали: 95 раз(а) ![]() |
Поначалу непривычно, но потом понимаешь, что это та же функция с рядом проверок и после каждой return. Наверняка и следует это оформить в качестве отдельной функции.
|
-=CHE@TER=- |
![]()
Сообщение
#138
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Поначалу непривычно, но потом понимаешь, что это та же функция с рядом проверок и после каждой return. Наверняка и следует это оформить в качестве отдельной функции. Вот я тоже так думал. Но если у тебя много разных переменных проверяется, то представь какого размера будет у этой функции список входных параметров? (*улыбается*)Хотя такие вещи, скорее всего, говорят о том, что сама архитектура программы, в целом, мягко говоря не фонтан. (*улыбается*) Но если работаешь с чужим кодом, то приходится выбирать из меньшего количества костылей, да. |
-=CHE@TER=- |
![]()
Сообщение
#139
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Надавно выдирал один код из другой программы на asm'е и после компиляции слегка окосел от результата:
CODE use16; компилируем 16-ти битный код ... mov bp, sp ... В той программе, откуда я дёрнул этот кусок, данная инструкция была представлена последовательностью байт: 8B EC А FASM скопмилировал эту инструкцию в: 89 E5 Погуглив выяснил, что я не один недоумеваю от происходящего. Цитата из той темы (я специально её дополнил и раскрасил, чтобы понятно было что к чему): QUOTE 10001011 - 11 101 100 (8B - EC) bp<-sp Там же, кстати, в теме есть ссылка на другую тему с примерами - кое-что можно аж 4 разными способами закодировать.10001001 - 11 100 101 (89 - E5) sp->bp Бит направления в первом случае установлен, а во втором нет. SP = 100 BP = 101 |
-=CHE@TER=- |
![]()
Сообщение
#140
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,355 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 311 раз(а) ![]() |
Это не совсем к программированию, но тем не менее.
Мучил я тут одну линуксовую прогу портированную под Windows, а там всё, что начинается с "-", это ключ командной строки. Поэтому, кстати, в DOS / Windows программах ключи начинаются с "/" - этот символ в имени файлов запрещён. Проблема в чём, вызываю я программу (да, имя входного файла с "-" начинается): thistool.exe -newfile.ext -opt1 -opt2 -opt3 ... А в программе позиция аргумента не привязана жёстко и считается что входной файл это всё, что не начинается с символа "-". Поэтому программа ругалась, требуя имени файла и недоумевая по поводу незнакомого ей ключа командной строки. А в другой программе, где я файл использовал, он должен был начинаться с "-". Короче, задолбался я переименовывать туда-сюда и решил эту проблему таким макаром - добавил ссылку на текущий каталог (".\") и оно, наконец-то, прожевало файл: tool.exe .\-newfile.ext -opt1 -opt2 -opt3 ... Можно и полный путь указать: thistool.exe C:\MYFOLDER\-newfile.ext -opt1 -opt2 -opt3 ... |
![]() ![]() |
Упрощённая версия | Сейчас: 29th April 2024 - 01:37 |