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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Разбейте задачу на подзадачи:

    1) Проверить, что данный элемент надо удалить
    1.1) Проверить, что элемент не уникальный
    1.2) Проверить, что элемент - не первый среди одинаковых (один-то его надо оставить)
    2) Удалить элемент из массива дописав 0 в конце.

    Все эти пункты выполняются циклом. в первых пунктах будет удобно завести булевую переменную, которая после цикла будет содержать значение проверки.
    Ответ написан
    Комментировать
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

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

    Создайте 2 функции, которые отличаются только вот в этих вот местах.
    Вставьте код в https://godbolt.org/

    Смотрите ассемблерный код для двух функций.

    Может, срабатывает strict aliasing. Видя тип T сомпилятор понимает, что эта переменная не может быть изменена какими-то другими std::byte в соседнем коде и может, например, пропустить загрузку-выгрузку данных в регистр из памяти.

    Может вообще что-то другое.

    Единственный вариант разобраться - это смотреть на ассемблерный код функций, которые вы и сравниваете. Не каких-то кусков, оттуда надерганных, а функций целиком.
    Ответ написан
    Комментировать
  • Ошибка Unhandled exception at 0x0099B514 in ConsoleApplication15.exe: 0xC0000094: Integer division by zero. Как исправить это?

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

    Засуньте ошибку в переводчик, если по английски не понимаете. Ну не умеют компьютеры нарушать законы математики - еще в школе же учат, что на ноль делить нельзя.

    Очевидно, что size/3 оказывается 0, потому что size меньше 3.

    Надо менять логику. Или отдельно обрабатывать случай size = 0,1,2 или не делить на 3. Вообще, неясно, откуда в этом коде 3 вылезло и что оно означает.
    Ответ написан
    Комментировать
  • Почему может быть ошибка во время компиляции?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема вот тут:
    parent.resize(++n);
    glub.resize(n);
    for (int i = 1; i <= n; i++) {


    Выход за границу массива. Неопределенное поведение.
    Вы выделяете массивы длины n (увеличенного на 1) и потом проходитесь от 1 до n (увеличенного на 1). Но ведь индексы в массиве только до n-1.

    Правильно так:
    parent.resize(n+1);
    glub.resize(n+1);
    for (int i = 1; i <= n; i++) {
    Ответ написан
    5 комментариев
  • Как реализовать идентификацию объектов?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    unordered_map<ID, Material>
    Ответ написан
    Комментировать
  • Ошибка ссылка на резрешенный внешний символ, как исправить в c++?

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

    Почитайте документацию библиотеки, надо в свойствах проекта добавить библиотеку curl линкеру.
    Ответ написан
    Комментировать
  • C++ как использовать функции winAPI?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вот это GetModuleHandle, например: Вводите в гугле "GetModuleHandle win32". Получаете ссылку вот сюда.

    Там прямо в заголовке написано libloaderapi.h
    Значит, вам надо делать #include "libloaderapi.h"

    Вот так по каждой интересующей вас функции надо найти документацию от microsoft. Там обычно написано, в какой библиотеке оно лежит и в каком заголовочном файле.

    Этот заголовочный файл является частью windows sdk.

    Как вызвать - смотрите в той же документации, какие параметры функция принимает. Или гуглите "GetModuleHandle example".
    Ответ написан
  • Где ошибка в коде переворота двумерного массива?

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

    Надо отдельно обработать случай y == y1
    Ответ написан
    Комментировать
  • Как сделать факториал деление?

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

    Вычислили 1/2. Это просто. Потом 1/(1+1/2). Это тоже просто, ведь 1/2 у вас уже есть. Потом вычислите 1/(2+(1/(1+1/2)). Последняя часть уже вычислена. Если ее обозначить за X, то вам надо подсчтитать 1/(2+X).

    Фактически у вас будет цикл на n итераций, и внутри вы будете пересчитывать этот самый X по формуле вроде X = 1/(n-i + X). Аккуратно посмотрите, может надо там +-1 куда-то вставить рядом с i.
    Ответ написан
    3 комментария
  • Как построчно выводить даные из .txt документа в C++?

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

    Откуда вы вообще взяли, что он должен читать весь файл? У вас цикл на одну итерацию. Внутри if/else, но в каждой ветке есть break, который цикл завершит. И в довесок ко всему - там еще и return стоит после break, который ни разу не выполнится.

    Вообще все надо с 0 переписать.
    Ответ написан
    Комментировать
  • ОШИБКА: "cannot overload functions distinguished by return type alone" Что делать?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну скормите ошибку гугл переводчику, если по английски не понимаете. У вас две функции называются одинаково, имеют одинаковые параметры но вощвращают разный тип значения. Так нельзя. Полный текст ошибки также укажет вам, какие именно 2 функции у вас там конфликтуют.
    Ответ написан
    Комментировать
  • Как разделить mesh на отдельные сегменты?

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

    Чтобы не копировать кучу раз данные туда-сюда создайте один массив из треугольников. Потом заведите еще один массив int-ов для пометок, к какому мешу каждый из треугольников принадлежит. Вы его заполните и потом можно за один проход разложить треугольники по новым мешам.

    Еще заведите массив списков длинной сколько у вас точек. Пройдитесь по каждому треугольнику и засуньте его номер в 3 списка для каждой из его вершин.

    Ну, а дальше, Breadth-First-Search запускаете. Пройдитесь циклом по всем треугольникам, если он еще не помечен, запускаете BFS от него. Помечайте его новым номером, помещайте его номер в очередь, и циклом пока очередь не пуста, извлекаете из нее элемент. Смотрите 3 списка для трех вершин. Если треугольник оттуда еще не помечен, помечаете его текущим номером меша, кладете в очередь.

    Еще для ускорения можно после просмотра списка треугольников для вершины отчищать его.

    Альтернативный вариант - завести hash_map из пары вершин в номер треугольника. Пройдитесь по треугольникам, и для каждого ребра, если оно еще не помечено, кладите номер треугольника в map. Иначе текущий и второй треугольник связаны - добавьте каждый из них в список инцидентности для второго. В таком варианте у каждого труегольника будет три ребра в соседей по сторонам.

    Только перед обращением к мапе точки сортируйте.
    Ответ написан
  • Как достать из браузера куки?

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

    Надо смотреть как конкретный браузер эти куки хранит. Найти нужный файлик на компьютере, распарсить его. Если вы пишите браузер, то это по сравнению с ним - элементарная задача.

    Chrome, например, хранит куки в SQLite базе в папке профиля пользователя. Тут вам понадобится найти SQLite библиотеку, с помощью ее открыть файл и взять оттуда данные.

    Учтите, что разные браузеры хранят куки по разоному. Даже разные версии браузеров. Так что вам придется поддерживать кучу случаев.
    Ответ написан
  • Почему std::swap вызывает конструктор перемещения?

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

    void swap(T &a, T &b) {
      T tmp{std::move(a)};
      a = std::move(b);
      b = std::move(tmp);
    }
    Ответ написан
    8 комментариев
  • Почему Config::search у меня возвращает мусор?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема вот в этой строчке:
    return str.c_str();

    Тут вы возвращаете указатель на внутренние данные у str. Но при выходе из функуции str уничтожается - это же локальная переменная. В итоге у вас получается висячий указатель (указатель на память, которой вы уже не владеете). Эту память какая-то другая часть вашей программы переиспользует и там остается что-то не ваше, выглядещее для вас, как мусор.

    Вообще, это undefined behavior - доступ к висячему указателю. Программа вполне может и аварийно завершится.

    Для решения этой проблемы возвращайте std::string. Или выделяйте char* вручную, через new[] (только не забудьте указатель потом удалить в вызывающем коде). Но лучше, конечно, возвращать string и не мучатся с ручным управлением указателями.
    Ответ написан
  • Как сократить код с подпрограмой?

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

    Ну какая разница, как у вас там переменная называется sA или sB - результат будет один и тот же.

    Да, может вы путаетесь, но аргумент в функции можно тоже переменовать. Хоть там и написано int masivA(int* a), этот a - это аргумент. Он никак не привязан к массиву a в main(). Туда можно передать и a и b и любой другой массив.
    Ответ написан
    4 комментария
  • Аварийное прекращение создания объекта из класса, который является родителем?

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

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

    Но этот метод не так легко обобщается на цепочки наследников. Надо чтобы все они одинаково интерпретировали этот флаг и меняли его при неудачной инициализации.
    Ответ написан
    3 комментария
  • Почему substr работает странно?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Потому что читайте документацию. substr принимает начало и длину подстроки, а не конец.

    Соответственно, надо делать вот так:
    std::string variable_value = var.substr(variable_value_start + 1, variable_value_end - variable_value_start - 1);
    Ответ написан
    Комментировать
  • Как перевести число в двоичную систему счисления?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нужно или выводить нужное количество ведущих нулей, или изменить условие в цикле перевода. У вас там сейчас while (Notspace[i] > 0), что как раз считает цифры до последней значащей цифры. Поменяйте на цикл в 8 итераций и будет у вас всегда 8 цифр.
    Ответ написан
    Комментировать