• Как мне записать конечный результат деления?

    @Mercury13
    Программист на «си с крестами» и не только
    В зависимости от того, какого происхождения числа, можно поступать так.

    1. Работать с погрешностью. Например.
    q := X1 / X2;
    if abs(q - Round(q)) < 1e-5 then ...

    Я в основном сейчас на «си с крестами» и непривычка не брать условие в скобки :)

    2. Работать в рациональных числах.
    type
      TRatio = record
        Num, Den : integer;
      end;

    Думаю, сами сможете написать операции ±×/ и, если надо, сокращение.

    3. Работать в фиксированной запятой — например, перевести рубли в копейки.
    var
      X1 : integer = 100;
      X2 : integer = 20;
    
    if X1 mod X2 = 0 then ...


    4. Работать в десятичной длинной арифметике. Это уже совсем «большая пушка», и может быть что-то типа
    type
      TDecFloat = record
        mantissa : uint64;  // например, от 1e17 до 1e18
        order : integer;
        sign : boolean;
      end;

    Примерно так можно сделать калькулятор, работающий в десятичной системе и переводящий в extended и обратно, если, например, нужно взять синус. Погрешность перевода для трансцендентных функций, разумеется, будет, зато 0,2 в такой системе — это точное 0,2, и это важно для калькуляторов: он вычислит в точности то, что человек вычислит ручкой на бумаге.

    ВНИМАНИЕ! Для методов 2,3,4 придётся переработать всю цепочку, через которую появляются 1 и 0,2. В float/double нет числа 0,2, и точка.
    Ответ написан
  • Можете помочь найти ошибку в коде?

    @Mercury13
    Программист на «си с крестами» и не только
    1. 1/2 = 0, надо писать 1.0/2.0 или просто 0.5.
    2. В printf немного другие правила, чем в scanf, и надо
    printf_s("max = %f\n", max);
    Ответ написан
    Комментировать
  • Может ли код(определение) в заголовочных файлах быть вынесен в shared library?

    @Mercury13
    Программист на «си с крестами» и не только
    Надо сделать CPP-файл, в которые перенести как можно больше кода из программы. И код производят:
    • Static- и глобальные переменные.
    • Нешаблонные, не-inline-функции.
    • Не-inline, полностью расшаблоненные функции template<>.
    • Не-extern объявление шаблона типа template class std::vector<int>.
    Мало того, эти четыре вещи ошибочно держать в хедерах — но этого, как ни странно, в нашей библиотеке и нет, ведь она полностью полагается на шаблоны. Но есть пара резервов.

    1. Функция в теле класса автоматически становится inline, и, я бы сказал, что-нибудь типа AsynchronousReader::init было бы ошибкой держать inline’ом. По-хорошему, его надо в CPP. Но это довольно небольшая часть кода.
    2. Можно также наиболее распространённые версии классов/функций залить в SO. Для этого их надо вынести из тел классов и поступить примерно так.
    // H
    template <int x>
    void foo () { std::cout << x << std::endl; }
    
    extern template void foo<2>();
    
    // CPP
    template void foo<2>();
    Ответ написан
    Комментировать
  • Qt+QMake: как задать настройки компиляции для конкретного файла?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    И снова приходится отвечать самому.

    #pragma GCC optimize("O1")
    #pragma GCC optimize("no-lto")
    Ответ написан
    Комментировать
  • Как вывести результат этой функции?

    @Mercury13
    Программист на «си с крестами» и не только
    EOF — это маркер «файл закончился, данных больше нет». Обычно getchar даёт цифры от 0 до 255, а EOF — значение вне этих пределов (вообще-то −1).
    Консоль никогда не кончается, но конец файла можно сделать, нажав Ctrl+Z.

    Правильно писать int c; int r[]; int s[]; или int c, r[], s[];. Но в любом случае перед нами статический массив и ему надо дать размер.

    Иногда бывают массивы без размера — когда мы не заводим память, а просто говорим: «перед нами какой-то отрезок памяти». Например.
    void doSmth(int a[]) {}  // передаём в функцию отрезок памяти неизвестной длины
    int x[5];
    doSmth(x);
    
    extern int b[];  // компилятор рассматривает b как отрезок памяти неизвестной длины.
    int b[5];    // …и только линкер подставит на место b настоящий массив

    В Java массивы не статические и им размер дают тогда, когда выделяют им память.
    int[] x = new int[5];    // повторяю, это не Си++, а Java!

    Но это уже офтоп.
    Ответ написан
    8 комментариев
  • Как добавить перенос на новую строку?

    @Mercury13
    Программист на «си с крестами» и не только
    Я добавлю к Александр .
    В отличие от Си, где условие цикла каждый раз вычисляется полностью, в Паскале вторая граница for вычисляется один раз и запоминается.
    Потому длина строки меняется, а мы ходим до самой первой.

    К тому же вы неправильно решаете задачу. Никакой там не одной строкой. В ответе сервера концы строк LF, а надо CR+LF. Вот функция (крайне неоптимизированная), которая приводит концы строк к единому виду независимо от того, какие там стоят.
    function NormalizeEol(const s : string) : string;
    begin
      Result := StringReplace(s, #13#10, #10, [rfReplaceAll]);
      Result := StringReplace(Result, #13, #10, [rfReplaceAll]);
      Result := StringReplace(Result, #10, #13#10, [rfReplaceAll]);
    end;
    Ответ написан
    Комментировать
  • Можете объяснить логику Python умножения чисел?

    @Mercury13
    Программист на «си с крестами» и не только
    Так устроены float и double: они двоичные, и в них точно представляются только числа вида k·2−n. 0,4 не таково, у него в знаменателе пятёрка.
    Для большинства инженерных расчётов и игр это нормально. А вот если надо так, как подсчитал бы бухгалтер на бумаге (например, пишете калькулятор) — работайте с десятичным длинным.

    UPD. Наконец нашёл ту статью, какую хотел.
    www.delphikingdom.com/asp/viewitem.asp?catalogid=1217
    www.delphikingdom.com/asp/viewitem.asp?catalogid=374
    Ответ написан
    Комментировать
  • Почему в Си работают локальные функции?

    @Mercury13
    Программист на «си с крестами» и не только
    Очевидно, расширение GNU.
    MinGW, даже с ключом -std=c99, OK.

    Причём работает только в режиме Си. MinGW/Cи++
    C:\TestApps\NestedFunction3\main.cpp|7|error: a function-definition is not allowed here before '{' token|

    Embarcaredo x86 (Borland):
    [bcc32 Error] File1.c(7): E2141 Declaration syntax error

    Embarcadero x64 (clang):
    [bcc64 Error] File1.c(6): expected ';' at end of declaration
    Ответ написан
    1 комментарий
  • Какой использовать алгоритм?

    @Mercury13
    Программист на «си с крестами» и не только
    Очень важный вопрос. Может ли содержимое папки попасться раньше, чем сама папка? Для простоты считаем, что нет, и что вы нашли библиотеку для JSON.
    Нужны два объекта: дерево (самодельный) и словарь ID (map: id → развилка дерева).
    Для каждого элемента…
    1. По parent id через словарь находим, куда его впихнуть. Если не нашли — вывести ошибку.
    2. Если folder: создать развилку, присвоить ID, вписать её в словарь ID.
    3. Если не folder: создать лист, присвоить ID и вписать в словарь ID (если надо по какой-то другой причине).
    Я плохо знаю Си с диезом, так что поправляйте меня.
    class Node {
      List<Node> children;
      List<Leaf> leaves;
    }
    
    class Leaf {
      // в нём может быть что угодно
    }
    
    class Tree {
      Node root;
    }
    
    Tree tree;
    Dictionary<string, Node> idDic;  // считается, что словарь нужен только на разбор JSON,
       // и он временный
    Ответ написан
    Комментировать
  • Как посчитать количество совпадающих символов в обоих строках?

    @Mercury13
    Программист на «си с крестами» и не только
    3 тоже есть, так что правильный ответ 3. Ошибка тройная.
    for(size_t z = 0; z < b.length(); z++){
            if(a.find(b[z]) != std::string::npos){

    1. Индексы строк в STL беззнаковые, и компилятор может ругаться на сравнение знакового целого и беззнакового.
    2. На что тут 4, если есть s.length()
    3. Знак «не найдено» — std::string::npos.
    Ответ написан
    3 комментария
  • C++ QT почему не работает запрос к sql Lite DB?

    @Mercury13
    Программист на «си с крестами» и не только
    Нет, ваше решение неуниверсально и ваша ошибка — не заэкранировать идентификатор E-mail.
    Попробуйте [E-mail].
    (Часто используется экранирование `E-mail`, но в SqLite оно не катит, это специфика MySQL.)
    Ответ написан
    Комментировать
  • Простой пример одного и того же кода в ООП, функциональном и процедурном стиле?

    @Mercury13
    Программист на «си с крестами» и не только
    Просуммировать элементы std::vector<int>. Си++.

    Процедурный
    int sum = 0;
    for (int v : vec)
      sum += v;
    std::cout << sum << std::endl;


    ООП.
    class Accumulator
    {
    public:
      void feed(int value) { fSum += value; }
      int sum() const { return fSum; }
    private:
      int fSum = 0;
    }
    
    Accumulator acc;
    for (int v : vec)
      acc.feed(vec);
    std::cout << acc.sum() << std::endl;


    Функциональный (правда, слегка настоянный на шаблонах)
    int sum = std::accumulate(vec.begin(), vec.end(), 0);
    std::cout << sum << std::endl;


    UPD. Третий такой маленький, потому что в стандартной библиотеке нашли подходящую функцию.

    UPD2. А теперь представьте себе, что нужно вычислять не сумму, а что-то сложное — например, среднее и квадратичное отклонение. В процедурном придётся или раскрывать сложные формулы, или налаживать какие-то обобщения. Объектное меняется на раз-два. В функциональном придётся менять функцию-шаблон, работающую над итератором.
    Ответ написан
    Комментировать
  • Почему в текст запроса вставляется exec?

    @Mercury13
    Программист на «си с крестами» и не только
    Это связано с версией клиента MS SQL. Несколько вариантов переписать триггер.
    ALTER TABLE table_name DISABLE TRIGGER tr_name
    ALTER  TRIGGER trigger_name  DISABLE
    Ответ написан
    Комментировать
  • Для чего существует short?

    @Mercury13
    Программист на «си с крестами» и не только
    Си рассчитан на всякие машины. У некоторых байт более 8 бит — то есть к 8-битному октету обращаются как к битовой маске. Какие-то 16-битные, какие-то 32-битные.
    По всей видимости, int когда-то был «системным размером», коим сейчас является size_t.
    А char, short, long, long long — это 1/2/4/8 байт.
    Ваши знания «int равен 2 байтам» устарели — на современных машинах int равен 4 байтам.
    printf("%d\n", (int)(sizeof(int) * 8));
    Ответ написан
    9 комментариев
  • MinGW: что за префикс _imp__ и как избавиться от него?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    Опять приходится отвечать самому. У меня три ошибки.
    Раз.
    //#define ZIP_EXTERN __declspec(dllimport)
    #define ZIP_EXTERN
    Очевидно, libzip рассчитана только на компиляцию в DLL, и точка.

    Два. -lz. Ну, это понятно, и эта библиотека в нашем дистрибутиве MinGW есть.

    Три — не до конца дописал Юникод.
    Ответ написан
    Комментировать
  • Как возможна замена Юникодов?

    @Mercury13
    Программист на «си с крестами» и не только
    Очевидно, транслятор языка программирования довольно либерально относится к тому, «что такое идентификатор». И все эти смайлики и говняшки (ыгы, эмодзи-говняшка не так давно тоже появилась) также считаются буквами. Однако тут есть маленькая ловушка: если один и тот же символ составить разными способами — например, «и+кратка» против монолитного «й» — это будут разные идентификаторы.

    UPD. Посмотрел, как это делается в Java. Годятся любые символы, являющиеся буквами в Юникоде. Как минимум по спецификации Гослинга.
    Ответ написан
    4 комментария
  • Как безопасно загрузить SVG на сайт?

    @Mercury13
    Программист на «си с крестами» и не только
    К сожалению, в этом плане мы отданы на милость производителю браузера — как, впрочем, и в PNG, и в JPG. С одной стороны, они стараются избавиться от ошибок — например, как-то были скрипты в SVG (вроде в классической Опере). Исправили.
    С другой — векторная графика на порядок сложнее точечной, и всё не предусмотришь.

    Я бы поделил это на три части.
    1. Типичные для XML риски.
    • Entity-бомбы.
    • Проблемы с DTD, особенно отсылки на локальные файлы и файлы-устройства.
    • Сильно вложенные тэги, призванные пробить врагу стек. С этим надо быть предельно осторожным, чтобы не пробить стек себе :)

    2. Известные эксплойты, связанные с SVG.
    • Скрипты (и кто их вообще исполняет сейчас в SVG — но интернет говорит, что немало таких зловредов).
    UPD. Исполняют, но при определённых условиях, и тэг IMG или фон через CSS теоретически безопасны.

    3. SVG, которые не могут работать.
    • Ссылка на внешний растровый файл.
    Ответ написан
    Комментировать
  • Как задать паролем перемешивание 32 элементов?

    @Mercury13
    Программист на «си с крестами» и не только
    Если не нужна криптостойкость, то…
    1. Преобразовать (однозначно) в очень длинное число.
    2. Получаем такие части этого числа.
    • Остаток от деления на 32
    • Неполное частное на 32, затем остаток на 31
    • Неполное частное на 32·31, затем остаток на 30
    • Неполное частное на 32·31·30, затем остаток на 29…
    На словах страшно, алгоритм простейший.
    3. Из 31 числа — первое от 0 до 31, второе от 0 до 30, последнее 0 или 1 — легко получить перестановку.

    Если криптостойкость всё же нужна — придётся пароль «посолить» до достаточной длины и зашифровать чем-то.
    Ответ написан
    1 комментарий
  • Какие предметы в ВУЗе выбрать для обучения программированию?

    @Mercury13
    Программист на «си с крестами» и не только
    Не зря студенты говорят «пойти на Иванова» — от личности препода зависит больше, чем от названия. Препод дятел — бросай нахрен.

    • Язык Python — с ограничением в 5 лекций ходить на язык не стоит, греби своими руками.
    • Структуры и алгоритмы компьютерной обработки данных — стоит, хотя зависит от программистской подготовки и может быть излишне просто.
    • Программирование на языке Java — с ограничением в 5 лекций ходить на язык не стоит, греби своими руками.
    • Язык C++ — с ограничением в 5 лекций ходить на язык не стоит, греби своими руками.
    • Рекурсивно-логическое программирование — очередная хитрая концепция программирования, фтопку
    • Системы искусственного интеллекта и экспертные системы — 70%, что пользование чужим софтом, тогда нет; 30%, что теория, тогда, возможно, да.
    • Функциональное программирование — интересная штука, но сильно зависит от препода.
    • Математическая логика — зависит от математической подготовки.
    • Основы параллельного программирования — интересная штука.
    • Объектно-ориентированное программирование (на примере C++) — фтопку
    • Компьютерная графика — в этом курсе может быть что угодно от хорошего до дряни. Допустим, на самом шаровом (!) потоке у нас в Киеве под этим скрывались страшнейшие задачи по вычислительной геометрии, половине группы я их решал, как бывший олимпиадчик.
    • Разработка ПО для мобильных систем (Objective C) — может потребоваться, но это инфраструктура Apple.
    • Технология разработки программного обеспечения — может быть что угодно, но в целом стоит разведать.

    • Системы реального времени — может быть что угодно. Пользование ПО — фтопку, что-то из теории и программирования — надо.
    • Операционные системы и компьютерные сети — с твоими интересами можно и забить.
    • Проектирование и администрирование информационных систем — может быть что угодно.
    • Визуальное программирование — фтопку
    • Операционная система Linux — фтопку
    • Операционная система Unix — фтопку

    • Теория автоматов, языков и трансляторов — очень хорошая штука, но с твоими интересами можно и забить.
    • Основы криптографии — аналогично.
    • Дискретная математика для программистов — зависит от математической подготовки
    • Дискретная математика — аналогично.
    • Алгоритмы теории графов — прогеру никогда не помешает.
    • Введение в Маткад и Матлаб — с твоими интересами забей.
    Ответ написан
  • Зачем gcc просит подключить stdlib.h?

    @Mercury13
    Программист на «си с крестами» и не только
    Раз у вас stdlib.h закомментирован, вы, наверно, знаете, откуда malloc взялся. Попробуем раскрутить ошибки.

    note: include ‘ stdlib.h ’ or provide a declaration of ‘malloc’
    Компилятор, очевидно, знает, где этот malloc завалялся…

    warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
    …но неявно объявляет функцию.

    warning: incompatible implicit declaration of built-in function ‘malloc’
    Неявное определение int* malloc(int). Реальное void* malloc(size_t). Преобразовать (int*)malloc надо было.

    Почему всё-таки запустилось? А потому, что на целевой машине size_t = unsigned int, а размеры указателей совпадают практически всегда. После того, как функция неявно объявилась, линкер подцепил на её место стандартную, и соглашения вызова совпали.
    Ответ написан
    1 комментарий