• Ошибка при чтении из файла в си.Что делать?

    @Mercury13
    Программист на «си с крестами» и не только
    feof возвращает true, когда мы попытались прочитать и не смогли, потому что каретка ударилась в конец файла. А не когда каретка аккуратно припарковалась в конце файла — и уж тем более не когда она отделена от конца пробелами.

    Лучше прочитайте про scanf…
    On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.

    …и посмотрите, как можно переделать условие цикла.
    Ответ написан
    Комментировать
  • Не работает функция. Что сделать?

    @Mercury13
    Программист на «си с крестами» и не только
    Я пока вижу…
    shitf_up(s,Parent);

    Может, ещё вы напутали с порядком кучи, но на таком кусочке кода этого не видно.
    Ответ написан
  • Почему "идентификатор не определён"?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Вытащи p, p1, p2 наружу из if. Читай «область видимости».

    2. Я бы сделал так…
    Work* p = NULL;
    if () {
      p = new Work();
    }
    delete p;

    Работает, потому что NULL можно спокойно уничтожать, и ничего не будет.

    На Си++11 можно также использовать умные указатели.
    std::unique_ptr<Work> p;
    if () {
      p = std::make_unique<Work>();  // простите, это Си++14, на 11 чуть не так.
    }
    Ответ написан
    Комментировать
  • Qt + MinGW + LTO + LLD: как заставить их работать вместе?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    К сожалению, я прошу невозможное. И связано это с архитектурой оптимизации при линковке GCC. Дело в том, что сам LD вызывает оптимизатор, и очень, блин, жаль. Ведь у LLVM другое устройство виртуальной машины, которая делает оптимизацию при линковке.
    Ответ написан
    Комментировать
  • Сhar *dictionary[][] = {}; Зачем тут const?

    @Mercury13
    Программист на «си с крестами» и не только
    Итак. Да, строковый литерал — это const char[], преобразуемое в const char*.
    • Си++03 разрешал (но не одобрял).
    • Си++11 запрещает.
    • Одинаковые строковые литералы компилятор может преобразовать в один адрес, а также хранить в памяти, куда писать нельзя — потому const. И в Си без крестов тоже, только там попытка записи даст простой AV.
    • Const — это т.н. «cv-модификатор» (const-volatile), входит в систему типов Си++, устанавливается свободно, снимается операцией const_cast и означает, что объект нельзя изменять.
    Ответ написан
  • В чем ошибка?Обьясните в чем ошибка?

    @Mercury13
    Программист на «си с крестами» и не только
    Вместо знака умножения плюс стоит.
    beforeTax = tirePrice + numTires;

    .07 — это очень некузявая запись для 0.07, ставки налога. Знаете же, что в США налоги зависят от кучи параметров, и их надо прибавлять вручную.
    Ответ написан
    Комментировать
  • Как изучать С# после С++, и стоит ли вообще?

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

    > С++, С# или все вместе?
    По минимуму желательно освоить оба языка, а вот рисунок кода, инструментарий и прочее — по Си# подтянуть хвосты будет как-то проще.

    > Если С# то учить с нуля?
    Вы уже не ноль, и курс, где вас будут просить решить квадратное уравнение в консоли, может поначалу для вас оказаться тратой времени. Но это уже зависит от ваших знаний — видимо, у вас их не так много и потери будут невелики.

    > Если С++, то что учить дальше кроме ООП?
    Строить живые проекты. Qt (хоть в простейшем виде). SDL (хоть в простейшем виде, раз уж вы геймдевщик). Какой-нибудь игровой движок (Unreal или Godot), но это уже серьёзно.

    > Есть ли что-то что повысит мои шансы попасть в геймдев?
    Трёхмерная математика. Кватернион единичной длины как замена матрице поворота в 3D. Обработка изображений и звука, хоть простейшая. «Programmer’s art» вроде шейдеров и систем частиц. Умение программировать трёхмерные игры на готовом движке хоть в простейшем варианте. Умение написать своими силами (на тонкой обёртке вроде SDL) хотя бы «Элиту».
    Ответ написан
    Комментировать
  • Есть ли в для C++14 map с поддержкой constexpr хэша?

    @Mercury13
    Программист на «си с крестами» и не только
    Нет, разумеется. ООП подразумевает смену состояния объекта, а в константных выражениях смена состояния запрещена. Может, и можно какую-то собственную горбушку придумать, но не знаю, как (даже конструктор — смена состояния).

    Если же задача — посчитать при компиляции хэш для константного элемента, и всё… вот это интересно, но тоже не знаю, как реализовать.
    Ответ написан
  • Задача по олимпиаде?

    @Mercury13
    Программист на «си с крестами» и не только
    ОПРЕДЕЛЕНИЕ. Беспорядок — а) чёрный блин внизу; б) белый блин на чёрном, чёрный на белом.

    ТЕОРЕМА. Переворот исправляет не более одного беспорядка.
    ДОКАЗАТЕЛЬСТВО. Ни в переворачиваемой стопке, ни в оставшейся как был беспорядок, так и остаётся. У нас есть шанс исправить один беспорядок — тот, в который мы залезли лопатой.

    СЛЕДСТВИЕ. Оценка снизу — количество беспорядков.

    ТЕОРЕМА. Эта граница достижима.
    БАЗА ИНДУКЦИИ. У нас 0 беспорядков. Все блины белые — реально нужно 0 ходов.
    ШАГ ИНДУКЦИИ. Доказано, что граница достижима для 0…N−1 беспорядков. Пусть теперь беспорядков N.
    Если количество беспорядков нечётно, вверху будет чёрный блин. Перевернём всю стопку, кроме нижних белых блинов. Теряем одним ходом один беспорядок, а для N−1 граница достижима.
    Если количество беспорядков чётно, вверху белый блин. Поскольку беспорядков не 0, белые блины лежат на чёрных. Перевернём белую группу (теряем один беспорядок) и получаем вверху чёрный блин. Теряем одним ходом один беспорядок, а для N−1 граница достижима.

    АЛГОРИТМ. Подсчитать количество беспорядков в стопке, вывести его. O(N).
    Ответ написан
    Комментировать
  • Какой парсер для математических выражений на Qt посоветуете?

    @Mercury13
    Программист на «си с крестами» и не только
    Egorithm, Отлично, теперь у вас есть файл библиотеки *.a, include-файлы *.h и разделяемая библиотека *.so.
    Задачи, в порядке приоритета.
    1. Заставить прогу компилироваться, для этого надо в проекте прописать доступ к include-файлам *.h.
    2. Заставить прогу линковаться, для этого надо в проекте прописать доступ к *.a (-lmuparser -L$$PWD).
    3. Заставить прогу запускаться, закинув куда надо *.so.
    Ответ написан
    1 комментарий
  • Как ускорить функцию?

    @Mercury13
    Программист на «си с крестами» и не только
    Название, конечно, не по прогерскому фэншую, и вспоминается знаменитый стих столетней давности:
    «We slog, slog, slog, slogging over Africa,
    Boots, boots, boots, boots moving up and down again».

    ПЕРВОЕ. Главный тормоз — дополнение строк нулями, которое квадратичное по скорости.
    for i:=length(s1)+1 to m do
             s1:='0'+s1;
          for i:=length(s)+1 to m do
             s:='0'+s;


    Как решить?
    function add1(const large,small:string):string;
    
    function add(const x, y : string) : string;
    begin
      if length(x) > length(y)
        then add := add1(x, y)
        else add := add1(y, x);
    end;


    Ну и разумеется, сделать, чтобы add1 работала с числами разной длины.

    ВТОРОЕ. У вас, по-видимому, ошибка — 99+1 = 100 не создаст третьего разряда.

    ТРЕТЬЕ. Я не знаю, какой у вас Паскаль, но, вероятно, передача строк по const/var также повысила бы скорость.

    ОФТОП. Если ваша задача не «ввести два числа, сложить и всё», я бы отделил длинное число от его строкового представления, примерно так.
    TLongNum = record
      length : integer;
      data : array [1..1000] of byte;
    end;
    Ответ написан
    1 комментарий
  • Как собрать библиотеку .lib [muParser]?

    @Mercury13
    Программист на «си с крестами» и не только
    Ну, раз уж решил пойти третьим путём (Как подкючить библиотеку [muParser] к Qt? ) — лови проект.

    Как вы видите, в большинстве случаев проект библиотеки строится тривиально: ищем, что надо включить в DEFINES, и затыкаем предупреждения.
    CONFIG -= qt
    
    TEMPLATE = lib
    CONFIG += staticlib
    
    CONFIG += c++11
    
    # The following define makes your compiler emit warnings if you use
    # any Qt feature that has been marked deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS MUPARSER_STATIC
    
    QMAKE_CXXFLAGS += -Wno-deprecated-copy -Wno-cast-function-type
    
    # You can also make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
        src/muParser.cpp \
        src/muParserBase.cpp \
        src/muParserBytecode.cpp \
        src/muParserCallback.cpp \
        src/muParserError.cpp \
        src/muParserInt.cpp \
        src/muParserTest.cpp \
        src/muParserTokenReader.cpp
    
    HEADERS +=
    
    INCLUDEPATH += include


    (ВНИМАНИЕ! Я использую новейший MinGW из MSYS, он на две версии новее, и, возможно, некоторые из предупреждений, которые я заглушил, не нужны.)

    В программе придётся указать
    DEFINES += MUPARSER_STATIC
    
    INCLUDEPATH += ../MuParser/include
    
    LIBS += -L$$PWD -lmuparser


    Если что, в MSYS тоже есть MuParser, хотя он у меня не установлен.
    pacboy sync muparser:i muparser:x
    Ответ написан
    Комментировать
  • Как подкючить библиотеку [muParser] к Qt?

    @Mercury13
    Программист на «си с крестами» и не только
    Тут есть несколько вариантов.
    1. Собрать *.a (любым подходящим методом), закинуть h-файлы в каталог include компилятора, *.a в каталог lib компилятора. В проекте добавить LIBS += -lmuparser.
    2. Закинуть исходный текст библиотеки куда-то в проект, добавить *.cpp (возможно, не все) в этот самый проект. Чтобы удобнее было подключать файлы, прописать INCLUDEPATH += muparser/include
    3. Промежуточный вариант — собрать *.a, закинуть его и *.h куда-то в проект. В проект добавить LIBS += -L$$PWD -lmuparser, INCLUDEPATH += muparser/include
    4. Собрать пакет для Qt. Как — не знаю.

    Когда каким методом пользуюсь.
    1. Только если библиотека есть в дистрибутиве MSYS.
    2. В подавляющем большинстве случаев.
    3. Иногда, особенно если библиотека большая. Ну и если авторы предлагают «официальную» DLL’ку — предварительно собрав, например, через Dependency Walker + DllTool подходящий *.a и заверсионировав его. (В больших проектах не обойтись без линкера LLD, но он, в отличие от LD, не подхватывает *.DLL, надо создавать файл библиотеки.)
    4. Если есть «официальный» пакет. Одна такая библиотека — QWT.
    Ответ написан
    1 комментарий
  • Почему pow возвращает разные значения от одинаковых float значений?

    @Mercury13
    Программист на «си с крестами» и не только
    У меня на свежайшем MinGW (Си, режим C99) не получилось повторить, а погрешность на пределе double — так что подозрение на runtime-библиотеку и управляющее слово сопроцессора (x87 control word).
    Ответ написан
    Комментировать
  • Для чего нужны лендинг - "выиграй приз"?

    @Mercury13
    Программист на «си с крестами» и не только
    Тут принцип прост. Вы получаете 10000 «фантиков». Если делаем ставки фантиками, выигрыш получаем тоже фантиками. Если на счету хоть копейка реальных — ставки фантиками делать нельзя. Единственный способ конвертировать фантики в деньги — продуть реальные деньги.

    Кроме того, если мы выиграли больше, чем вложили, казино берёт комиссию в 20%. Вот такая дрянь.
    Ответ написан
    Комментировать
  • Восходящее преобразование массива производного класса к родительскому?

    @Mercury13
    Программист на «си с крестами» и не только
    Почему нельзя: если мы объявим ящик бананов ящиком фруктов и положим туда яблоко, он перестанет быть ящиком бананов.
    #include <iostream>
    
    class Vocal {  // интерфейс
    public:
        virtual void shout() = 0;
        virtual ~Vocal() = default;
    };
    
    class Dog : public Vocal {
    public:
        virtual void shout() override { std::cout << "Woof!" << std::endl; }
    };
    
    class Unrelated {};
    
    // ВАРИАНТ 1. Метод выкручивания рук.
    
    void shoutAll_v1(Vocal** x, int n)
    {
        for (int i = 0; i < n; ++i)
            x[i]->shout();
    }
    
    template <class T, int N>
    inline void shoutAll_v1(T* (&x)[N]) {
        // Тупая проверка концепции, ждём Си++20
        static_assert (std::is_base_of<Vocal, T>(), "Need array of Vocal");
        T** xx = x;
        shoutAll_v1(reinterpret_cast<Vocal**>(xx), N);
    }
    
    // ВАРИАНТ 2. Виртуальный полиморфизм.
    
    class Choir { // интерфейс
    public:
        virtual int size() const = 0;
        virtual Vocal& at(size_t i) const = 0;
        virtual ~Choir() = default;
    };
    
    void shoutAll_v2(const Choir& x)
    {
        int sz = x.size();
        for (int i = 0; i <sz; ++i)
            x.at(i).shout();
    }
    
    template <class T>
    class VocalArray : public Choir {
    public:
        template <int N>
        VocalArray(T* (&x)[N]) : fData(x), fSize(N) {}
        int size() const override { return fSize; }
        Vocal& at(size_t i) const override { return *fData[i]; }
    private:
        T** const fData;
        int fSize;
    };
    
    int main()
    {
        Dog* sons[3];
        for(auto& x : sons) {
            x = new Dog;
        }
        //Unrelated* unrel[3];
    
        std::cout << "V1" << std::endl;
        shoutAll_v1(sons);
        //shoutAll_v1(unrel);   не компилируется
    
        std::cout << "V2" << std::endl;
        shoutAll_v2(VocalArray<Dog>(sons));
        //shoutAll_v2(VocalArray<Unrelated>(unrel));  не компилируется
    
        return 0;
    }
    Ответ написан
    4 комментария
  • Почему именно такое отношение между классами ( Trip has Airplane)?

    @Mercury13
    Программист на «си с крестами» и не только
    Очевидно, тут имеется в виду жизнь аэропорта в динамике. То есть не заполнить его данными и замолкнуть, а вести вылеты-прилёты, сажать пассажиров в самолёты и т.д.
    Trip — это маршрут, и в одном самолёте могут ехать несколько маршрутов (например, с посадками, или рейс вообще чартерный и несколько турагентств заполняют самолёт).
    Ответ написан
    Комментировать
  • Как пишутся в JavaScript строки сверх BMP?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    Ладно, отпишусь сам — так можно.
    <html>
    <body>
    <script type="text/javascript">
    var s = "☺";
    alert('length  of ' + s + ' is ' + s.length + '.');
    </script>
    </body>
    </html>

    Если эмодзи настоящий, а не та замена, которую получается сделать в Q&A, выведет 2 (внутренне строки — UTF-16).
    Ответ написан
    Комментировать
  • Как называется этот алгоритм сортировки?

    @Mercury13
    Программист на «си с крестами» и не только
    Я это называю «сортировка в три строки». А так это сильно упрощённый алгоритм сортировки выбором.
    Ответ написан
    Комментировать
  • Как найти кратчайший маршрут в графе с дополнительными требованиями к маршруту?

    @Mercury13
    Программист на «си с крестами» и не только
    ВАРИАНТ 1. Расстояние приоритетнее кол-ва заправок.

    Моё решение — в каждой вершине хранить не просто цифру пройденного расстояния, а список: «расстояние/запас топлива/предыдущая вершина». И расстояние, и топливо не убывают.

    С этими списками можно делать такие операции:

    1. Добавить расстояние + израсходовать топливо. Для каждого элемента списка расстояние′ = расстояние + x, топливо′ = топливо − y. Если получается нехватка топлива — что ж, не повезло, этого элемента в списке не будет.
    2. Добавить расстояние + израсходовать топливо + заправиться. Аналогично, но оставляем один элемент — соответствующий наименьшему расстоянию, где хватает топлива. расстояние′ = расстояние + x, топливо′ = полный бак.
    3. Добавить очередной элемент в список. Тогда удаляем из списка те элементы, где расстояние не меньше, а запас топлива не больше.

    После этого на оптимальном маршруте проводим оптимизацию заправок.

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

    Можно также вместо расстояния хранить список «расстояние, кол-во заправок» с лексикографическим порядком на ней и другой операцией «прибавить+заправиться».

    ВАРИАНТ 2. Кол-во заправок приоритетнее расстояния.

    Аналогично первому, только роль расстояния играет пара «кол-во заправок, расстояние» с лексикографическим порядком на ней.
    Ответ написан
    Комментировать