Задать вопрос
  • Что означают эти строки в коде?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Указатель на указатель. Мы создаём 2D-массив как кучу динамических 1D-. Если 1D-массив — указатель, то массив из таких 1D- — массив из указателей, то есть указатель на указатель.
    2. Указатель простой (создать 1D-массив из указателей, который станет «хребтом» нашего 2D-).
    Ответ написан
    5 комментариев
  • Возможно ли заразить компьютер вирусами ,если подключить жесткий диск через USB SATA/IDE?

    @Mercury13
    Программист на «си с крестами» и не только
    Можно. Если не запускать ничего — то зависит от версии Windows и стоящих на ней апдейтов.
    7+ вроде научилась не запускать ничего в DLL, чтобы подгрузить оттуда иконки, и не делать автозапуска ни для чего, кроме CD.
    В общем, советую для таких винтов обновлённую 7+ и двухпанельный коммандер, а не Проводник. Мало ли какой эксплойт попадётся, чтобы заразить комп через Проводник, а под коммандеры пока такого не пишут — да и путей подобного заражения меньше.
    UPD. И исполняемый файл сложнее принять за каталог на двухпанельном коммандере.
    UPD2. После этого тем же коммандером перетряхните скопированные каталоги, чтобы убедиться, что там законные файлы, а не исполняемые. После чего можно пользоваться даже Проводником — вероятность заразиться мизерна. Если там «левые» документы (DOC, PDF и прочее, что часто эксплойтят) — советую прогнать скопированное на проге типа CureIt.
    Ответ написан
    3 комментария
  • Какие dll добавить в проект Qt, чтобы на удаленном компьютере работал доступ к MySQL?

    @Mercury13
    Программист на «си с крестами» и не только
    Если с MySQL работаем напрямую, то
    plugins\sqldrivers\qsqlmysql.dll
    libmysql.dll
    Ответ написан
    4 комментария
  • Как найти алгоритм?

    @Mercury13
    Программист на «си с крестами» и не только
    Если число 3 задано жёстко, проще всего тройной цикл
    для i = [0..n—2)
      для j = [i+1..n−1)
        для k = [j+1..n)


    Если нежёстко, то получаем такое.

    Изначально массив инициализирован числами 0, 1, 2. Шагом является вот такая сложная операция.
    Добавляем единицу к последнему элементу. Если он больше n−1, то крутим вторую итерацию цикла — добавляем 1 к предпоследнему, если он больше n−2, крутим третью.
    Если цикл прошёл весь массив и так и не закончился — перебор окончен. Иначе идём по массиву вперёд и заполняем хвост числами a[i]+1, a[i]+2…
    Ответ написан
    3 комментария
  • Какие есть книги про связь высшей математики и программирования?

    @Mercury13
    Программист на «си с крестами» и не только
    Дональд Кнут. «Конкретная математика»
    Теория графов, алгебра логики — любая книга
    Ответ написан
  • Как переставить в обратном порядке элементы массива, расположенные между его минимальным и максимальным элементами?

    @Mercury13
    Программист на «си с крестами» и не только
    Найти индекс минимального и максимального.
    Если нужно, поменять местами, чтобы один был меньше другого. ИНДЕКСЫ, не элементы.
    А теперь цикл.
    ++низИндекс
    --верхИндекс
    пока низИндекс < верхИндекс
      поменять a[низИндекс], а[верхИндекс]
      ++низИндекс
      --верхИндекс

    Если индексы беззнаковые, надо проверить как-то, что первое --верхИндекс не приведёт к «антипереполнению». Например, «если верхИндекс > 0»…
    Ответ написан
    Комментировать
  • Структура RGBA матрицы, декодированных чанков PNG-изображения?

    @Mercury13
    Программист на «си с крестами» и не только
    Это так называемый фильтр, для каждой строчки свой. Хорошо описано в англовике.

    В первой строчке фильтр 1 — пиксель слева. Сначала к (0,0,0,0) (все пиксели за пределами картинки имеют цвет (0,0,0,0)) добавляем (0,255,0,255). Для всех остальных пикселей прибавка будет (0,0,0,0).
    Во второй строчке фильтр 2 — пиксель сверху. То есть к пикселю сверху (зелёному) прибавляем (0,0,0,0) — и получаем такой же зелёный пиксель.
    Когда начинается красная полоска, поступаем так же — первая строчка строится по пикселю слева, остальные — по пикселю сверху.
    В оранжевой строчке у нас хитрый фильтр 4 — фильтр Пэта. Для каждого из каналов берём пиксель сверху, слева или сверху-слева — в зависимости от того, что ближе к В + Л − ВЛ. Ну и соответственно прибавляем 0, 100, 0 и 0. Почему система выбрала именно этот фильтр, если фильтр 1 справится не хуже — не знаю.

    Есть пять фильтров.
    0 — как есть.
    1 — прибавить к пикселю левее.
    2 — прибавить к пикселю выше.
    3 — прибавить к их полусумме.
    4 — прибавить к тому пикселю из трёх, что ближе к В + Л − ВЛ. Приоритет на случай «ничьей» — Л > В > ВЛ.

    Всегда работаем с байтами; если глубина <1 байта — значит, один байт захватывает несколько пикселей, а под «пикселем слева» подразумеваем предыдущий байт. Если >1 байта — отступаем на глубину цвета (2, 3 или 4). Полусумма байтов вычисляется в достаточной точности с округлением вниз; «прибавить» — в типе byte (т.е. по модулю 256).

    Главное, что так долго делает программа PNGOUT — это экспериментирует с фильтрами. Подобная оптимизация может серьёзно уменьшить результирующий PNG.
    Ответ написан
    Комментировать
  • Как подключиться к MySQL из Qt?

    @Mercury13
    Программист на «си с крестами» и не только
    Нужны две DLL’ки: libmysql.dll в каталоге с программой, и qsqlmysql.dll в каталоге plugins/sqldrivers.
    От подкаталога plugins можно избавиться, написав в программе

    QApplication a(argc, argv);   // это наша программа, обычно создано автоматом
    a.addLibraryPath(QCoreApplication::applicationDirPath());


    От sqldrivers, насколько мне известно, так нельзя.
    Ответ написан
    Комментировать
  • Почему косинус иногда изменяется на синус?

    @Mercury13
    Программист на «си с крестами» и не только
    Что такое синус и косинус? У нас есть отрезок (0, 0) — (1, 0). Повернём его вокруг первого конца, и координаты второго конца — это cos и sin.

    А теперь нарисуем на плоскости вторую систему координат: у неё ось x' смотрит вниз, а ось y' вправо. Эти две системы координат совпадают началом координат, масштабом (т.е единица в одной будет единицей в другой) и ориентацией (ось y против часовой стрелки от оси x).

    У нас есть отрезок (0,0) — (x, y) длины 1. В системе (x, y) это единичный, повёрнутый на угол α, в системе (x', y') — на угол β=90°+α.

    Поскольку x = y' (мы так нарисовали вторую сетку), то cos α = x = y' = sin β = sin(90° + α).

    P.S. Я попробовал доказать всё это относительно строго, не ссылаясь ни на графики, ни на более сложные утверждения вроде синуса суммы.
    Ответ написан
    Комментировать
  • Какой компонент использовать для работы с Excel в RAD Studio 10.1 Berlin (Delphi)?

    @Mercury13
    Программист на «си с крестами» и не только
    Можно загуглить NativeExcel — он распространялся с исходниками, и вполне найдётся хакнутая версия.
    Есть, правда, несколько не слишком удачных вещей в NativeExcel, и если модуль приглянется, спросите меня, что в нём можно улучшить. Вкратце.
    1. Портирование WideString → UnicodeString.
    2. Портирование Delphi ZLib port → Embarcadero Zlib interface.
    3. Разглючка для Zip’ов LOo.
    4. Разглючка для XML LOo.
    5. Разглючка с цветами XLSX. LOo тут, как ни странно, ни к чему, но однажды попадался такой XLSX.
    6. Разглючка с распознаванием bool (тоже LOo).

    UPD. Сам NativeExcel три года как брошенный, его домен с недавних пор ничей — надеюсь, автор коммерческой библиотеки будет не сильно против.
    Ответ написан
    Комментировать
  • Как QFileDialog вывести диалог открытия файла и получить имя файла в char?

    @Mercury13
    Программист на «си с крестами» и не только
    this — это скрытый параметр каждого не-static-метода, который говорит: для какого объекта он вызван. Если этот объект не QWidget, или функция static, или вообще не метод, то или подставляйте другой QWidget (это значит: кнопка на панели задач та же, что и у этого QWidget), или ставьте NULL (завести новую кнопку на панели задач).

    В вашем случае, разумеется, NULL. Или nullptr, если работаете в Си++11.

    QString *qs = new QString("переведи меня в чары! :)");
    char const* ch = qs->toLocal8Bit().constData();

    Верно придумали, только нет нужды заводить строку в куче операцией new. Строка в Qt и так достаточно «экономная», так что хватит
    QString qs("переведи меня в чары! :)");
    char const* ch = qs.toLocal8Bit().constData();

    Только не забывайте про время жизни этого char const*: он будет жить ровно столько, сколько будет жить конкретное значение строки.
    Ответ написан
    Комментировать
  • Можно ли в C++ узнать позицию с которой начинается подстрока без перебора символов в строке?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Надо проверить pSubStr на NULL. Если оно так — не найдено.
    2. Всё наоборот, pSubStr - str.
    Ответ написан
    Комментировать
  • Запуск консольного приложения при перетаскивании на него файла Drag&Drop C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Перетаскивание просто запускает программу, подставив имя файла как параметр командной строки. Те самые argc и argv, передаваемые в main().

    Кроме того, очень желательно (если у вас Windows) работать в Юникоде (в MinGW настройка компилятора -municode, для других компиляторов разбирайтесь сами). Функция main меняется на _wmain, её параметры на int argc, wchar_t** argv. Хотя не обязательно, если пути не содержат расширенных символов.
    Ответ написан
    1 комментарий
  • Не понимаю почему не работает for правильно?

    @Mercury13
    Программист на «си с крестами» и не только
    arr — исходные строки.
    arr2 — сортированные.
    Исходные строки, скорее всего, не будут совпадать ни с одной из сортированных — потому arr2[i]==sarr[j] во втором фрагменте, скорее всего, не выполнится.
    Я бы поступил таким образом. Сделал бы индексированный список сортированных строк и порядковый массив исходных. Поиск сортированной строки в индексированном списке. Если не обнаружена — сортированную в индексированный, исходную в порядковый.

    Что в JS будет индексированным списком — просто не знаю. Вероятно, можно обойтись массивом, присвоив sortedList[arr2[i]] = 1. Вот только как найти то, есть ли?

    UPD. Можно также воспользоваться хранилищем «ключ-значение»: ключом будет сортированная строка, значением — исходная. iamevg_ так и поступил. Единственная засада (которая хороша или плоха, в зависимости от задачи) — портит порядок строк.
    Ответ написан
    1 комментарий
  • Как написать путь файла с пробелами в функции system в C?

    @Mercury13
    Программист на «си с крестами» и не только
    Заэкранировать кавыки.
    system("gcc \"C:/Folder/My Folder/example.c\"" );

    Точно так же экранируется и обратный слэш, если вдруг потребуется.
    system("gcc \"C:\\Folder\\My Folder\\example.c\"" );


    Экранирование символов — механизм, имеющийся в текстовых языках и протоколах. Он служит, чтобы символы, которые считаются служебными и имеют особое значение, этого значения лишить и объявить «просто символами». Нам нужно двойное экранирование: для ОС (строка с пробелами закавычивается) и для Си (перед кавычкой слэш).
    Ответ написан
    Комментировать
  • Почему не видит функцию из библиотеки в Ардуино?

    @Mercury13
    Программист на «си с крестами» и не только
    Запомни раз и навсегда! Inline не создаёт кода, создаёт факт его использования где-либо.
    С одной стороны, inline-функция при каждом использовании должна быть определена. С другой, она не попадёт в объектный файл сама по себе.
    Потому inline держат в хедерах (кроме хитрых случаев вроде private inline, когда синтаксически нельзя эту функцию вызвать откуда попало, а хедер лучше не засорять).

    Когда доберётесь до шаблонов Си++ — они обладают теми же свойствами. Шаблон не создаёт кода, создаёт расшаблонивание. И тоже в хедерах, кроме хитрых случаев вроде private template или шаблона, у которого есть ровно N предопределённых специализаций и (N+1)-я не нужна.

    А вот полная специализация шаблонной функции типа template<> (в угловых скобках пусто, не inline) создаёт и ей место в CPP.
    Ответ написан
    4 комментария
  • Как сделать и вывести срез строки(String) C/C++?

    @Mercury13
    Программист на «си с крестами» и не только
    1.
    std::cout << text.substr(начало, длина) << std::endl;

    Поскольку перед нами учебный текст, дальше не буду подсказывать. Методом тыка выясни, что будет началом и что длиной.

    2. Ничего, что, если строка не оканчивается точкой, последнее «недопредложение» выведено не будет? Может быть, так и верно, но если задача — разделить текст по tab’ам или запятым, надо после цикла выкинуть то, что осталось.
    Ответ написан
    Комментировать
  • Удаление объекта в C++ без создания его через new, или можно ли удалять объекты взятием адреса (&)?

    @Mercury13
    Программист на «си с крестами» и не только
    > Объект BaseClassObj будет удален только по завершению программы.
    BaseClass baseClassObj;
    Здесь создаётся объект на стеке. Имя — это просто имя объекта. Никаких указателей здесь нет. Как только мы покинем блок (любым образом: штатно выйти, goto, break, выброс аварии — кроме «жёсткого» выхода из программы функциями типа exit), у объекта автоматически исполнится деструктор и прямой вызов не нужен. Блок, то есть подпрограмму BaseClassPresentation.

    BaseClass *BaseClassObjPtr = new BaseClass(2);
    Здесь BaseClassObjPtr это имя указателя (а не указатель на указатель). Объект создаётся в динамической памяти, и его придётся уничтожать вручную. Многое в Си++11 сделали для того, чтобы подобные объекты уничтожались не вручную, а всё теми же автодеструкторами.
    std::unique_ptr<BaseClass> BaseClassObjUp = new BaseClass(2);
    Это уже маленький объект со своим деструктором. А в деструкторе находится delete, и он сработает, как только программа выйдет из своего блока.

    То, что вы хотите, иногда бывает нужно, и я вижу этому две причины.
    1. Объект управляет какими-то сложными и важными ресурсами: большим количеством памяти, файлом, мьютексом… И этот важный ресурс бывает нужно освободить раньше, чем наступит деструктор. Например, у любого файлового потока есть функция close() — она закрывает файл.
    2. У нас сложное и хитрое управление памятью, когда приходится использовать placement new и прямой вызов деструктора. Скажу честно, не использовал никогда. Как и 90% программистов на Си++.
    Ответ написан
    9 комментариев
  • Почему линия не прорисовывается с права?

    @Mercury13
    Программист на «си с крестами» и не только
    UPD2. Запомните уж, рисование на форме надо делать только в OnPaint. Сверни-разверни окно — линия исчезнет Код будет примерно такой.
    TForm1 = class(TForm)
       ...
      private
        MyLabel,MyLabel2:TLabel;  // тут они занулятся автоматически, да и фэншуйнее
        ...
      end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    ...
    MyLabel2.Caption:='3';
    Invalidate;   // Запросить перерисовку
    end;
    
    procedure TForm1.FormPaint(Sender: TObject);  // Событие OnPaint
    begin
      if MyLabel <> nil then
        with Canvas do begin
          Pen.Color:=clRed;
          MoveTo(MyLabel.left,MyLabel.top+(MyLabel.Font.Size+MyLabel.Font.Size div 2) div 2);
          LineTo(MyLabel2.left,MyLabel2.top+(MyLabel2.Font.Size+MyLabel2.Font.Size div 2) div 2);
        end;
    end;

    А для расчёта ваших выносок вариантов несколько.
    1. Нарисовать цифру во внеэкранный буфер и рассчитать размеры реально закрашенной части.
    2. Получить метрику шрифта, по ней прикинуть размеры типичной «заглавной» цифры. Справа убрать пиксель межбуквенного пространства, плюс внести какую-то поправку на «узкую» единичку.

    UPD3. В чём было дело? А в том, что TGraphicControl (к коим относится и TLabel) — это абстракция Delphi, не имеющая аналога в Windows. Он просто берёт тот TWinControl, на котором находится, в случае Transparent рисует фон под собой через WM_PAINT, а затем рисует себя. При этом чёрточка, нарисованная НЕ через OnPaint, стирается.

    UPD4. Полный порядок, рисование через OnPaint — это всё, что надо было. TGraphicControl умный и обходится без лишних перерисовок.

    Ну и наконец «хорошие качества» вашего кода.
    MyLabel := TLabel.Create(Form1);
    MyLabel.Parent := Form1;
    Лучше использовать Self, а не Form1.

    Form1: TForm1;
       p,c,z,j:integer;
    Если бы эти переменные были нужны, лучше было бы их внести в Form1. Если бы…

    function rez(p:integer): integer;
       begin
       c:=p+20;
    
       end;
    Мы тут, очевидно, рассчитываем габариты наших надписей. А нельзя это сделать без побочных эффектов?

    UPD. Это только макет и будет глючить на высоких DPI. Пожалуйста, если хотите такое широкой публике — усложните расчёты.
    Ответ написан
    Комментировать
  • Где располагаются переменные в данном случае (стэк, куча)?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы совершенно правы. Это массив из одного элемента, и при таком расположении он будет в стеке. Со всеми его полями: alloc, size и mp_d. При выходе из функции есть шансы, что он будет затёрт, и так действовать нельзя.

    Кто затрёт? Да кто угодно. Хоть драйвер, пожелавший воспользоваться твоим стеком. Хоть последующий вызов какой-нибудь функции.

    С другой стороны, на то и помечена структура __mpz_struct двумя подчерками, чтобы её не использовали.
    __mpz_struct* foo()
    {
        mpz_t var;
        return (__mpz_struct *)var;
    // C:\TestApps\RetLocal\main.cpp|15|warning: address of local variable 'var' returned [-Wreturn-local-addr]|
    }


    А так работает: всё в куче. Только не забывайте очищать через delete[].
    __mpz_struct* bar()
    {
        __mpz_struct* var = new mpz_t;
        return var;
    }
    Ответ написан
    2 комментария