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

    @Alexander1705
    Сделать вектор пар std::vector<std::pair<int, char>>, а в std::sort передавать собственный компаратор, который будет сравнивать только первые элементы:
    vector<pair<int, char>> vec;
    sort(vec.begin(), vec.end(), [](pair<int, char> a, pair<int, char> b){return a.first < b.first;});
    Ответ написан
    1 комментарий
  • Как использовать чисто виртуальный метод внутри класса?

    @Alexander1705
    В объявлении метод принимает ссылку, а вы передаёте указатель.
    fillBufferForPrint(&s); // Нужно не так.
    fillBufferForPrint(s);  // А так.
    Ответ написан
    Комментировать
  • Как в Vusial studio разделить проект на элементы а потом сделать их одним целым?

    @Alexander1705
    Вы имеете ввиду разбить проект на несколько файлов?
    Вам понадобится создать по два файла для каждого модуля: заголовочный (с объявлениями) и собственно файл с реализацией (определением). Файлы с объявлениями имеют расширение .h .H .hpp и так далее.

    main.cpp: определение функции main.
    // Следующая строка при компиляции будет заменена на содержимое файла helloworld.h
    #include "helloworld.h"
    
    int main(int argc, char** argv)
    {
        helloworld(); // Вызываем функцию определённую в другом файле.
        return 0;
    }

    helloworld.h: объявление функции helloworld
    // Следующая конструкция называется include guard.
    // Благодаря ней вы не сможете вставить содержимое этого файла дважды,
    // что поможет вам избежать ошибок переопределения.
    #ifndef HELLOWORLD_H 
    #define HELLOWORLD_H
    
    // Объявление функции.
    // Если функция объявлена но не определена в данном файле,
    // компилятор будет искать её реализацию в других файлах.
    void helloworld();
    
    #endif

    helloworld.cpp
    // Снова вставляем содержимое файла helloworld.h
    #include "helloworld.h"
    
    #include <iostream>
    
    // Определяем функцию.
    void helloworld()
    {
        std::cout << "Hello, world!";
    }
    Ответ написан
    Комментировать
  • Почему CLANG/GCC не компилируют код код который компилируется MSVC++?

    @Alexander1705
    Потому, что gcc - компилятор языка C. Используйте g++.

    Upd.
    Ошибку выбивает потому, что вы не подключили библиотеку libstdc++, в которой определены string и другие объекты стандартной библиотеки:
    gcc file_name.cpp -lstdc++
    Просто, msvc++ и g++ делают это автоматически.
    Ответ написан
    2 комментария
  • Какой наиболее удобный (автоматизированный, простой) способ работы с двумерными динамическими массивами (матрицами) в С++?

    @Alexander1705
    Наверняка как-то это уже реализованно/упрощено с помощью стл или буст или чего-то еще.

    Так почему же не проверить, перед тем, как задавать вопрос? Вот, первая ссылка - то, что вам нужно.
    Ответ написан
    Комментировать
  • C++ Муки округления. Как "красиво" сделать следующие функции?

    @Alexander1705
    Так же как в десятичной системе счисления вы не можете представить число 1/3 в виде десятичной дроби, вы не можете представить в двоичной системе счисления некоторые дроби, которые можете представить в десятичной. Если всё же попытаетесь это сделать, получите бесконечную периодическую дробь.
    Так, например если перевести число 0.4 из десятичной системы в двоичную, получите такую периодическую дробь: 0,0110011001100.. и так далее до бесконечности. 100 / 1010 = 0.(0110)

    Однако это не означает, что ваша задача не решаема. Просто нужно подойти к решению с другой стороны:
    class DecimalFixedPoint
    {
    public:
    
        static const int denominator = 100; // Affect on precison
        friend std::ostream& operator<<(std::ostream& stdout, DecimalFixedPoint dfp);
    
        DecimalFixedPoint()                  : numerator(0)               {}
        DecimalFixedPoint(int i, bool)       : numerator(i)               {}
        DecimalFixedPoint(int i)             : numerator(i * denominator) {}
        explicit DecimalFixedPoint(float f)  : numerator(f * denominator) {}
        explicit DecimalFixedPoint(double d) : numerator(d * denominator) {}
    
        DecimalFixedPoint operator+(const DecimalFixedPoint& right)
        {
            return DecimalFixedPoint(numerator + right.numerator, true);
        }
    
        DecimalFixedPoint operator-(const DecimalFixedPoint& right)
        {
            return DecimalFixedPoint(numerator - right.numerator, true);
        }
    
        DecimalFixedPoint operator*(const DecimalFixedPoint& right)
        {
            return DecimalFixedPoint(numerator * right.numerator / denominator, true);
        }
    
        DecimalFixedPoint operator/(const DecimalFixedPoint& right)
        {
            return DecimalFixedPoint(numerator * denominator / right.numerator, true);
        }
    
    
    private:
        int numerator;
    };
    
    
    std::ostream& operator<<(std::ostream& stdout, DecimalFixedPoint dfp)
    {
        stdout << dfp.numerator / DecimalFixedPoint::denominator
               << '.'
               << dfp.numerator % DecimalFixedPoint::denominator;
        return stdout;
    }

    Upd.
    В конструкторе DecimalFixedPoint(int i, bool) : numerator(i) {} второй параметр нужен для того, чтоб сигнатура отличалась от конструктора
    DecimalFixedPoint(int i) : numerator(i * denominator) {}
    Если вызывается конструктор с параметром bool, подразумевается, что мы не приводим целое число к нашему типу, а передаём заранее вычисленный числитель нашей дроби. Это, конечно, костыль, но так как такой подход используется в самом стандарте C++ (перегрузка префиксных и постфиксных инкремента/декремента), то совесть моя чиста.
    Ответ написан
    Комментировать
  • Как в конструкторе скопировать все данные в создаваемый объект из объекта того же типа, получаемого из функции в этом конструкторе?

    @Alexander1705
    То, что вы написали, называется делегирующий конструктор. И это работает начиная со стандарта C++11.
    Ответ написан
    Комментировать
  • Для чего нужна передача объекта в функцию по значению и по указателю в С++?

    @Alexander1705
    Указатели действительно не очень востребованы в языке C++, так как в большинстве случаев лучше использовать ссылки. Однако в языке С ссылок нет, и поэтому для совместимости иногда используют указатели.
    Передача по значению создаёт копию передаваемого объекта. Это используется тогда, когда в функции (или методе) вам может понадобится изменить объект, однако эти изменения не должны затронуть тот объект, который вы передавали.

    Например, поиск наибольшего общего делителя:
    int gcd(int a, int b) {
       int c;
       while (b) {
          c = a % b;
          a = b;
          b = c;
       }
       return abs(a);
     }

    В функции изменяются копии переданных объектов, а не сами объекты.
    int a = 16;
    int b = 4;
    gcd(a, b);
    cout << a << ' ' << b; // Выведет "16 4", а не "4 0"


    Upd.1
    Указатели используются в многих структурах данных. Например, связный список:
    template<T> struct LinkedListItem
    {
        T value;
        LinkedListItem* next;
    };

    Значение здесь использовать нельзя, так как объект не может содержать внутри объект того же типа (получается бесконечная рекурсия). Ссылку использовать также нельзя, так как ссылка должна быть сразу привязана к объекту (переменной), а в случае со списком, элементы могут быть добавлены/изменены в любое время.

    Upd.2
    Можно создавать указатели на функции. Функцию нельзя передать по значению или по ссылке.
    #include <iostream>
    
    float f1(float x)
    {
        return 2 * x + 6;
    }
    
    float f2(float x)
    {
        return -3 * x * x + 8 * x - 6;
    }
    
    void printTable(float(*f)(float), float beg=0.f, float end=10.f, float step = 1.f)
    {
        for(float x = beg; x <= end; x += step)
        {
            std::cout << "x = " << x << "\ty = " << f(x) << '\n';
        }
    }
    
    int main(int argc, char** argv)
    {
        printTable(f1);
        printTable(f2);
    }
    Ответ написан
    2 комментария
  • Как сделать звук в программе на си/си++?

    @Alexander1705
    cout << static_cast<char>(7);
    Если серьёзно, то смотрите OpenAL или DirectSound.
    Ответ написан
    1 комментарий
  • Как исправить ошибку в коде на C++?

    @Alexander1705
    Эмм... Что это?
    srand(time(0));
    for (i = 0; i < n; i++)
    {
    C[i] = (double)(rand() % 50) / 10;
    if (C[i] >0)
    {
    p *= C[i];
    ++k;
    }
    }


    P.S. Используйте тэг <code lang="cpp"></code>
    Ответ написан
    Комментировать
  • Конвертация строковых литералов-идентификаторов в числа в compile time?

    @Alexander1705
    #define MSG_ADD_OBJECT 0
    #define MSG_REMOVE_OBJECT 1
    
    int64 a = MSG_ADD_OBJECT; // a = 0
    int64 b = MSG_REMOVE_OBJECT; // b = 1


    Второй вариант:
    enum MSG {ADD_OBJECT, REMOVE_OBJECT};
    
    // Можно использовать два варианта:
    int64 a = ADD_OBJECT; // a = 0
    int64 b = MSG::REMOVE_OBJECT; // b = 1
    Ответ написан
    Комментировать
  • Язык для олимпиадного программирования?

    @Alexander1705
    Python не подойдёт для школьного олимпиадного программирования, так как ваши программы должны будут улаживаться в определённое время. Например, на Всеукраинской ученической олимпиаде по программированию доступны только Pascal, C и C++.

    Учите С++. Я начинал учить именно с него, и хотя возникали некоторые сложности, сейчас ни о чём не жалею, так как теперь легко осваивать любые другие языки, в том числе и Python. На С++ писать не сложно, нужно лишь немного времени, чтоб привыкнуть к синтаксису.

    Могу порекомендовать книгу "Язык программирования С++" Стенли Липпмана.
    Ответ написан
    Комментировать
  • Как динамически вставлять элементы в двумерный вектор?

    @Alexander1705
    for (int i = 0; getline(in, line); i++) {
        matrix.push_back(vector<int>()); // добавляем новую строку
        for (int j = 0; j < line.size(); j++) {
            matrix[i].push_back(line[j]); // в данную строку добавляем элементы.
        }
    };


    Хотя по логике у вас должен быть vector<vector<char>> а не vector<vector<int>>.

    Если у вас на входе числа, делайте так:
    int num;
    for (int i = 0; getline(in, line); i++) {
        stringstream ss(line);
        matrix.push_back(vector<int>()); // добавляем новую строку
        while(ss >> num) {
            matrix[i].push_back(num); // в данную строку добавляем элементы.
        }
    };
    Ответ написан
    1 комментарий
  • В чем различие полиморфизма и перегрузки?

    @Alexander1705
    При перегрузке ты можешь перегрузить функцию для разных количества и типов аргументов, но для каждого случая нужно отдельно определять функцию.
    int plus(int a, int b) {return a + b;}
    float plus(float a, float b) {return a + b;}
    double plus(double a, double b) {return a + b;}
    unsigned long long plus(unsigned long long a, unsigned long long b) {return a + b;}
    // выбьет ошибку для любого другого типа, кроме int, float, double, unsigned long long

    При использовании шаблонов ты определяешь шаблон только однажды, а компилятор сам сгенерирует определение стольких функций сколько потребуется.
    template<typename T>
    T plus(T a, T b) {return a + b;}
    // Работает для любых типов, которые определяют opeator+


    P.S. По сути, и перегрузка и шаблоны это и есть средства полиморфизма.
    Ответ написан
    1 комментарий
  • Как решаются задачи на вероятность?

    @Alexander1705
    Конкретно эту задачу можно решить так:

    И так, у нас p - вероятность нападения разбойников, 0 <= p <= 1. Пускай q - вероятность выйти из леса.
    Рассмотрим какие варианты событий могут произойти и с какой вероятностью:
    1. С вероятностью 0,(3) богатырь выходит из леса.
    2. С вероятностью 0,(6)*p нападают разбойники.
    3. С вероятностью 0.(6)*(1-p) богатырь проходит в другой город. (рекурсивный вариант)

    Так как 3 вариант рекурсивный, он не меняет соотношение вероятностей выйти_из_леса и нападения_разбойников. Значит в итоге соотношение будет 0,(3) к 0,(6)*p, а их сумма будет равна единице.

    Получаем уравнение:
    q / ( 1 - q ) = 0.(3) / ( 0.(6) * p )

    Решаем, получаем следующее выражение:
    q = 0.(3) / ( 0.(6)*p + 0.(3) )
    Ответ написан
    Комментировать