![]() |
Кодерские tips and tricks
Кодерские tips’n’tricks
В данной теме делимся программерскими трюками. Это могут быть советы по оптимизации, нестандартные приемы, интересные (но не слишком большие) куски кода. Не стоит превращать тему в свалку исходников, выбирайте наиболее интересные и полезные участки кода. Желательно откомметировать трюк, чтобы всем было понятно. Delphi Оптимизация [Передача аргументов] Никогда не передавай функции в качестве параметра структуру, лучше передавать указатель на нее Код:
//Ни в коем случае не делай так.[Функции - инварианты] Довольно распространенная ошибка программистов – присутствие функций - инвариантов в цикле. Код:
//Неоптимизированный вариантКод:
//Так лучшеКод:
// Неоптимизированный вариантКод:
// Оптимизированный вариантДля уменьшения размера скомпилированных прог исправим модели System.pas и SysInit.pas, удалив все «лишнее». Затем перекомпилируем их и полученные dcu-файлы поместим в папку с прогой. Минимальный System.pas Код:
unit System;Код:
unit SysInit;Код:
Dcc32.exe – Q System.pas SysInit.pas –M –Y –Z -$D- -OНекоторые трюки [Обмен] Обмен значений между двумя переменными без привлечения третьей. Код:
x:=x xor y; |
Оптимизация выходного файла в Microsoft Visual C++.
Параметры линкера для уменьшения размера: - объединение секций Код:
/MERGE:.data=.text /MERGE:.rdata=.textКод:
/ALIGN:32Код:
/ALIGN:512- смена точки входа Код:
/ENTRY:mainКод:
/ENTRY:WinMain- еще можно убрать нафиг CRT или линковать ее динамически: Код:
/NODEFAULTLIB msvcrt.libКод:
#include <windows.h>Дизассемблерный листинг точки входа не содержит ни одного лишнего байта: Код:
00400230 >/$ 55 PUSH EBP/ALIGN:16 /DRIVER это нужно вписать в настройки проекта, в #pragma comment(linker) это не прокатит |
Delphi
Чтобы во время выполнения циклов, не происходил эффект зависания, нужно в теле цикла вставить Код:
Application.ProcessMessages; |
в VCL (delphi) есть "перехват" закрытия формы
OnCloseQuery (где canclose boolean типа который и дает "разрешение" на закрытие формы)... |
Экстремально маленький Hello Word! на Delphi.
Собирать исполняемый файл линкером от Microsoft. К сожалению, майкрософтовкий линкер понимает только COFF и Intel OMF, наотрез отказываясь работать с Borland OMF. Delphi же, начиная с третьей версии, перешла с формата Intel OMF на Borland OMF. Поэтому компилировать придется компилятором от Delphi 3. Пример минимального HelloWord. Код:
Unit HelloWord;Компилируем: Dcc32.exe –JP -$A-,B-,C-,D-,G-,H-,I-,J-,L-,M-,O+,P-,Q-,R-,T-,U-,V-,W+,X+,Y- HelloWord.pas Открываем файл HelloWord.obj в HEX-редакторе и смотрим во что превратилась наша точка входа. Допустим Start$wwrv. Теперь выполняем сборку Link.exe /ALIGN:32 /FORCE:UNRESOLVED /SUBSYSTEM:WINDOWS /ENTRY:Start$wwrv HelloWord.obj user32.lib /out:Hello.exe В результате имеем файл размером 832 байта. |
в библиотеках (касается Delphi) если передаешь string данные от лучше заюзать переменную типа ShortString либо добавить ShareMem в раздел Uses... Имхо 1 лучше...
а если явно передаваемые данные string (например Edit1.Text), преобразуй ShortString(Edit1.Text); таким образом можно пребразовывать не только ShortString, но допустим и из string в PChar=> pchar(edit1.text) |
Вот нашел несколько полезных советов для M$ Visual Studio.
Кому интересно - оригинал тут Я приведу собственный перевод с моими комментариями. 1. Учим Visual Studio раскрывать структуры и классы в отладчике Редактируем файл \Program Files\Microsoft Visual Studio\Common\MSDev98\Bin. Его формат можно определить методом тыка, посмотрев уже существующие строки. (Там все не так уж и сложно. В начале файла есть немаленький комментарий про синтаксис. Насколько я понял, просто вместо древовидной структуры объекта или структуры будет показываться одно значение. Например, для CString - m_pchData - Прим. Great). 2. Добавляем слова для подсветки. Если создать файл usertype.dat в каталоге \Program Files\Microsoft Visual Studio\Common\MSDev98\Bin со словами по одному на строчку, то эти слова студия будет выделять синим цветом как ключевые. (Я уже добавил туда main и WinMain для удобства - Прим. Great). 3. Как использовать расширение *.cc для C++ Нужно произвести следующие изменения в реестре: Цитата:
4. Как закрепить меню. В Visual Studio панель меню перемещаемая (об этом говорят две полосы слева). Если это мешает, это можно убрать, выставив галочку "Use screen reader compatible menus" в диалоговом окне Tools -> Options -> закладка Worspace 5. Напоминания при компиляции Если у тебя плохо с памятью :) и тебе сложно запомнить, например, что вот тот кусок кода в финальной версии желательно убрать или что в этом коде содержится некритичная проблема, можно сделать себе напоминание: Код:
#define Stringize( L ) #LЦитата:
Просто поставить код Код:
__asm int 3;7. Отладочные значения в различных областях памяти программы 0xCDCDCDCD Память выделена в куче, не инициализирована 0xDDDDDDDD Память, выделенная в куче, уже освобождена 0xFDFDFDFD Заполнитель NoMansLand записывается у границ участка памяти для контроля распространенного типа ошибки выхода за границы массива и переполнения. После затирании это указатели при освобождлении этой памяти free/delete выдаст диалоговое окно: DAMAGE: after ТИП block (#номер) at 0xадрес., где ТИП - обычно Normal - тип освобождаемого участка, номер - номер блока. Пример неправильного кода: Код:
char* a = new char[2];0xCCCCCCCC Выделено в стеке, не инициализировано 8. Предопределенные псевдопеременные во время отладки В окно Watch можно добавить следующие "переменные": @err - последняя ошибка (GetLastError) @tib - адрес Thread Information Block потока @clk - время выполнения программы (мс) 9. Просмотр указателей как массивов Обычно, если добавить в окно Watch переменную типа char*, она покажется как строка, а не как массив. Чтобы посмотреть отдельные элементы массива (например, чтобы узнать ASCII-код символа из этой строки), надо добавить в Watch выражение переменная,длина, где переменная - переменная указательного типа, длина - за массив какой длины отладчик ее должен считать. Например, пусть объявлен char* str; Выражение str,10 нам покажет всю строку + отдельно как массив ее первые 10 символов (в массиве - индексы 0-9). Выражение ((char*)&main),100 покажет нам первые 100 байт машинного кода функции main 10. Вызов программных функций во время отладки Если у тебя есть функция, например, Код:
int function()11. Именование потоков при отладке Следущий код содержит функцию, позвляющую назвать поток с указанным ID'ом своим именем Код:
#define MS_VC_EXCEPTION 0x406d1388 |
Не совсем в тему, но все же. Поиск базы длл по ее имени в адресном пространстве другого процесса (аналог GetModuleHandle, но для др. адресного пространства).
Может, кому понадобится. Писал я по просьбе протеуса ну и соотв. там мои норкоманские идеи :) Итак, че же для этого я сделал. Ищем первый поток процесса. С помощью GetThreadSelectorEntry получаем запись LDT по селектору FS = 0x3b. Открываем Thread Environment Block, из него Process Environment Block, из него - структуру данных загрузчика (все это через ReadProcessMemory), потом проходимся по списку модулей. Код:
const DWORD FS = 0x3B; |
Цитата:
Код:
DWORD RemoteGetModuleHandle(char *name, DWORD dwPid) |
Cr4sh, нуууууу ))) так не прикольно :)) Прикольно вручную анализировать ))
Хотя изобретать велосипед, конечно, тоже не стоит ) |
| Время: 04:17 |