Кодерские tips and tricks

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by TaNkist, 16 Nov 2006.

  1. Joker-jar

    Joker-jar Elder - Старейшина

    Joined:
    11 Mar 2007
    Messages:
    581
    Likes Received:
    205
    Reputations:
    37
    Delphi. Простая, но очень полезная функция (при написании игр, искусственных интеллектов, эмуляторов игровых автоматов и т.д.). Функция идентична random: boolean, только с параметром percent, (0 <= percent <= 100) - вероятностью истинного результата. Например, probrandom(80) вернет true с вероятностью 80%.
    Code:
    function probrandom(percent: integer): boolean;
    begin
      result := random(100) < percent;
    end;
    З.Ы. Не забываем инициализировать генератор случайных чисел (randomize)
     
    #21 Joker-jar, 24 May 2007
    Last edited by a moderator: 26 May 2007
  2. Joker-jar

    Joker-jar Elder - Старейшина

    Joined:
    11 Mar 2007
    Messages:
    581
    Likes Received:
    205
    Reputations:
    37
    Code:
    const
      alf = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
      function power(x,y: integer): int64;
      begin
        if x = 0 then
          result := 0
        else
          result := trunc(exp(ln(x)*y));
      end;
    
      function fromdec(d: int64; s: integer): string;
      begin
        if (d < s) then
          result := alf[d + 1]
        else
          result := fromdec(d div s,s) + alf[d mod s + 1];
      end;
    
      function todec(d: string; s: integer): int64;
      begin
        if length(d) = 1 then
          result := pos(d,alf) - 1
        else
          result := (pos(d[1],alf) - 1) * power(s, length(d)-1) + todec(copy(d,2,length(d)-1),s);
      end;
    Delphi. Системы счисления. 2 <= s <= 36

    З.Ы. Рекурсия рулит
     
    1 person likes this.
  3. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    И все-таки, как написано в 1 посте, "Не стоит превращать тему в свалку исходников, выбирайте наиболее интересные и полезные участки кода."
    Выбирайте действительно ИНТЕРЕСНЫЙ и НЕОБЫЧНЫЙ код, какието нестандартные приемы там и прочее. Банальщина типа реализации CopyFile не очень нужна.
     
    1 person likes this.
  4. Ch3ck

    Ch3ck Elder - Старейшина

    Joined:
    9 Jun 2006
    Messages:
    1,363
    Likes Received:
    1,192
    Reputations:
    430
    Выводит содержимое файла в шестнадцатиричном формате и в виде ASCII кодов.

    Code:
    #include <iostream>
    #include <fstream>
    #include <cctype>
    #include <iomanip>
    using namespase std;
    
    int main(int argc, char *argv[])
    {
    		 if(!argc=2) {
    		   cout << "USAGE: Display" 
    		   rerutn 1;
       }
    ifstream in(argv[1], ios::in | ios::binary);
    		 if(!in) {
    		 cout << "Cannot open input file.\n";
    		 return 1;
       }
    register int i, j;
    int count = 0;
    char c[16];
    		 cout.setf(ios::uppercase);
    			while(!in.eof()){
    			 for(i=0; i<16 && !in.eof(); i++) {
    			   in.get(c[i]);
       }
    if(i<16) i--;
    for(j=0; j<i; j++)
    cout << setw(3) << hex << (int) c[j];
    for(; j<16; j++) cout << "  ";
    cout << "\t";
    for(j=0; j<i; j++)
    if(isprint(c[j])) cout << c[j];
    else cout << ".";
    cout endl;
    	  count++;
    if(count=16) {
    count=0;
    cout << "Press ENTER to continue: "'
    cin.get();
    cout << endl;
    }
    }
    in.close();
    return 0;
    }
     
  5. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    штука наверняка не новая, но новичкам может быть пригодится: если возникает трудность с использованием модульности (дополнительных длл-плагинов) в своей программе, а именно в обработке плагином, например, своего объекта (так как по-хорошему мы не знаем как он представляется в памяти и видимо не должны знать по причине того, что плагин может быть написан абсолютно на чем угодно), то можно написать свою дополнительную длл, которая имеет набор функций по созданию\обработке обьекта (да хоть переменной какой-то структуры) в пространстве процесса из которого происходила загрузка сего и ее использовать как плагинной так и основной частью программы.
     
  6. [53x]Shadow

    [53x]Shadow Leaders of Antichat

    Joined:
    25 Jan 2007
    Messages:
    284
    Likes Received:
    597
    Reputations:
    514
    Функция-шаблон считывания из потока n байт.
    Написал специально для удобства работы с различными потоками в stl. Так, например, нет стандартного метода считывания n байт из объекта ifstream в string в stl.


    Code:
    template
    	<
    		typename InputIterator,
    		typename OutputIterator
    	>
    	void readn(InputIterator begin, InputIterator end, int n, OutputIterator out)
    	{
    		for(;n > 0 && begin != end;--n, ++begin, ++out)
    		{
    			*out = *begin;
    		}
    	}
     
  7. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    Будь-то программирование на winapi, будь-то программирование на posix при создании многопоточного приложения одинаково часто возникает неудобство выраженное в виде невозможности стандартным образом передать своей функции через CreateThread/pthread_create более одного аргумента. Пример двух используемых функций по вин thread.c:
    Code:
    /*
     thread.c by ZaCo
    */
    
    #include <windows.h>
    //вспомогательная функция-поток из которой вызываем запрашиваемую функцию
    
    void * Thread(int * temp)
     {
      void * func=(void *)(*temp);//вызываемая функция
      temp++;                     //переходим к следующему адресу
      int num=*(int *)temp;       //кол-во аргументов
    
      int i;
    
      temp+=num;                 //сдвигаемся просто до конца тк аргументы нужно передавать задом-наперед ;)
    
      for(i=num-1;i>=0;i--,temp--)
       {
        int * param=*(int **)temp;//каждый раз получаем нужный адрес
        _asm push param;
       }
    
      delete [2+num] (temp-1);    //освобождаем память выделенную в NewThread
    
      _asm call func;             //вызываем функцию
      return NULL;
     }
    
    //функция создания потока: func - функция, num - кол-во аргументов-указателей после num
    
    void * NewThread(void * func, unsigned int num, ...)
     {
      int * temp=new int[2+num];  //temp - массив адресов которые  в итоге нужно передать функции-потоку
      memcpy(temp,&func,(2+num)*sizeof(void*));
    
      CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,temp,0,NULL));
     }
    
    //
    Работа в основной программе:
    Code:
    #include <stdio.h>
    void * NewThread(void *, unsigned int, ...);
    void * Thread(int *);
    #include "thread.c"
    
    void * func(int * a,char * b,int * c, char * s)
     {
      printf("%d+%d+%d+%s\n",*a,*b,*c,s);
      return NULL;
     }
    
    int main(int argc, char* argv[])
    {
     int a=5,b=7,g=4;
     char s[]="it's xek!";
    
     NewThread(func,4,&a,&b,&g,&s[0]);
    
     Sleep(1000);
     return 0;
    }
    
     
    2 people like this.
  8. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    Для Microsoft Visual Studio 7 (она же 2003 .NET):

    Если нет желания таскать за собой рантайм в том или ином виде, а при его отключении линкер орёт на неразрешенные ссылки на __chkstk, ___securitycookie и @__security_check_cookie@4, можно обойтись следующей реализацией этого (писал сам :))

    Code:
    // будем тока выделять место в стеке под переменные
    extern "C" __declspec(naked) void _chkstk()
    {
    	__asm
    	{
    		// Enter: EAX = size
    
    		xor ebx, ebx
    		xchg [esp], ebx  // запоминаем адрес возврата
    		add esp, 4  // удаляем его
    		sub esp, eax  //  выделяем место
    		push ebx  // кладем адрес возврата на место и возвращаемся
    		retn
    	}
    }
    
    // любое число, в принципе, но чтобы оно было "случайное", а не вида 00010000.
    // хороший вариант - 19237845 или BACBBAFD или что-нибудь в этом роде
    extern "C" DWORD_PTR __security_cookie = 0x5F8E34B0;
    
    // проверка на переполнение буфера
    extern "C" void _fastcall __security_check_cookie(DWORD_PTR cookie)
    {
    	if(__security_cookie != cookie)   // можно добавить ченить более умное при ошибке
    		__asm int 3;
    }
     
    #28 _Great_, 27 Jun 2007
    Last edited: 27 Jun 2007
    1 person likes this.
  9. [53x]Shadow

    [53x]Shadow Leaders of Antichat

    Joined:
    25 Jan 2007
    Messages:
    284
    Likes Received:
    597
    Reputations:
    514
    Stl/c++

    Преобразование из string в int с контролем целостности ;)

    Code:
    bool to_number(char const* beg, int sz, int& num)
    	{
    		char* end = 0;
    		int tmp_num = ::strtol(beg, &end, 10);
    		if(end != beg + sz)
    		{
    			return false;
    		}
    		num = tmp_num;
    		return true;
    	}
    use:
    Code:
    std::string value;
    int num;
    if (!to_number(value.c_str(), value.size(), num))
             return false;
    
     
  10. Piflit

    Piflit Banned

    Joined:
    11 Aug 2006
    Messages:
    1,249
    Likes Received:
    585
    Reputations:
    31
    что правильнее при написании malware и почему: сначала полностью писать тулзу, а потом править ее так, чтобы не детектилась ав или брать хелло ворлд и добавлять к нему по одной функции на каждом шаге проверяя, что наша прога не палится?
     
    1 person likes this.
  11. gevara

    gevara Elder - Старейшина

    Joined:
    29 Nov 2006
    Messages:
    47
    Likes Received:
    7
    Reputations:
    5
    Возникла у меня такая идейка. Функции в Си могут возвращать значение в регистрах eax, edx. Иными словами можно заставить функцию возвратить 2 значения вместо того, чтобы не передавать лишний укказатель указатель. Может быть это не совсем корректно, зато иногда бывает удобно.

    насколько я разобрался - здесь можно поступить двумя способами:

    LARGE_INTEGER function xx()
    {
    }

    void main()
    {
    LARGE_INTEGER a;
    a = xx();
    a.HigthPart ..
    a.LowPart
    }

    или непосредственно к регистрам
    void main()
    {
    int a,b;
    xx();
    __asm{mov b,edx}
    __asm{mov a,eax}
    }

    P.S. для более удобново вызова можно попробовать переопределить операторы...
     
  12. Joker-jar

    Joker-jar Elder - Старейшина

    Joined:
    11 Mar 2007
    Messages:
    581
    Likes Received:
    205
    Reputations:
    37
    Генерации кодов Грея. Пишу для тех, кто знает о чем я. Короче, как вы помните, чувак предложил рекурсивный алгоритм и все такое. Я чуть не попутал, когда убедился, что ту же самую последовательность можно сгенерировать практически одной строкой:

    Code:
    for i := 0 to N-1 do
      writeln(i xor (i div 2));
    Какая нах рекурсия!!!

    Пример использования. Генерация всех подмножеств множества:

    Code:
    {$apptype console}
    
    var
      U: array[0..3] of byte = (1, 2, 3, 4);
      i,k: integer;
    
    function checkbit(d, i: integer): boolean;
    begin
      if (d and (1 shl i)) = 0 then
        result := false
      else
        result := true;
    end;
    
    begin
      writeln('Dano: { 1 2 3 4 }'#13#10);
      for i := 0 to  16 - 1 {16 - 2^N, N=4 - мощность множества} do
        begin
          write('{ ');
          for k := 4-1 {N-1} downto 0 do
            if checkbit((i xor (i div 2)), k) then
              write(U[4-1 {N-1} -k],' ');
          writeln('}');
        end;
      readln;
    end.
    Также хочу показать простой способ построения таблиц истиности логических выражений. Допустим, нужно построить:
    Code:
    X or (Y and Z)
    | X | Y | Z | Y and Z | X or (Y and Z) |
    | 0 | 0 | 0 |    0    |        0       |
    | 0 | 0 | 1 |    0    |        0       |
    | 0 | 1 | 0 |    0    |        0       |
    | 0 | 1 | 1 |    1    |        1       |
    | 1 | 0 | 0 |    0    |        1       |
    | 1 | 0 | 1 |    0    |        1       |
    | 1 | 1 | 0 |    0    |        1       |
    | 1 | 1 | 1 |    1    |        1       |
    Вот так это делается быстро и красиво:

    Code:
    {$apptype console}
    
    type
      myBool = 0..1;
    
    var
      X,Y,Z: myBool;
      i: integer;
    
    function checkbit(d, i: integer): myBool;
    begin
      if (d and (1 shl i)) = 0 then
        result := 0
      else
        result := 1;
    end;
    
    begin
      writeln('X or (Y and Z)');
      writeln('| X | Y | Z | Y and Z | X or (Y and Z) |');
      for i := 0 to 7 do
        begin
          X := checkbit(i,2);
          Y := checkbit(i,1);
          Z := checkbit(i,0);
          write('| ',X,' | ',Y,' | ',Z,' |    ',Y and Z,'    |        ',X or (Y and Z),'       |');
          writeln;
        end;
      readln;
    end.
     
    1 person likes this.
  13. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Вот только недавно сталкнулся с одной проблемой в сетевом программировании.
    Навреное и другие тоже сталкивались с этим.
    А именно: когда стоит на компе Kaspersky Antivirus ( на 6 версии - 100%) то
    любой connect будет удачным. В том смысле:
    при коннекте к любому компу на заведомо закрытый порт - коннект пройдет удачно, в следствии того, что каспер подменяет IP и порт на localhost:1110 - какбы на свой прокси, с целью проверки трафика и именно по этой причине все коннекты являются удачными. Следовательно необходимо заботится о том, чтобы какимнить обрабом проверять естьли коннект реально или нет!
     
  14. DWORD

    DWORD Elder - Старейшина

    Joined:
    24 Jul 2007
    Messages:
    129
    Likes Received:
    70
    Reputations:
    -36
    Ну и извращение! Си позволяет возвращать не только простые, но и сложные типы данных, например структуры, только зачем это нужно, мне например вообще почти никогда не бывает нужно. В С++ - да. При перегрузке операций для классов там без этого не обойтись, а в си...

    __asm{mov b,edx} вот это вообще издевателсьво. Остерегайтесь ассемблерных вставок в windows программах пользователського режима - они там ненужны, кроме того такой С-код непереносим. В gcc специально сделали синтаксис АТ&Т, чтобы неповадно было ассемблер использовать :)
     
  15. DWORD

    DWORD Elder - Старейшина

    Joined:
    24 Jul 2007
    Messages:
    129
    Likes Received:
    70
    Reputations:
    -36
    С такой проблемой не сталкивался, но выход напрашивается, если ты используешь sockets api, проверяй после установки соединения, с кем реально ты соединился (если не sockets api, то наверняка тоже можно)
     
  16. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 DWORD
    В том то и дело, что по всем параметрам соединение идет какбы нормальное. потмоу что всё подменяется довольно четко. А писать громозкий код для определения сетевой активности своей проги - тоже както не хочется.
    Если сам разрабатываешь и серверную и клиентскую часть, то выход прост. А если к примеру делается клиент к уже существующему серверу и идет жесткая организация пакетов типа по RFC то тогда возникает проблема. К примеру у меня тесты показали, что даже даже первые данных посланные через send удачно посылаются, даже если сервер недоступен. Просто данные шлются касперу, а от него теряются. Хотя повторная отправка пакета - уже выдает ошибку отправки, при отключеном сервере.
     
  17. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    2slesh очень странно, в принципе, чисто теоретически, подобный перехват со стороны касперского должен официально подделывать возвращаемые ip-пакеты (адрес отправителя) иначе бы возникли проблемы с работой многих сетевых приложений. насчет connect'а: я так понимаю, что касперский должен выполнять функцию шлюза локальной сети, однако если тут этого не происходит, то видимо он вообще работает с пакетами на высоком уровне))
    если так, то лучше избавиться от подобного ПО:)
    при определенных навыках можешь поработать с сырыми пакетами и посмотреть кто-что посылает. по-хорошему касперский должен быть ТОЧНО ip-прокси.
     
  18. KEZ

    KEZ Ненасытный школьник

    Joined:
    18 May 2005
    Messages:
    1,604
    Likes Received:
    754
    Reputations:
    397
    Касперский не перестаёт нас удивлять. А что же дальше? Инжект во все процессы, с целью посмотреть, что они будут делать? Заражение .ехе файлов на диске с целью закрепить свою защиту в системе?
     
    1 person likes this.
  19. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    Бред. Что куда неперносимо? В пределах разных Windows? С какой радости. Между платформами? Дык виндоус-код и так непереносим в этом смысле..
    Так что уточни, что ты имел в виду.
     
  20. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    >>Бред. Что куда неперносимо?

    >>программах пользователського режима - они там ненужны, кроме того такой С-код непереносим

    с опущенным словом windows очень даже правильно:) про пользовательский режим - ну в общем-то правда, хотя наверняка найдутся примеры чья оптимизированная реализации на ассемблере будет нужна по части глупости компилятора. а C-код и правда не переносим будет, ведь асм-вставки это не стандарт языка.