Задать вопрос
Ответы пользователя по тегу C++
  • Почему CharToOemW преобразует не все символы?

    @Mercury13
    Программист на «си с крестами» и не только
    А такое будет работать?

    inline const char* wtc(const WCHAR *from)
    {
      //Используется буффер -- статическая переменная
      static char buf[1024] = { 0 };
      size_t nChars = std::min<size_t>(wcslen(from), 1024 - 1);
      if (!CharToOemBuffW(from, buf, nChars)) {
        cout << GetLastError();
        exit(-1);
      }
      buf[nChars] = 0;
      return buf;
    }
    Ответ написан
  • Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Например, int занимает 4 байта

    По современному консенсусу, да. Но иногда может занимать 2 байта (меньше — вроде нет).

    В случае с double можно задать абсолютно любое число

    double x = 1e500;
    Ответ статического анализатора Clang: magnitude of floating-point constant is too large for type 'double'; maximum is 1.79…E+308

    На число 1.23456789012345678901234 не жалуется, но учите матчасть — относительная точность double 52 двоичных цифры (исключая головную единицу), или около 16 десятичных.

    для чего в конце приписывают 'f' ,когда пользуются типом данных float?

    Чтобы расчёт float x; return x + 12.34f вёлся в менее точном типе float, а не double.
    А вот коду float x = 12.34; это совершенно не нужно, компилятор и сам поймёт, что преобразование double → float можно сделать при компиляции.

    Сколько бит(байт) занимают типы данных с плавающей запятой в C++?

    Зависит от машины, но по выработанному консенсусу — float 4, double 8.
    Нестандартная (присущая x86) реализация long double имеет 10 значащих байтов, но 12 или 16 вместе с выравниванием.
    Ответ написан
    Комментировать
  • Что означают данные строки?

    @Mercury13
    Программист на «си с крестами» и не только
    Перед нами вариативный шаблон Си++11.

    Функция printTypes действует так. Для первого параметра подбираем подходящую перегрузку функции NameOf. Второй и далее — снова подставляем в функцию printTypes.

    types... t — это любое количество параметров любых типов. Которые, в свою очередь, можно рекурсивно подставить в шаблон printTypes.

    DEF_TYPENAME(float) — это использование препроцессора Си++ (никакой уже не 11), чтобы объявить несколько стандартных специализаций одного шаблона.
    Ответ написан
  • Как правильно называть переменные в заголовке функции (параметры или аргументы)?

    @Mercury13
    Программист на «си с крестами» и не только
    Одна сатана. В терминологии одних языков принято parameter, других argument.
    Ответ написан
    Комментировать
  • Почему нельзя передавать лямбду как аргумент шаблона?

    @Mercury13
    Программист на «си с крестами» и не только
    #include <iostream>
    
    template <class Body>
    void call(const Body& body) {
        body();
    };
    
    void test() {
      std::cout << "function" << std::endl;
    }
    
    int main() {
      call(test);
      call([]() {
        std::cout << "lambda" << std::endl;
      });
      return 0;
    }


    Дело в том, что лямбда — это объект неизвестного класса с операцией (). И только так её вызывают.
    Ответ написан
    1 комментарий
  • Правилен ли такой подход к разбиению C приложения на модули?

    @Mercury13
    Программист на «си с крестами» и не только
    Смотря в чём задача.
    Возможно, нет никаких проблем.
    Возможно, удастся вытащить общую функциональность в defines.h.
    Возможно, удастся каким-то образом разорвать порочный круг. Например, в ООП это можно делать через интерфейс.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы CodeBlocks не ставил знаки?

    @Mercury13
    Программист на «си с крестами» и не только
    Settings → Editor → General Settings (стоит по умолчанию) → Editor Settings (стоит по умолчанию) → Indent Options → Brace completion

    5cfa263e49d5b731760499.png
    Ответ написан
    Комментировать
  • Исключение. Что это значит?

    @Mercury13
    Программист на «си с крестами» и не только
    Это значит: вы «сломали» память. Как правило, разыменованием «висячего» указателя или вылетом за пределы массива.
    Ответ написан
    Комментировать
  • Как вычислить интеграл с помощью формулы Симпсона?

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

    Первое, что нужно сделать,— вынести расчёт интеграла в отдельную функцию. Помимо прочего, она должна принимать параметром n — количество точек разбиения. И проверьте, разумеется, работоспособность.

    Затем поднимаемся на более высокий уровень — налаживаем алгоритм выдерживания точности. Я бы написал так.
    n := 10
    yНовое := расчёт(n)
    повтор
      n := n·2
      yСтарое := yНовое
      yНовое := расчёт(n)
    пока |yСтарое - yНовое| > эпсилон
    вывести/вернуть yНовое

    Сможешь перевести на Си?
    Ответ написан
    Комментировать
  • Почему Segmentation fault?

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

    @Mercury13
    Программист на «си с крестами» и не только
    Нужен или массив с запасом (например, на 6 мест), или динамический (например, std::vector).
    Си++ — язык достаточно низкого уровня, и сам программист видит, где там память динамически выделяется, а где выделена заранее.
    Ответ написан
    2 комментария
  • Объясните разбор файла mainwindow.h в QT по шагам?

    @Mercury13
    Программист на «си с крестами» и не только
    // Защита от повторного включения
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    // Пара include’ов
    #include <QWidget>
    #include <QMainWindow>
    
    // Определение UI-класса наперёд, чтобы визуальное редактирование не приводило
    // к крупным перекомпиляциям
    namespace Ui {
    class MainWindow;
    }
    
    // Собственно класс формы
    class MainWindow : public QMainWindow
    {
        // Макрос, который добавляет файл в компиляцию MOC’ом,
        // а также реализует пару функций
        Q_OBJECT
    
    public:
        // Конструктор-деструктор.
        // Форма семантически не эквивалентна parent’у,
        // потому конструктор explicit
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    // Слоты — фишка Qt, которая обрабатывается MOC’ом
    private slots:
    
    
    private:
        // Указатель на UI (для него в Qt есть ещё одна программа, UIC)
        Ui::MainWindow *ui;
    };
    
    // Защита от повторного включения
    #endif // MAINWINDOW_H


    Что ещё написать?

    Определение класса наперёд не мешает писать указатели и ссылки.

    Конструктор explicit запрещает неявное преобразование. Explicit имеет смысл, если возможен вызов конструктора с одним параметром. Правило таково: ставь explicit, если твой объект по смыслу не эквивалентен единственному параметру конструктора. Например, Ratio(int x);, но explicit Array(int x);: при построении рационального числа из целого будет полный эквивалент, но при построении массива — нет.
    Ответ написан
    Комментировать
  • Почему пробел заменяется на W?

    @Mercury13
    Программист на «си с крестами» и не только
    Пробел не isupper.

    Расчёт тут идёт в знаковом типе, потому *i + key - 97 < 0

    Существует два метода деления с остатком, в x86 встроен тот, где знак остатка равняется знаку делимого (а неполное частное — результат округления к нулю). Именно его впоследствии кодифицировали в Си99. Значит, (*i + key - 97) % 26 < 0

    Это значит, что результат преобразования будет меньше 97 = 'a'. Например, 'W'.

    Ах да. В Си можно написать (*i + key - 'a') % 26 + 'a'.
    Ответ написан
    Комментировать
  • Как быстро выбирать подстроку у строки?

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

    @Mercury13
    Программист на «си с крестами» и не только
    typedef struct ttime {
    Си, на ++ не нужен typedef.
    И используй наконец тэги для кода.

    int hours; int minute; int sec;
    Странное именование, обычно пишут hour.

    struct date {
    ttime time;

    которая в свою очередь входит в состав структуры Date.
    Странно, ведь это не дата, а скорее Clock — часы.

    Методы позволяют изменять текущее время

    Ну и где тут измерение?

    Моя архитектура.
    1. Время. Получение времени из системы, сравнение, вывод в консоль.
    2. Часы. Хранят последнее время. Команда «tick» — получить время, сравнить с последним, при неравенстве — сохранить новое и вывести его в консоль.
    3. Внешний цикл (может быть как в часах, так и снаружи). Часы тикают, делают небольшую задержку и проверяют на нажатие клавиши.
    Пять объектов никак не будет, да и Date нужно только в том случае, если вы реально работаете с датой. Я бы, чтобы докинуть количество объектов до нужного, сделал бы дату (date), время (time) и дату-время (stamp).

    Для турнира единоборств (для простоты — без весовых категорий).
    • Fighter: имя, всякая информация про него вроде города, клуба и титулов.
    • Stub: указатель на Fight + enum (Winner/Loser) — откуда берётся участник. Указателя на Fight нет — тогда TBD (то есть не определился).
    • Participant: указатель на Fighter + структура stub.
    • Fight: номер, два Participant, дата/время, кто победил (0/1), причина победы (ещё не проводился, KO, TKO, по очкам, неявка…)
    • Tournament: содержит список боёв и таблицу результатов.

    Можно также разорвать кольцо зависимостей, наладив интерфейс FightInfo, сделав в Stub FightInfo*, а не Fight*, и чтобы Fight реализовывал FightInfo.
    Ответ написан
  • Как разобраться, что происходит в этом заголовочном файле?

    @Mercury13
    Программист на «си с крестами» и не только
    Учи понятие «единица компиляции». Тут, к сожалению, есть и вещи, которые должны быть в CPP-файле, и вещи, которые должны быть в H-файле.

    #pragma pack(1)
    Структуры данных нам нужны «один в один», без байтов заполнения.

    struct FileHeader 
    struct MAPINFO

    Формат BMP. Не забывай, что формат BMP записывается с нижней строки!

    Функция Open читает картинку «один в один», Save пишет «один в один», GetMapInfo и GetFH выдают какие-то заголовки нашего BMP.

    Остаётся GetMap(), который, по идее, должен выдавать матрицу цветов, но реально действует только для 32-битного BMP и никак не инкапсулирует ни ширину-высоту матрицы, ни тот факт, что формат BMP пишется с нижней строки.

    За этот код — тройка с минусом.

    А теперь чего ваш код НЕ поддерживает, но, по идее, должен, чтобы выполнить вашу задачу.
    1. Создание BMP нужного размера с нуля, а не загрузка из файла.
    2. Инкапсулировать матрицу пикселей. Желательно так, чтобы был быстрый доступ к строкам как к буферам в памяти, для простоты переноса информации из старого BMP в новый, на 30×30 пикселей больший.
    3. Если вы ограниченно поддерживаете формат BMP — вылетать с ошибкой, если версия неподдерживаемая (например, не то количество цветов).

    Задача именно своими силами наладить поддержку BMP? А то в Builder’е есть TBitmap.
    Ответ написан
    6 комментариев
  • Как организовать указатели в си?

    @Mercury13
    Программист на «си с крестами» и не только
    Дело тут в очерёдности операций.
    Сначала вычисляются правые одноместные, потом левые.

    Надо (**h)[1] = 0;.
    Ответ написан
    Комментировать
  • Qt checkbox this combobox?

    @Mercury13
    Программист на «си с крестами» и не только
    Через сигналы-слоты способа не вижу.
    Унаследоваться от QStandardItemModel, присосаться на setModelData.
    А ещё лучше унаследоваться от QAbstractTableModel и переопределить все эти data(), flags()…
    Ответ написан
    Комментировать
  • Передача ссылки на экземпляр объекта из конструктора?

    @Mercury13
    Программист на «си с крестами» и не только
    Дело у вас вот в чём. Файл Part_Of_Word.h напоминает единицу компиляции (*.cpp), но имеет расширение заголовочного файла (*.h). После того, как вы удалили все его include’ы, эти функции просто перестали компилироваться.

    А до этого, вангую, у вас было два include’а — а значит, две копии одной функции из разных единиц компиляции. Тоже ошибка линкера.

    Решение: переименовать этот файл в cpp.
    Ответ написан
    Комментировать
  • Как понять: массив указателей на объекты классов?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы тут просто не знаете, что такое указатель. А это, грубо говоря, адрес другого объекта в памяти.
    Операция new заводит объект в «куче», вызывает конструктор (если таковой есть) и возвращает указатель на него.
    И мы можем разыменовать указатель: пройти на тот объект, куда он указывает, и сделать с ним что-то. В Си разыменование — операция ->.

    Указатели не на абстрактный класс, а на вполне конкретный, a.

    a(int) — не конструктор копирования, а просто конструктор, делающий объект из int’а. Конструктор копирования всегда a(const a&). Отличается от других конструкторов тем, что автоматика его по возможности строит, но не всегда верно. В вашем объекте с одним полем int вполне себе построит без всяких проблем.

    Обычный указатель Си никоим образом не знает, есть объект или нет, и кто этот объект уничтожает. У вас это приводит к ошибке «утечка памяти»: теряется указатель на объект, и уже никак его не освободишь. Из-за небольшого размера и линейного характера программы неопасно, но всё-таки.
    Ответ написан
    Комментировать