Задать вопрос
Ответы пользователя по тегу C++
  • Как найти принадлежность точки к такому графику?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Разбейте область на простые фигуры (квадраты, окружности, полуплоскости) и опишите логически. Вроде точка в области, если она в фигуре А, но не фигуре Б; или в фигурах В и Г, или в фигурах Д и Е.

    Далее перевести это в код - это один if с кучей условий объедененных логическими или (||) или логическими И (&&).
    Ответ написан
    Комментировать
  • Ошибка сегментирования (стек памяти сброшен на диск) c++. Как исправить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ваша программа бесконечно уходит в рекурсию, у нее кончаетсся память и она падает. func(1, v) в цикле при i=0 вызовет func(1,v1), которая опять же вызовет func(1,v1), которая опять же... И так пока программе не поплохеет.
    Ответ написан
    Комментировать
  • Как решить эту задачу на C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Немного порешав разные суммы руками можно понять, что тут работает жадное решение - можно брать самую большую купюру, помещающуюся в оставшуюся сумму.

    Это также можно доказать. Брать более одной 100 нет смысла, их можно было бы заменть на 200. Также более двух 200 брать смысла нет - три можно разменять на 500+100, что меньше купюр. Аналогично для всех оставшихся купюр.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    желательно используя средства только голого c++, без библиотек?


    Если вы в линуксе, то введите в терминале "man sendmail". Разберитесь с командой и вызывайте ее из C++ программы через system.

    Иначе - разбирайтесь с сокетами, протокалами SMTP, TCP. Простенький клиент строчек на 3000 сможете написать через пару месяцев, наверное. Ну, или, все-таки, пересмотрите ваши условия и используйте библиотеки или более удобный для этого язык. Так в питоне это делается буквально в 2 строчки.
    Ответ написан
    Комментировать
  • Где ошибка в решении?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас number в int не помещается. А вы цикл гоните от 2 до number. У вас условие i < number в цикле будет всегда выполнятся - потому что ну не может int i быть больше number.

    edit: И вообще логика проверки на простоту у вас сломана. del = i выполнится для любого j, такого что i на него не делится. Т.е. если i=6, то при j=5 вы dеl перезапишите. Вам надо в цикле устанавливать bool flag. И, после цикла на него смотреть.
    Ответ написан
    9 комментариев
  • Почему максимальный размер объекта std::string равен 4611686018427387897?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну вот просто создатели библиотеки захардкодили именно это число.
    Эта конструкция возвращает разные значения, в зависимости от компилятора, разрядности, опреационной системы.

    Это 2^62-7. Почему 2^62? Может, в силу каких-то причин в вашей системе нельзя адресовать больше 62 бит. Может, система 2 бита для чего-то использует. Почему -7? Надо еще где-то хранить длину, надо оставить место для нулевого символа в конце и надо оставить нетронутым индекс std::string::npos - это значение используется для обозначения "несуществующего индекса". Конкретное значение зависит от того, что там программисты стандартной библиотеки сделали.

    В любом случае, это значение на много-много порядков больше любой практически возможной длины строки. Ну не сможете вы выделить 4 экзобайта памяти.
    Ответ написан
    Комментировать
  • Нужно понять что значит код и что выведется на экран?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Запустите и посмотрите: https://www.onlinegdb.com/online_c++_compiler. Попробуйте поменять по одному символу и смотреть, что происходит с выводом. Так вы поймете, что именно выводится, а потом чуть чуть знания C и вы поймете, почему так происходит.
    Ответ написан
    4 комментария
  • Не работает алгоритм std find для строки?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы вызываете std::find, который призван искать элемент в коллекции. А пытаетесь искать там строку. Это все почти компилируется, потому что строка - это коллекция символов, по ней можно было бы искать один символ. Но вы передаете туда указатель (ваша строковая константа). Компилятор не может преобразовать его в символ и на это ругается.

    Для того, что вам надо - есть std::string::find. Т.е. вам надо вызвать str.find(" ").

    Или же ищите один символ. Только не забудьте algorithm включить, а то непонятные ошибки с итераторами полезут.
    Ответ написан
    1 комментарий
  • Не понимаю, как правильно реализовать программу?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Во-первых, можно отлично читать из файла сразу число. Вы как с консоли числа вводите? Вот точно также, только из файла. Вы как строку-то читаете? Вот передавайте там не строку, а int условный. Ну, еще, если scanf-ом читаете, то надо туда %d вместо %s передавать. А так есть еще функции преобразования числа в строку. Читайте справки по atoi, sscanf, stringstream.
    Ответ написан
    3 комментария
  • Алгоритм для нахождения количества пересечений отрезков в последовательности(списке)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Заведите массив из нулей. Для каждого отрезка сделайте +1 в координату его левого конца и -1 в координату, следующую за правым концом.

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

    Это если вам надо весь массив, как в примере, выводить. Не знаю специфику вашей задачи, может эффективнее будет класть в массив пары {координата, +-1} и сортировать. Потом точно также обойти слева направо поддерживая счетчик.
    Ответ написан
    4 комментария
  • Инициализирование класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас в примере вообще классы без данных, поэтому разницы никакой нет между первым и вторым вариантом. Третий выделят память под объект не на стеке, а в куче - поэтому и выделение и работа с объектом, обычно, будет дольше.

    Если бы в объекте были данные, то первый вариант был бы быстрее всего, потому что он ничего бы не инициализировал, в отличии от остальных.

    Если бы в объекте был еще и конструктор, то первый и второй варинт были бы идентичными.

    Третий вариант всегда инициализирует объект и выделяет память, поэтому он будет медленнее.
    Ответ написан
    Комментировать
  • Как передать в функцию указатель если она принимает ссылку?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Никак. Заставьте вашу функцию принимать указатель:

    template <typename type>
      static void readMemory(uintptr_t offset, unsigned int length, type* var) {
        ReadProcessMemory(targetHandle, (LPVOID)offset, var, length * sizeof(type), 0);
      }
    
    uint8_t arr[100500];
    readMemory<uint8_t>(0x00, 10, arr);
    Ответ написан
    2 комментария
  • Почему у временного объекта можно вызывать non-const метод?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    По поводу вызова неконстантных методов - а с чего вы взяли, что они не дожны быть возможны? Временные объекты не имеют const квалификаторов. Иначе нельзя было бы делать вещи типа SomethingBuilder().WithA().WithB().Finalize().

    //! f6() = X(1);

    Оператор присвоения требует Lvalue слева. Временный объект же - Rvalue. Eго можно ставить только справа от =. А не потому что у него const квалификатор.

    Это сделано скорее всего потому, что, ну, нет же смысла перезаписывать временный объект. Он временный, к нему потом никак не обратиться.

    //! f6().modify();

    Вот тут попытка вызова неконстантного метода у константного (и временного - но это не важно) объекта.

    //! f7(f5());

    Видимо, это чтобы исключить некоторый класс ошибок. Если вы передаете в качестве неконстантной ссылки что либо, значит оно должно внутри менятся и снаружи эти изменения должны быть видны. Иначе можно было бы передавать по константной ссылке или по значению. Но вы передаете туда временный объект - его никак снаружи видно не будет. Он существует только в этой строчке. Поэтому в C++ нельзя инициализировать неконстантные lvalue ссылки через rvalue (временные объекты).
    Ответ написан
    1 комментарий
  • Как прочитать масив данных динамической длинны?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам придется переписать функцию readMemory, чтобы она принималаlength и читала length*sizeof(type). Или вызывайте прямо ReadProcessMemory в вашей функции.

    Текущая реализация для вашей цели не подходит вообще. Тип шаблона должен быть известен на этапе компиляции. А вы хотите как-то в нем передать динамическую длину.
    Ответ написан
    4 комментария
  • Как исправить ошибку сборки проекта, при подключении sdl?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы, похоже, создали обычный оконный проект, а надо было создавать консольное приложение. Легче всего будет пересоздать проект. Внимательно смотрите, что вы там выбираете.
    Ответ написан
  • Как сымитировать правильную скорость выполнения различных сортировок путём usleep?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы наткнулись на важное свойство ассимптотического анализа. O(n^2) -означает, что на достаточно больших n, время работы будет примерно n^2 с точностью до константы. Эта самая константа может быть хоть 0.5, хоть 10000000.

    Сравните 2 алгоритма:
    // n(n-1)/2 инкремента.
    for(i = 0; i < n; ++i){
      for (j = i+1; j < n; j++) {
        cnt1++;
      }
    }
    // n^2 инкремента.
    for(i = 0; i < n; ++i){
      for (j =0; j < n; j++) {
        cnt2++;
      }
    }


    Оба алгоритма имеют O(n^2) сложность, но один делает примерно в 2 раза меньше операций.

    Суть в том, что хоть алгоритмы и работают с одинаковой ассимптотикой, они могут работать разное время! Особые странности могут быть при маленьких n. O(n log n) алгоритм часто может быть медленнее O(n^2) алгоритма. Поэтому все настоящие реализации сортировок для маленьких массивов запускают более тупые квадратичные алгоритмы.

    Если же вы хотите показать только ассимптотику, то возьмите n побольше, и тогда эти 30% будут незаметны по сравнению с десятикратным замедлением O(n^2) относительно O(n log n). Или нормируйте ваши сортировки. Искуственно ускорьте одни алгоритмы и замедлите другие, чтобы получить именно тот результат, который вы хотите. Но это как-то нечестно что ли. Если же вы все-таки хотите именно этого, назначьте каждой сортировке время C\*n^2 или С\*n\*log n миллисекунд. Прогоните алгоритмы сортировки без визуализации, подсчитайте, сколько операций замедления вы бы сделали (тот же самый код, что у вас, только вместо usleep() делайте sleep_count++). В конце подсчитайте коэффициент замедления - сколько каждый usleep должен спать, чтобы суммарно sleep_count их спал заданное время. И запускайте каждую сортировку уже с подсчитанными параметрами для usleep.
    Ответ написан
    Комментировать
  • Почему нельзя возвращать объект по значению в non-const &?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Первое - это Retrun Value Optimization. Компилятор видит, что результат работы функции используется для инициализации переменной и вместо выделения памяти под временный объект и копирования сразу заполняет результат.

    По поводу ссылки. Результат работы функции в вашем случае - prvalue

    там же по ссылке написано:
    An rvalue may be used to initialize a const lvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.

    An rvalue may be used to initialize an rvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.


    Т.е. стандартом запрещено инициализировать не const ссылку через prvalue.

    Почему это сделано? Потому что эти самые prvalue/rvalue по сути являются временными объектами. У них нельзя взять адрес, у них нет имени, компилятор может засунуть их куда угодно и уничтожить сразу за текущим выражением.

    Если бы можно было делать ссылку на эти временные объекты и как-то их менять потом, это бы усложняло анализ и возможность некоторых оптимизаций. Как, например, RVO в вашем вопросе. Пришлось бы создавать временную переменную в main для хранения результата, потому что функция память под результат не выделяет. Поэтому в стандарте C++ этого нет.

    Потом, когда в С++11 ввели rvalue ссылки и перелопатили категории значений - разрешили инициализировать rvalue ссылки через prvalue.

    Поэтому работают
    const int& r1 = f();
    int&& r2 = f();
    Ответ написан
    1 комментарий
  • Как в массиве хранить указатели на объекты разных типов?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Если все эти типы унаследованны от одного и того же класса, то можно хранить указатели на базовый класс.
    Ответ написан
    3 комментария
  • Как исправить ошибку EXC_BAD_ACCESS (code=1, address=0x0)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы "создаете" класс sf::RectangleShape через malloc в составе временных массивов pq, qr. Он оказывается заполнен мусором. Нарушены какие-то его внутренние инварианты. Может быть куча проблем: начиная от того, что там переопределен оператор присванивания, который должен что-то где-то почистить, заканчивая тем, что таблица виртуальных методов у класса будет испорчена. Любая попытка сделать что угодно с таким экземпляром класса - скорее всего неопределенное поведение.

    Если уж вы используете классы из C++, то выделять память надо через new[], а не malloc. Тогда экземпляр класса создасться нормально и конструктор вызовется.

    Можно было бы подумать, что memmove решил бы вашу проблему - но, опять же, при этом нарушаются внутренние инварианты. Какой-нибудь unique_ptr внутри будет уже не уникальным. Такие операции работы с памятью можно делать только для POD (Plain old data) - структур состоящих из структур, массивов и базовых типов.

    Или, еще лучше использовать vector для временных массивов. Тогда вам не придется заботиться об освобождении памяти. Еще, вместо копирования можно использовать std::move, может работать бысрее, если эти sf классы имеют более эффективные операторы перемещения.
    Ответ написан
    1 комментарий
  • Как вынести определение конструктора шаблонного класса(вариативного) вне него?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Надо так:
    template<typename ...Args>
    UniformBuffer<Args...>::UniformBuffer(Args... arg)
    { 
    //код
    }


    У вас шаблоном является сам класс, а не его методы.
    Ответ написан
    2 комментария