• Как на C++ выполнить параллельные математические вычисления?

    @Alexander1705
    Способов распаралелить много, но хочу заметить, что ваши вычисления получаются бесконечными отчасти благодаря следующей строке:
    cout << sqrt(n) << endl;
    А именно, из-за endl. После каждого вычисления вы зачем-то сбрасываете поток вместо того, чтоб просто вывести символ перевода на новую строку '\n'.

    P.S. В С пишите math.h, а в C++ - cmath. И зачем вы используете while вместо for?
    #include <cstdint>
    ...
    for (uint64_t i = 0; i < UINT64_MAX; ++i)


    P.P.S. Вот пример на чистом C++. Не забудьте подключить библиотеку pthread.
    Код
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <thread>
    #include <mutex>
    #include <chrono>
    #include <cmath>
    #include <cstdint>
    
    
    using namespace std;
    
    
    mutex ios_mutex;
    
    
    void compute(int b, int e)
    {
        stringstream buffer;
        for (uint64_t i = b; i < e; ++i)
        {
            buffer << sqrt(i) << '\n';
        }
    
        ios_mutex.lock();
        cout << buffer.str();
        ios_mutex.unlock();
    }
    
    
    int main(int argc, char** argv)
    {
        thread t0(compute,   0,  99);
        thread t1(compute, 100, 199);
        thread t2(compute, 200, 299);
        thread t3(compute, 300, 399);
        thread t4(compute, 400, 499);
        thread t5(compute, 500, 599);
        thread t6(compute, 600, 699);
        thread t7(compute, 700, 799);
    
        t0.join();
        t1.join();
        t2.join();
        t3.join();
        t4.join();
        t5.join();
        t6.join();
        t7.join();
    
        return 0;
    }

    Ответ написан
    1 комментарий
  • Насколько оправдан код на C++ в стиле Perl/PHP, с операцией || в роли if (!)?

    maaGames
    @maaGames
    Погроммирую программы
    НЕ стоит так писать. Оптимизатор вполне может сделать предвычисление аргументов функций до вызова самих методов и, если аргументы не тривиальные, то это может изменить логику программы. Да и вообще, такое читать довольно сложно и не очевидно.
    Ответ написан
    8 комментариев
  • Как изучать дальше(c++)?

    GavriKos
    @GavriKos
    Прочитав книгу и посмотрев серию уроков вы не изучили C++ аж никак. Вам нужна практика. Придумайте себе любую задачу и решите ее. И поиск юзайте - вопрос поднимался много раз.
    Ответ написан
    1 комментарий
  • Почему не работает функция?

    Nipheris
    @Nipheris Куратор тега C++
    Для вещественных чисел нет сравнения ==. Есть сравнения (a - b) <= eps. В большинстве случаев так и нужно, т.к. вещественными числами моделируется континуальные величины из реального мира (т.е. те, в которых не обязательно считать с точностью до каждой цифры).

    С другой стороны, для денежных расчётов вещественную арифметику использовать нельзя, т.к. деньги в принципе дискретны. Никто не хочет по определению увидеть 4.74999999...$ вместо 4.75$. Для таких расчетов используются decimal-типы (таких типов не в стандартном C++, есть реализованные в виде библиотек).

    Она должна превращать такие числа 0.475 в такие 475

    Строго говоря, задача поставлена некорректно. Ну или бессмысленно. Такую задачу можно было бы поставить для decimal-типов, которые считаются всегда точно, и количество десятичных цифр в их записи ПРЕДСКАЗУЕМО. А для float у вас будет получаться что-то вроде 4749999999998.

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

    В общем, добро пожаловать в мир машинной арифметики.

    https://en.wikipedia.org/wiki/Floating_point
    https://en.wikipedia.org/wiki/Decimal_data_type
    Ответ написан
    Комментировать
  • "Python experience is plus" в вакансии Senior C++ Developer и похожих. С чем связано?

    GavriKos
    @GavriKos
    На питоне часто пишут какие то мелкие тулзы для внутренних нужд компании. Возможно именно это и есть причина. А вообще - вы можете прийти на собеседование и спросить - зачем им питон :-)
    Ответ написан
    Комментировать
  • Можно ли возвращать лямбды?

    @MiiNiPaa
    Вот так делать - это нормально?
    Вполне

    И что в таком случае возвращается, указатель на функцию или сама функция?
    Функциональный объект. Лямбда — не функция, она может быть приведена к указателю на функцию в некоторых случаях.

    Если возвращается указатель, то где хранится сама функция, в куче или стеке?
    «Функция» лямбды хранится там же, где и остальной код. На лету ничего не собирается и не компилируется. Лямбда это синтаксический сахар для объявления класса с перегруженым оператором вызова функции.

    И еще один вопрос, по этой же теме:
    Это сокращенная запись вот такой конструкции:
    Или что то другое?
    lambda имеет уникальный тип. Это не функция (но может быть приведена к ней в данном случае).
    Ответ написан
    Комментировать
  • Где скачать среду для С++?

    Вообще не нашел адекватной сборки.
    В этом и проблема. Вы ищите какие-то левые сборки с кряками, но на официальный сайт даже не удосужились зайти.
    Компилятор не работает, отладка не работает, нихера не работает. Бомбит. А отзывы-то хорошие.
    Всё работает. Нужно не бомбить, а читать документацию.
    Аналогично: компилятор не компилируется.
    Вы даже не понимаете, что должно происходить.
    Ответ написан
  • Выдает ошибку при компиляции C++, Как решить?

    @res2001
    Developer, ex-admin
    Какая ошибка то?
    У вас подозрительные какие-то символы » и «. Если они же и в реальном коде, то это не правильно - правильно >> и <<.
    Ответ написан
    1 комментарий
  • {} при инициализаци массива массивов?

    @MiiNiPaa
    Вообще, оно не должно компилироваться вообще. Размеры массивов должны быть константными выражениями.

    То что у вас — расширение компилятора. Не работает в С++14 скорее всего потому, что в С++11 компилятор использует собственное расширение основанное на сишных VLA. А в С++14 — более ограниченные С++ ARB, которые могли войти в С++14, но не вошли.
    Ответ написан
    2 комментария
  • Что за ошибка с памятью и как её решить?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Здесь надо выделять массив, а не переменную
    bool* nptr = new bool;
    В целом код еле-еле натягивает на троечку. Использование четырёх! стеков там, где можно обойтись двумя. Двойное копирование массивов в push, где можно обойтись одним, не говоря уже про realloc. Копирование массивов при pop, где оно совсем не нужно. Перевыделение памяти на каждый push/pop.
    Передача типа строкой вместо bool или enum.
    Ответ написан
    Комментировать
  • Как именно работает данный конструктор list?

    @MiiNiPaa
    Что является результатом данной строки

    Пустой список. Чтобы там что-либо было, туда нужно что-нибудь положить

    И как производить обращение к элементам, в таком случае?

    К первому/последнему — через front/back. К остальным — через итераторы.

    Пример:
    list<vector<string>> lvs {{"Hello", "World"}, {"Goodbye", "Universe"}, {"What", "am", "I", "doing"}};
    for(auto it = list.cbegin(), it != list.cend(), ++it) {//Проходимся по всем элементам списка
        cout << (*it)[1] << '\n';
        // (*it) даст элемент списка: vector<string>
        // Пы можем обратиться к элементу вектора при помощи оператора []
    }
    Ответ написан
    3 комментария
  • Как циклом перебирать посимвольно string переменную c++?

    @Alexander1705
    string str = "Hello, world!";
    
    for (auto c : str)
    {
        do_something(c);
    }
    Ответ написан
    Комментировать
  • Почему не считается остаток от деления в Arduino?

    a_volkov1987
    @a_volkov1987
    Инженер-схемотехник
    arduino.ru/Reference/Serial/Write
    arduino.ru/Reference/Serial/Print

    Видите разницу?
    В первом случае вы результат отправите как бинарный код. И монитор порта отобразит совсем не то, что вы ожидаете.
    Во втором случае вы результат отправите как ASCII текст. То есть, что отправите, то и увидите в мониторе.

    Попробуйте просто для сравнения:
    Serial.write(65);
    Serial.write("65");
    Serial.print(65);

    Вывод: проблема не в математике, проблема в формате вывода результата в порт.
    7704bdbbbae94ba498493b97e096d07e.png

    UPD: ТС для проверки использует Proteus, я - Arduino Leonardo
    Ответ написан
    9 комментариев
  • Где и как правильно использовать спецификатор virtual в С++?

    zagayevskiy
    @zagayevskiy
    Android developer at Yandex
    Это называется "динамический полиморфизм".
    Виртуальные методы полезны тем, что вызывая метод через ссылку или указатель на базовый класс, на самом деле вы вызываете метод дочернего класса:
    class B {
    public:
        virtual void f() {}
        ...
    }
    
    class D: public B{
    public:
        void f(){}
        ...
    }
    ...
    doF(D());
    ...
    void doF(const B& b){
        b.f();// вызовется D::f() 
    }


    Если написать вместо тела виртуальной функции "=0;", то получится чисто виртуальный класс. Это уже полноценный аналог абстрактного класса в джаве. А если сделать все методы чисто виртуальными и не делать полей-данных, то получится аналог интерфейса.

    Виртуальным обязательно должен быть деструктор у класса, который создаётся для наследования. Иначе сделав так:
    B *d = new D();
    delete d;
    вы вызовете только деструктор базового класса.
    Ответ написан
    5 комментариев
  • Можно ли программировать Arduino на Python?

    @Roman_Popov
    лужу, паяю, линуксом управляю
    Микроконтроллер, который стоит в ардуино, понимает только машинные коды. Поэтому программировать его, по большому счету, можно хоть на чем - главное чтобы была соответствующая среда разработки. Насколько мне известно существует проект такой среды для питона, но сам не пробовал.
    На торрентах видел книжку "Python Programming for Arduino", Pratik Desai, 2015
    Интересовался темой поверхностно, т.к. предполагал, что обучить великовозрастных дитятей (15-16) питону будет проще, чем сям. Ошибался... Они вообще необучаемые :)
    Ответ написан
    Комментировать
  • Как работает static cast?

    @MiiNiPaa
    Пытается произвести преобразование используя определённые операторы преобразования и конструкторы. Если подобного преобразования нет, выдаст ошибку.

    С указателями на классы связанные отношением наследования всё несколько сложнее:

    1) Преобразование указателя на дочерний класс в указатель на базовый.
    static_cast безопасно приводит типы: возвращаемое значение — указатель на базовый субобъект дочернего класса.

    2) Преобразование указателя на базовый класс в указатель на дочерний.
    Преобразование всегда успешно (нет ошибки компиляции). Если базовый указатель указывает на субобъект дочернего класса, приведение успешно и безопасно. Если базовый указатель не указывает на субобъект дочернего класса, то результат приведения не определён и может случится что угодно.
    struct base 
    {};
    struct derived: base
    {};
    //...
    derived* d = new derived;
    
    //Работает, безопасно
    base* b = static_cast<base*>(d);
    
    //Работает, безопасно так как b на самом деле указывает на derived
    d = static_cast<derived*>(b);
    
    b = new base;
    //Undefined Behavior. Программа превращается в тыкву.
    d = static_cast<derived*>(b);
    Ответ написан
    4 комментария
  • Где найти библиотеку?

    @MiiNiPaa
    Она является частью языка. Если компилятор ругается не её отсутствие: выкиньте Turbo C++/установите компилятор по-нормальному.
    Ответ написан
  • Приведение обьекта производного класса к базовому?

    Nipheris
    @Nipheris Куратор тега C++
    поля объявленные в производном классе исчезают?

    Это называется object slicing. Это явление проявляется в языках, где сложные типы данных вроде классов и записей а) могут наследоваться и добавлять новые поля при наследовании; б) могут присваиваться по-значению (by value). Это и приводит к тому, что поля потомка при присвоении в переменную типа предка отсекаются. Такое присвоение само по себе некорректно, т.к. если вы работаете с объектами классов-наследников через интерфейс базового класса, это подразумевает полиморфное поведение и работу через ссылку/указатель, т.е. чтобы вместо самого объекта копировалась ссылка/указатель на него (т.е. его identity, "уникальный ключ"), а сам оставался нетронутым и лежал там же, где и лежал.

    При работе через ССЫЛКУ на базовый класс (т.е. Base&) таких проблем не будет, однако ссылка сама по себе переменной не является (в отличие от указателя) - это лишь дополнительное ИМЯ для некоторой другой переменной или области памяти. Поэтому, вы не сможете сохранить ссылку в векторе - ваш код не скомпилируется. В векторе вам нужно будет хранить указатели. Например, std::vector<Base*>.

    Запомните простое правило - если ваши объекты подразумевают работу через интерфейс базового класса (т.е. полимофрное поведение), то в большинстве случаев вам следует работать с ними через указатель (и, в большинстве случаев, размещать эти объекты в куче). В том числе через умные указатели (unique_ptr, shared_ptr).

    В других языках (C#, D вроде тоже) существует фундаментальное разделение на типы-значения и ссылочные типы, и для всех ссылочных типов работа "через ссылку" предоставляется автоматически. В C++ такого разделения нет, и как работать с типом вы выбираете сами, при его ИСПОЛЬЗОВАНИИ (т.е. используете либо по-значению, либо через указатель).

    P.S. С днем рождения!
    Ответ написан
    1 комментарий
  • Умные указатели?

    Есть задачи, которые не имеют решения на ссылках (либо это решение в разы хуже, чем если бы мы использовали указатели).
    Пример: паттерн стратегия
    #include <iostream>
    #include <memory>
    
    class Strategy {
    public:
        virtual void doAction() = 0;
    };
    
    class FirstStrategy : public Strategy{
    public:
        void doAction() override {
            std::cout << "First" << std::endl;
        }
    };
    
    class SecondStrategy : public Strategy{
    public:
        void doAction() override {
            std::cout << "Second" << std::endl;
        }
    };
    
    class A {
        std::shared_ptr<Strategy> behavior;
    
    public:
        void setBehavior(std::shared_ptr<Strategy> b) {
            behavior = b;
        }
    
        void doBehavior() {
            behavior->doAction();
        }
    
    };
    
    int main() {
        A a;
        a.setBehavior(std::make_shared<FirstStrategy>());
        a.doBehavior();
    
        a.setBehavior(std::make_shared<SecondStrategy>());
        a.doBehavior();
        return 0;
    }


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

    @evgeniy_lm
    35 лет занимаюсь изготовлением плат, но не разу даже не пришло в голову использовать емкость для травления как-то иначе
    Ответ написан
    Комментировать