• Хотел написать движок на OpenGL, а примитивная ходьба работает криво, как исправить?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Дебажить, конечно же. Взять бумажку и ручку/планшет и стилус или что там есть под рукой, расписать по шагам весь алгоритм, сделать вывод результатов каждого шага алгоритма в коде и сравнить как должно быть и что получилось.
    Ответ написан
    2 комментария
  • Как передать в аргумент функцию, и выполнить её, передаваю в неё параметры?

    @dima20155
    you don't choose c++. It chooses you
    Самый простейший пример.
    Модифицируйте его если нужны ссылки на аргументы

    #include <functional>
    #include <iostream>
    
    template <typename Func, typename ... Args>
    void foo(Func func, Args ... args) {
        func(args...);
    }
    
    int main() {
        foo([](){ std::cout << "endl;" << std::endl; });
        foo([](int i){ std::cout << "int i: " << i << std::endl; }, 123);
    }
    Ответ написан
    Комментировать
  • Что стоит учить с или c++ или c#?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Добрый вечер! Столкнулся с такой проблемой: Мне очень нравятся семейство языков Си, у меня есть выбор учить C++ либо C#, хочу разрабатывать ПО для ПК. Подумал начать с C++ и говорят что сначала поучить чистый СИ, а после переходить на C++, так что же из этого правильно? Надо ли учить Си? Или может лучше начать с C#, а дальше уже выучу C++?

    Тема сравнения С/C++/C# в публичном пространстве - опасная тема. Она обычно заканчивается
    топиком в 1000 страниц и великой войной всех против всех. Я видел много таких войн.
    Они ничем не заканчиваются. Специалисты остаются при своих мнениях. А зритель просто развлекается.

    Сам по себе выбор языка ставят только новички. Професиионалу безразличен язык (почти). Его может больше интересует отрасль, стек технологий, стандарты и протоколы. С моей точки зрения сегодня
    таким стандартом может быть выбор облака (AWS, Azure, GCP).

    Чистый СИ учить смысла нет. Учи сразу С++. Но даже его создатель Бьорн Страуструп считает что С++ это
    сложный язык и он настаивает чтобы новички не брались учить все фичи сразу. Исключение по языку
    СИ может быть в том случае, если ты собрался быть инженером по разработке микро-контроллеров
    и у тебя скорее всего будет только СИ как основной (на 80-90%) инструмент взаимодействия с таким железом. Выйти на мидловый или синьорный уровень в С++ очень тяжело. Тяжелее чем в других языках.
    Поэтому будь готов терпеть. Вот когда виски станут седые - тогда и будешь господин-синьор.

    C# - это очень сильно корпоративный стандарт от Microsoft. Никакой связи с С++ он не имеет. Он конечно
    внешне похож но это сходство обманчиво. Да изучать его тоже можно. Он учится легко. Существуют книги
    вроде ".... C# за 14 дней". Разработка бизнес-приложений на шарпах идет гораздо быстрее чем на С++
    например. И завалить систему в синий экран в этом языке гораздо труднее. В нем реализованы методы
    защиты памяти и нельзя грязно трюкачить с указателями как это любят в С или С++. Производительность
    шарпов в численных методах будет слабее чем в С++ но обычно бизнес не ставит таких задач и чаще
    надо будет писать веб-хендлеры или хендлеры MQ-систем. Кач уровней синьорити идет быстрее в шарпах.
    Ответ написан
    2 комментария
  • Что стоит учить с или c++ или c#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Это 3 совершенно различных, с точки зрения целей, языка. Лучше пойми что ТЫ хочешь, а потом выбери
    Ответ написан
    Комментировать
  • Как правильно реализовать освобождение памяти выделенной в функции?

    @dima20155
    you don't choose c++. It chooses you
    Все до безобразия просто:
    Вы выделяете память в момент, когда она вам нужна, а удаляете когда эта память вам более не нужна.
    Соотвественно, вам нужна функция array_deinit(), которая возьмет на себя непосильную ношу освобождения памяти в момент, когда вы больше не планируете обращаться к своему двумерному массиву.

    В простейшем случае, в С++ подобный функционал оборачивают в класс, который, в свою очередь, обязательно должен почистить за собой память хотя бы в деструкторе.

    Также в современном С++ не принято использовать new/delete без веской причины (например, вы пишете супер быстрый, современный контейнер, в котором хотите управлять всеми аллокациями самостоятельно), а рекомендуется использовать умные указатели для работы с памятью.
    Ответ написан
    2 комментария
  • Почему нельзя использовать std::function как аргумет шаблонной функции?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Потому что лямбда не ялвяется std::function. Компилятор, вообще говоря, может лямбду привести к типу std::function, но не в вашем случае. Вам надо, например, самим преобразовать лямбду в std::function:
    std::function<bool(int, int)> comp = [](int left, int right)
      {
        return left < right;
      };
      Sort(vec, comp);


    Сам компилятор тут это сделать не может, потому что ему тип к которму приводить-то неизвестен - он зависит от параметра шаблона T.

    Можно, еще, например, указать компилятору параметры шаблона, тогда все скомпилируется:
    Sort<int>(vec, [](int left, int right)
      {
        return left < right;
      });


    Но лучший вариант - не использовать std::function в шаблоне. Просто используйте какой-то typename U, у которого вы продполагаете существует operator(int, int). Если туда передать не function и не лябмду, оно не скомпилится:

    template <typename T, typename U>
    void Sort(std::vector<T>& vector, U comparison) {
        // Используете comparison, как-будто это std::function:
        if (comparison(1, 1)) return;
    };
    
    
    int main()
    {
      std::vector<int> vec = { 1, 2, 3, 4, 5, 7, 6, 9 ,8 };
    
      Sort(vec, [](int left, int right) -> bool
      {
        return left < right;
      });
        return 0;
    }
    Ответ написан
    Комментировать
  • Почему умножение матрицы 8x8 медленнее чем 10x10?

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

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

    Ну и главное, выполнять такое короткое действие всего один раз - это вообще моветон. Надо выполнить его сотню тысяч раз и потом общее время делить на количество запусков. Иначе вы меряете случайный шум в основном. Может тут вам просто все время (не)везет и вот так третий тест оказывается быстрее остальных.
    Ответ написан
    3 комментария
  • Как определить принадлежность точки к плоскости?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    У вас нет проверки условий для диагональных границ области: y<=x при x<=1 и abs(y)<=x-1 при x>=1. Добавляйте, проверяйте и сдавайте решение.
    Ответ написан
    1 комментарий
  • Не работает case в switch. Как решить проблему?

    @res2001
    Developer, ex-admin
    Блоки case в операторе switch это просто аналог меток для goto. Соответственно после перехода на какой-то case выполнение программы продолжается по всем строкам кода подряд. И если вы не предусмотрели явный выход из блока case (с помощью break или return), то выполнение продолжится и в следующем case и т.д.

    Современные компиляторы умеют выдавать ошибки или предупреждения для таких случаев, т.к. очень часто в коде действительно присутствует ошибка - пропуск оператора break или return (как у вас). В gcc для этого служит опция -Wimplicit-fallthrough. Иногда проваливание в следующий case бывает полезно и используется на практике программистами, тогда (при использовании опции -Wimplicit-fallthrough) надо явно указать на это компилятору. В документации gcc в описании этой опции указано как это сделать.

    Вообще рекомендую ужесточать проверки компилятора, как минимум с помощью стандартных опций: -Wall -Wextra.
    А так же указывать какому стандарту языка надо придерживаться компилятору: -std=c++17 или -std=gnuc++17
    Можно добавить и опцию: -pedantic
    По умолчанию многие полезные предупреждения отключены.
    Многие предупреждения можно перевести в ошибку или игнорировать.
    Есть и другие полезные проверки, которые может делать компилятор, которые не входят в -Wall -Wextra. Но для начала используйте хотя бы их.

    Описание опций предупреждений gcc смотри тут: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
    Ответ написан
    Комментировать
  • Как хранится struct в памяти?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Зависит от компилятора и заданных при компиляции опций. Например, при плотной упаковке (#pragma pack(1)) каждый элемент структуры занимает ровно столько, сколько ему необходимо. А при выравнивании на 64 бита (#pragma pack(8)) под каждый элемент выделится память, кратная 8 байтам и достаточная для размещения элемента. Для разных архитектур процессоров могут быть доступны разные настройки выравнивания.
    Ответ написан
    Комментировать
  • Почему не работает перемещение в C++?

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

    Вот как вы себе пердставляете перемещение int*?
    int* - это адрес в памяти. Число. Когда вы "перемещаете" img этого типа, вы перемещаете одно число. Из переменной img, в вектор.

    При этом что там лежит в памяти по адресу, равному этому числу (или на 20 сдвинутому), вообще не поменялось.

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

    Так, у вас в imgs вы не пихаете копию данных, а пихаете указатель.
    Ответ написан
    2 комментария
  • Откуда взялся const?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    const char* взялся вот отсюда: "Hello world". Это строковая константа в коде. Ее программа менять никак не может. Компилятор ее засовывает в read only секцию исполняемого файла.
    Ответ написан
    Комментировать
  • Откуда взялся const?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Попробуй так.

    void printMessage(const char str[]);

    Чем новее становится версия стандарта С++ - тем строже проверки.
    Ответ написан
    Комментировать
  • Почему в С++ не работают 2 цикла for?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Ты наверное новичек?

    Переменную не рекомендуется дважды использовать в разных ролях в одном блоке кода.
    Ты-же не в ассемблере пишешь? Верно? Зачем тебе эта экономия. Создание новой переменной -
    безопаснее и надежнее. Хороший компиллятор уже сам разебертся где оптимизировать а ты
    - просто напиши чортов правильный код.

    И не забывай инициализировать. И не забывай про scopes.

    for(int i = 0; i < n; i++) {...}

    Иногда профессионалы могут использовать переменную дважды для достижения какой-то другой
    цели. Тут надо смотреть use-case.

    Но Quod licet Iovi, non licet bovi. Тебе пока не позволено. Научись сначала просто
    писать код без ошибок а потом уже делай трюки.
    Ответ написан
    2 комментария
  • Что означает T()?

    @rPman
    T() вызовет конструктор по умолчанию для типа T, тут это переменная шаблона, т.е. тот тип что указан при определении переменной класса List<имя_типа_или_класса>, который собственно тут описан.

    В данном случае возвращать будет новый экеземпляр объекта T в качестве значения аргумента data по умолчанию, если конструктор класса Node будет вызван без аргументов.

    Если честно у меня вопрос, что будет если тип T будет указан скалярный, типа int, определено ли значение по умолчанию для таких типов?
    upd. погуглил пишут да, в контексте шаблонов это нормально и значение по умолчанию определено
    Ответ написан
    4 комментария
  • Что означает запись?

    @res2001
    Developer, ex-admin
    Похоже, это прям низкий уровень - работа с регистрами UART.
    COMBase - это базовый адрес порта. По этому адресу находятся регистры порта их несколько. Добавляя число вы пишите данные в регистр, соответствующий заданному смещению относительно базового адреса.
    Вот тут есть старинное хорошее описание низкоуровневой работы с UART и последовательным портом, с регистрами и прочим.
    Ответ написан
    Комментировать
  • Что означает запись?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В контроллере COM-порта несколько регистров. Запись в них определённых значений меняет режим работы порта. Эти регистры адресуются от базового адреса контроллера.
    _outp(COMBase+3,0x80); - Line Control Register (LCR). Установка старшего бита разрешает доступ к делителю.
    _outp(COMBase,0x01); - установка младшего байта делителя (0x01 => 115200 tick/s).
    _outp(COMBase+3,0x03); - отключение доступа к делителю и установка размера символа 8 бит, 1 стоп-бит, без контроля чётности.
    _outp(COMBase+1,0x00); - Inerrupt Enable Register (IER), запрет всех прерываний.
    _outp(COMBase+2,0xC7); - FIFO Control Register (FCR), разрешить буферы FIFO размером 14 байт и очистить их.
    _inp(COMBase); - прочитать байт из буфера.
    www.osdever.net/documents/CP_serial.pdf
    Ответ написан
    Комментировать
  • Не работает простой код хотя он правильный в чем может быть проблема?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Цифр больше 9 в десятичной системе не бывает.
    А ваш код выдаёт числа от 1 до 10, как вы в нём и написали.
    Ответ написан
    1 комментарий
  • Может ли новичок программирование начать с с++/Gamedev?

    vabka
    @vabka
    Токсичный шарпист
    Ответ на вопрос из заголовка - смотри требования в вакансиях на gamedev C++ и оценивай свои силы, сколько времени тебе понадобится, чтобы эти требования выполнить.

    Если говорить про разработку собственной игры или движка:
    https://qna.habr.com/q/1285166
    Опять же попробуй декомпозировать задачу по разработке конкретной игры с конкретными механиками / визуалом / сюжетом и оцени сколько тебе времени понадобится, чтобы освоить все инструменты и разработать.
    И сколько денег, если ты захочешь привлечь людей со стороны.
    И сколько времени, чтобы заработать эти деньги
    И какие навыки нужны для заработка этих денег
    И сколько времени понадобится на получение этих навыков
    И сколько денег нужно, чтобы не умереть с голоду во время получения этих навыков и разработки игры.

    я видел на форумах писали что Gamedev на плюсах это ели на хлеб наскребсти.

    Геймдев на любом языке такой, тк деньги компенсируются "интересностью".
    Если хочется денег - идти надо в enterprise.


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

    Хороший вариант.

    я не хочу чтоб моя жизнь была проведена на заводе до старости и люди меня считали глупым мне хочется поступить в МФТИ или в какие то престижные колледжы/университеты чтоб уж точно не пропасть в жизни

    1. То что ты с пятого класса учишься на одни тройки не делает тебя автоматически глупым.
    2. Учёба в хорошем вузе не защищает тебя от работы на заводе до старости и не гарантирует тебе, что ты достигнешь какого-либо успеха в жизни.
    3. Чтобы поступить на бюджет в МФТИ или аналогичного уровня университет не достаточно хорошо учиться и получить много баллов на ЕГЭ.
    4. Одним из признаков глупого человека является неумение грамотно и лаконично выражать свои мысли.
    Ответ написан
  • Калькулятор C++ как убрать 1.33333e+06 подобные результаты вычисления?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выводить в фиксированном виде:
    std::cout << std::fixed;  // Меняем формат вывода вещественных чисел 
    std::cout.precision(10);  // Сколько вы там хотите знаков после запятой выводить.
    double e = 1.3333e6;
    std::cout << e;  // 1333300.00000000000;
    Ответ написан
    1 комментарий