Задать вопрос
  • Динамический массив строк, используя string, в чем проблема?

    @Mercury13
    Программист на «си с крестами» и не только
    i++;
        a[2] = "monday";

    Выход за пределы массива. Массив длины 2 имеет два элемента: [0] и [1].
    Ответ написан
    Комментировать
  • Как "устроены" Emoticons?

    @Mercury13
    Программист на «си с крестами» и не только
    Вопрос: этот JSON мы разбираем или нет?
    Для простоты предположим, что разбираем (ну или транслятор JS разбирает — всё едино). Тогда текст у нас закодирован в UTF-16.
    • Символы 0000…D7FF — они и есть.
    • Символы D800…DBFF — за этим символом должен идти символ из DC00…DFFF, и они образуют суррогатную пару, которая будет одним символом. Подробнее гугли «UTF-16». Если идёт один из этих двух символов без пары — это некорректный UTF-16.
    • И символы E000…FFFF также кодируются как есть.

    Вот эта суррогатная пара, которую ты подкинул, кодируется в символ 1F345, помидор какой-то.

    Функция конвертации суррогатной пары в код символа:
    charCode = 0x10000 + ((leadingCode & 0x3FF) << 10) + (trailingCode & 0x3FF)

    А уж какие коды вам не нужны — копайте таблицы Юникода.

    Более простой способ, который вам может подойти — запретить все суррогатные пары.
    Ответ написан
  • Delphi. Как Узнать номер диска по его букве?

    @Mercury13
    Программист на «си с крестами» и не только
    stackoverflow.com/questions/5501749/how-do-you-get...
    На Паскаль сам переведёшь? Внимание, работает только для фиксированных дисков.
    Ответ написан
    Комментировать
  • Когда имеет значение порядок подключения заголовочных файлов?

    @Mercury13
    Программист на «си с крестами» и не только
    Заголовочные файлы надо писать так, чтобы порядок их подключения был неважен.

    В реализации подключать первым собственный заголовочник — правильная идея; так мы убеждаемся, что в заголовочнике нет недостающих зависимостей.

    Совать #include в пространство имён без хорошего обоснования не стоит.

    По вашему обтекаемому описанию не видно, как устроены ваши заголовки, именованное пространство имён или нет, закрыты ли все скобки в хедерах, и т.д. Но причина ошибки очевидна: из-за пространств имён компилятор не отождествил классы в первом и втором заголовке; предварительное объявление «class A;» осталось неразрешённым. Поэкспериментировав, я выяснил вот что.
    // Не компилируется!
    class A;
    
    namespace XXX {
        std::shared_ptr<A> a;
        class A { public: int x; };
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }


    // Компилируется!
    class A;
    
    namespace XXX {
        class A { public: int x; };
        std::shared_ptr<A> a;
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }

    // Тоже компилируется!
    namespace XXX {
        class A;
    }
    
    namespace XXX {
        std::shared_ptr<A> a;
        class A { public: int x; };
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }

    В первом случае shared_ptr<::A>, который, естественно, не определён (есть XXX::A).
    Во втором — определение наперёд ::A вообще ни на что не сдалось; используется shared_ptr<XXX::A>.
    В третьем примере только один тип, XXX::A.

    Если первым идёт не использование, а make_shared — выходит другая ошибка, не удаётся получить sizeof недоопределённого типа A.
    Ответ написан
    2 комментария
  • Почему WinExec не открывает программу exe Windows 7 (64 Бит) выходит ошибка 2?

    @Mercury13
    Программист на «си с крестами» и не только
    Я креветко. Не работает вот почему: вы решили отказаться от стандартных хедеров Windows и неверно указали соглашение вызова.
    #include <windows.h>
    
    int WINAPI WinExec(string lpCmdLine,int uCmdShow);

    Чему равняется макрос WINAPI — зависит от компилятора.

    Что писать в CreateProcess, если что…
    #include <windows.h>   // убирай этот kernel32.dll
    
    STARTUPINFO si;
    PROCESSINFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.wShowWindow = SW_SHOWDEFAULT;
    
    CreateProcess(NULL, L"c:\\AlertMailer.exe", NULL, NULL, false, 0, NULL, NULL, &si, &pi);
    // Мы не ждём ничего от программы — шшас закроем.
    // Если хотите дождаться — WaitForSingleObject(hProcess, INFINITY);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    );
    Ответ написан
    Комментировать
  • Как освободить память в java?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Самое простое. var = null; Если нужно ещё и мусорщика пустить — ну пусти, System.gc();
    2. Если нужно, чтобы объект не удерживался — WeakReference. Как только объект исчезнет, слабая ссылка перещёлкивается в null. Бывает нужно: 1) если объекты-дети переживают своих владельцев, и при этом потерять владельца — это несмертельно; 2) когда строим какой-нибудь временный список.
    3. Не выдавать безымянный объект наружу, если он переживает создателя. В безымянных объектах есть ссылка на создателя. Выдавать лямбду: если создатель не нужен, ссылки никакой не будет.
    4. Аналогично с внутренними классами — если он переживает создателя, делай его static.
    5. String.intern, если вы работаете с кучей мелких одинаковых строк. Ну или наладить свой кэш :)
    6. Использовать объектные пулы и прочие структуры, снижающие нагрузку на мусорщик.
    7. Разбивая строки на мелкие кусочки, использовать паттерн doSomething(String data, int start, int length), не вытягивая подстроку физически. Использовать StringBuilder.
    Ответ написан
    1 комментарий
  • Код из Delphi в С++!?

    @Mercury13
    Программист на «си с крестами» и не только
    InStr/InSize — немного избыточно по дельфийским меркам и можно преобразоватть в const char* data / size_t length.

    Результат — ну std::string, разумеется. Или std::vector<char>. Что вместо SetLength — читай доку.

    InStr[i + 1] → data[i]. Остальные массивы нумеруются с нуля, всё как и было.

    Inc(j) → ++j.

    Мне кажется, этот код механически переписывался с Си на Паскаль и переписать обратно будет несложно.

    Ещё тут магическое число 16 — догадайся, на что заменять. Кстати, не стоит размазывать по коду две строки, связанные с j.
    Ответ написан
  • Низкочастотный писк монитора LG 29uc88, в чем дело?

    @Mercury13
    Программист на «си с крестами» и не только
    Если монитору несколько лет — тащите в ремонт (или сами перепаивайте, если способны). Отказывают конденсаторы в блоке питания. Стандартная дешёвая поломка, в Киеве 30$ (плюс-минус). Если глюк повторяется через силу — запишите на флэшку ту картинку, где это добро проявляется.
    Если новый — тыкайте сервис-центр носом в проблему. Явно питальник без запаса сделали — и из-за дефектов производства где-то чего-то не хватило по параметрам, и начало пищать.
    Ответ написан
  • Как быть с реестром (пишет в WOW64)?

    @Mercury13
    Программист на «си с крестами» и не только
    Так надо, у W32 и W64 разные места в реестре. И в 90% случаев ничего не надо делать.
    Но иногда всё-таки приходится, например:
    • Есть проги для W32 и W64, и хотелось бы иметь общие настройки.
    • Прога для W32 читает чужие настройки от проги для W64, и наоборот.
    • У вас программа, оперирующая реестром: редактор, чистильщик, архиватор…
    Тогда вот дока от M$, объясняющая всё это.
    https://msdn.microsoft.com/en-us/library/windows/d...

    P.S. «Работает с реестром» — это пишет свои настройки в реестр или действительно оперирует реестром, типа редактора или чистильщика реестра?
    Ответ написан
    2 комментария
  • Стоит ли вынести объявление типов в отдельный файл?

    @Mercury13
    Программист на «си с крестами» и не только
    Стоит!
    Назовите этот хедер как-нибудь defines.h
    Ответ написан
    Комментировать
  • Как взять данные stringstream без копирования?

    @Mercury13
    Программист на «си с крестами» и не только
    stringstream не обязан хранить данные в строке. Так что функция str() просто собирает информацию в строку.

    https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++...

    Судя по исходникам G++, их sstream хранит информацию в длинном буфере, но не в строке. Но и это не обязательно; буферов может быть много.

    Так что, к сожалению, для экономии памяти придётся делать свой велосипед. Правда, как говорит MiiNiPaa, некоторые задачи удастся выполнить и на stringstream’е, воспользовавшись, например, итератором.
    Ответ написан
    Комментировать
  • Как сделать скриншот определенной программы на java?

    @Mercury13
    Программист на «си с крестами» и не только
    colororacle.org
    Вот тут опенсорсный симулятор дальтонизма на Java. Делает снимки всего экрана; как — посмотрите в исходники.

    Сомнительно, что получится на Java кроссплатформенно сделать снимок отдельной программы — больно уж системная штука.

    P.S. Для скриншотов используется класс, именуемый «тестирующий робот» — скриншот-то им можно сделать, а вот как получить прямоугольник чужого окна? По-видимому, только через native-обёртку.

    P.P.S. Оказывается, и native-обёртка есть — JNA. С ней никогда не работал.
    Ответ написан
    Комментировать
  • Как overcockers узнают про правленный hosts?

    @Mercury13
    Программист на «си с крестами» и не только
    Ещё и с ошибкой написали, правильно «правленый».

    А вот так. Из кода страницы.
    var script = document.createElement('script');
    script.onerror = function(){
       // тут пишем сообщение об ошибке
    }
    script.src = "https://c.amazon-adsystem.com/aax2/amzn_ads.js";
    document.body.appendChild(script);

    То есть всё просто: если при вызове рекламы произошла ошибка, выводим сообщение.

    Вот гады ползучие, очередной сайт, написанный полностью на JS и ничего не выводящий, когда такового нет.

    Да ещё и опечатка у вас под стать этому гадству: «overcockers».
    Ответ написан
    Комментировать
  • Для чего нужны замыкания в C++ и как вы их используете?

    @Mercury13
    Программист на «си с крестами» и не только
    Замыкание — это способ передать в callback, из какого контекста он запустился.
    struct Row {
      int data[10];
    };
    struct Table {
      Row rows[10];
    }

    Нам нужно отсортировать таблицу по j-му столбцу. Номер j заранее неизвестен.

    int sortJ;
    
    int myCompare(const void* a,const void* b) {
      int ia = reinterpret_cast<Row*>(a)->data[sortJ];
      int ib = reinterpret_cast<Row*>(b)->data[sortJ];
      if (ia < ib) return -1;
      if (ia == ib) return 0;
      return 1;
    }
    
    int someJ = 5;
    sortJ = someJ;
    qsort(table.rows, 10, sizeof(Row), myCompare);

    Вот эта переменная sortJ — по какому столбцу сортировать — это и есть замыкание. Но, как известно, «избегай незнакомых женщин и глобальных переменных». Поэтому на STL мы делаем функтор (объект-функцию) и эту информацию кидаем в него.

    class MyCompare {
    public:
      MyCompare(int aJ) : j(aJ) {}
      bool operator () (const Row& a, const Row& b) const
        { return (a.data[j] < b.data[j]); }
    private:
      const int j;
    }
    
    int someJ = 5;
    std::sort(table.rows, table.rows + 10, MyCompare(someJ));

    Вот мы и избавились от глобальной переменной, закинув наше замыкание в private-поля объекта.

    Что плохо? Не будем говорить про технические тонкости. С точки зрения красоты и лаконичности кода: код слишком разлапистый. И тут пришёл C++11.
    int someJ = 5;
    std::sort(table.rows, table.rows + 10,
      [someJ](const Row& a, const Row& b) -> bool { return (a.data[someJ] < b.data[someJ]); } );

    Корявовато, но таков синтаксис Си++. Автоматически создаётся объект-функтор, и someJ становится его полем. Вот оно, замыкание — [someJ] — то есть те вещи, которые надо протащить внутрь функтора.

    Из реального проекта. Отбегал поток автоматического поиска нового регистрационного ключа; если что-то получилось — синхронно вызываем лямбду через Qt’шный механизм «сигнал-слот». Чтобы всё было синхронно, нужен объект, живущий в главном потоке (и он в интерфейсе MainControl — управление главной формой — тоже есть). Но тогда придётся вызывать не слот, а лямбду. Этой лямбде нужны два поля: fReregKey (новый ключ защиты от копирования) и fMainControl. Оба они в this, его и замыкаем.
    connect(this, &RenewThread::needUpdate, fMainControl.maincQobj(),
                [this]() {
            drm::createFile(fReregKey);
            fMainControl.maincLayoutOnRegister();
        });


    А теперь посмотрим в WinApi. Первая попавшаяся функция из DirectInput.
    HRESULT EnumObjects(
             LPDIENUMDEVICEOBJECTSCALLBACK lpCallback,
             LPVOID pvRef,
             DWORD dwFlags
    );
    
    BOOL DIEnumDeviceObjectsCallback(
             LPCDIDEVICEOBJECTINSTANCE lpddoi,
             LPVOID pvRef
    );

    Про pvRef говорится: функции EnumObjects он ни на что не нужен; что функция приняла, то и даст в callback. Тоже форма замыкания: можно передать указатель на любые данные, которые нужны callback’у.
    Ответ написан
    4 комментария
  • Почему ошибка в netbeans c++?

    @Mercury13
    Программист на «си с крестами» и не только
    В одном проекте два CPP-файла: int_float.cpp и hello.cpp. В обоих по main’у.
    Я не знаю, как NB объединяет файлы в проект, но если всё, что в каталоге и подкаталогах — значит, не держи где-то в подкаталогах другой проект.

    Второй вариант — очистить временный каталог с .o-файлами; там, возможно, завалялось что-то старое.
    Ответ написан
    Комментировать
  • Как определить число инверсий для перестановки?

    @Mercury13
    Программист на «си с крестами» и не только
    Инверсия — это когда a < b, но стоят они наоборот.
    В пределах блока (например, 1…3n−2) инверсий, разумеется, нет.

    Между первым и вторым блоком.
    • С 2-кой: 4, 7,… То есть n−1 шт.
    • С 5-кой: начиная с 7 — то есть n−2 шт.
    • Итого 0 + 1 + 2 +…+ (n−1) = n(n−1)/2 шт.

    Между первым и третьим, и между вторым и третьим сам инверсии посчитаешь? И чётное оно или нет — тоже, надеюсь, посчитать несложно.
    Ответ написан
    Комментировать
  • Как разнести класс по файлам?

    @Mercury13
    Программист на «си с крестами» и не только
    Принцип прост. В .h можно ставить только то, что не производит кода. Как только в проекте появится второй CPP и задействует этот хедер, код будет произведён дважды, и компоновщик (cl/ld/ilink) будет ругаться, что переменная или функция в двух экземплярах. Что именно не производит кода…
    • Определения макросов. Они в принципе кода не производят.
    • Объявление любого типа. Оно лишь говорит об устройстве этого самого типа; код же производят те, кто этим типом пользуются.
    • Шаблоны. Код производит не сам шаблон, а факт расшаблонивания. Разумеется, шаблон может расшаблониться в двух единицах компиляции, но с этим автоматически бороться научились.
    • inline—  код производит не сам inline, а факт включения. inline бывает как явный ключевым словом, так и неявный — в теле класса.
    • Прототипы и extern — они говорят: код есть, но где-то не здесь.
    • Constexpr C++11. Они подставляют значение.
    • Некоторые const в зависимости от компилятора. Например, на Borland const double производит код, а const int — нет.

    Производят код и в хедерах запрещены.
    • Переменная без extern, даже const.
    • Функция, которая не inline.
    • Полностью специализированный шаблон, в котором не осталось шаблонных параметров (template<>).

    Не производят кода, но и лучше закинуть в CPP.
    • Некоторые скрытые (private) inline и шаблоны, если они не используются из хедера.
    Ответ написан
    3 комментария
  • Как изменить класс компонента?

    @Mercury13
    Программист на «си с крестами» и не только
    Самый простой способ. Открываем DFM (ПКМ на форме, View as Text) и проводим Search-Replace.
    После этого вносим любые изменения в модуль (да хоть пробел добавляем и удаляем), и сохраняем. Автоматика будет спрашивать: заменить? — соглашаемся.

    Я изменял в Unit1.pas - type TPanel на sPanel и в Unit1.dfm TPanel на sPanel.
    Но при открытии пишет, что класс sPanel не найден, хотя в uses прописано sPanel.

    Если модуль называется sPanel, то сам компонент должен немного по-другому. TsPanel?

    UPD. Да, TsPanel, если это он.
    Ответ написан
    Комментировать
  • Как можно реализовать?

    @Mercury13
    Программист на «си с крестами» и не только
    Подсчитать кол-во нулей (единиц, двоек, троек). Если неодинаково — нельзя.
    Иначе — подсчитаем такую матрицу (4×4). Если в 1-й строке на i-м месте 1, а во 2-й 3, прибавляем единицу к a[1, 3].
    a[i, i] не учитываем: они уже на своих местах.
    a[i, j] и a[j, i] взаимокоменсируем: каждая такая парочка даёт min(a[i, j], a[j, i]) перестановок.
    Точно так же пересматриваем все тройки a[i, j], a[j, k] и a[k, i]. Как всегда, взаимокомпенсируем их; каждая такая тройка даёт 2·min(•, •, •) пререстановок.
    Остаётся просуммировать всё, что осталось (кроме диагонали, разумеется), и помножить на 3/4.
    Ответ написан
    Комментировать
  • На чем сейчас разрабатывают игры?

    @Mercury13
    Программист на «си с крестами» и не только
    Почему скриптовой язык идет вместе с компилируемыми? Разные задачи?

    1. Для упрощения внутренней логики игры. Например, программа — монолитное однопоточное приложение, но каждый объект ведёт себя как сопрограмма. Качающийся маятник можно реализовать на состоянии и на сопрограммах…
    // На состоянии
    функ Маятник.ПровестиТакт
      ++кадр;
      если (кадр >= 10)
        кадр = 0;
      УстановитьКадр(кадр);
    
    // На сопрограммах
    функ Маятник.Жизнь
      для i=[0..10)
        УстановитьКадр(i)
        НовыйТакт


    2. Чтобы геймдизайнеры и прочие непрофессионалы (в программировании, естественно, непрофессионалы) могли свободно корректировать код.

    3. Часто игру пишут на готовом движке. А в нём зашит какой-то скриптовый язык — это самый простой способ написать игровой движок, законченный и пригодный к применению программистом куда меньшей квалификации. Так, например, устроен Wintermute Engine (старый, но хорошо известный движок для квестов).

    Читал, что плюса, C#, Lua.

    • C++: язык с давними традициями в геймдеве. Выразительный код (при достаточном профессионализме) плюс контроль за деструкторами — так что не будет просадок FPS из-за мусорщика. Выбор №1, если нужно написать игру с нуля.
    • C#: очень простой в изучении язык общего назначения. Библиотеки для Windows, скорее всего, у пользователя есть изначально. Куча движков, библиотек и фреймворков. Даром, что мусорный — если игра не слишком сложная, просадок FPS не будет (хотя последнего босса Hyper Light Drifter я долго громил — в критические моменты игра тормозила).
    • Lua: наиболее известный из скриптовых языков, которые можно реально присоединять к Си-программе, и скрипт будет вызывать функции, написанные на обычном компилируемом языке.
    Ответ написан
    Комментировать