Задать вопрос
Ответы пользователя по тегу C++
  • Как программно работать с USB веб-камерой в Linux использую C/С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нужны библиотеки. Гуглите v4l2, pipewire.
    Напрямую с драйверами или тем более свой драйвер с USB протоколами вы писать замучаетесь.
    Ответ написан
    2 комментария
  • Возможно ли присвоить «ничего» в ссылку?

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

    В вашем коде 2 проблемы. = default; можно писать, если у вас нет никакого списка инициализации. И константную ссылку нельзя использовать для инициализации неконстантной.

    Вот такой код компилируется:
    template<typename T>
    struct Test
    {
        T& ref;  // нужно присвоить null
    
        Test(T& _ref) : ref(_ref) {};
    };
    Ответ написан
    3 комментария
  • Как использовать целое число с размером больше чем 64 бита в C++?

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

    Если надо делить нацело или брать по модулю маленького числа (<64 бит), то тоже элементарно - один цикл по цифрам числа.

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

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

    1) Используйте std::vector<std::array>.

    2) Что-то среднее между двумя вариантами у вас: как и везде, у вас есть одномерный массив для данных. А operator[] на классе возвращает int* на первый элемент в строке. То же, что у вас, только не надо никакого вспомогательного класса. Таким образом двойная индексация будет работать как надо. Но, как и во втором упомянутом вами примере, тут не будет проверки выхода за границы массива.
    Ответ написан
    Комментировать
  • Всё ли в порядке с данным блоком?

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

    Во-первых, он не компилируется. У вас там названия переменных кое где из двух слов состоят (А в других местах те же переменные с '_' идут - явно кто-то ошибся при перепечатывании текста).

    Во-вторых, тут подход немного через пятую точку. Не нужна вам строка из алфавита. Чтобы получить случайный символ, можно случайное число от 0 до 25 прибавить к 'a' - ведь символы в C++ - это целочисленные переменные, хранящие ASCII коды букв. B вот дизайнеры этих кодов были довольно умные дяденьки, поэтому английский алфавит идет там по порядку одним блоком.
    Ответ написан
    Комментировать
  • Сокращение функций в си++?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    На выбор: std::initializer_list, variadic arguments, variadic templates.

    Примеры по ссылкам есть. Последнее - вообще оверкилл, и в вашем случае вообще не нужно. Советую использовать initializer_list.
    Ответ написан
    1 комментарий
  • Как реализовать приоритетную очередь с функциями extractMax и add, которая поддерживает одинаковые элементы?

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


    Если нумерация массива идет с 1, то два ребенка элемента i будут 2*i и 2*i+1. У вас же нумерация с 0, т.ч. у вас дети - 2*i+1 и 2*i+2.

    Первое условие достигается правильной расстановкой строгого и нестрогого неравнества в условиях в алгоритме.

    Похоже, проблема в том, что у вас нумерация с 0 и, если новый элемент оказывается итак максимальным, вы вернете индекс 0, вместо нужного 1. Если вы элемент вниз просеиваете, то у вас там +1 стоит в res.first, но изначально у вас-то там 0.

    Далее, вы вектор неправильно используете. Вы делаете reserve и потом работаете с пустым вектором, как-будто он фиксированного размера. Вам надо делать resize вместо reserve. Или еще лучше, вместо вашей переменной size вы используйте arr.size(). При изменении размера массива делайте pop_back() и push_back().
    Ответ написан
    8 комментариев
  • Ошибка в конструкторе при передаче массива c++?

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

    Вот так работает:
    int data[] = {90, 90};
    Array<int, 3> arr (data);


    Ну не может компилятор по Array<int, 3> arr { 90,90 }; догадаться, что {90, 90} - это числа в массиве, адресс которого надо передать.

    Кстати, у вас тут ошибка: Array вы создали на 3 элемента и копируете 3 элемента, а данных задали только 2.
    Ответ написан
  • Почему неправильно решает задачу?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Небольшое замечание: можно код сильно ускорить, применяя математику. Можно взять все номера букв по модулю 26, тогда a=1, ... y=25, z=0. Тогда операция будет - умножение на 2 и взятие по модулю 26 (для 'a' все также выдаст 'b', для 'z' все так же выдаст 'z'). До этого можно додуматься, потому что вот это вот "вычитание 26" - ну очень похоже на операцию взятия по модулю 26.

    Применение этой операции 2024 раза равносильно умножению на 2^2024 по модулю 26. Воспользовавшисть теоремой эйлера, это равносильно умножению на 2^(2024 % 12) = 2^8 = 128. Далее, умножение на 128 по модулю 26 равносильно умножению на 24.

    Т.е. можно умножать один раз на 24 вместо 2024 умножений на 2 (и в конце взять по модулю 26).
    Ответ написан
    Комментировать
  • Как сделать скрин на C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    На винде? Кроме gdi+ можно ещё через directx (гуглите dxgi duplicator) или через windows graphics capture api. Но последние 2 не работают в старых системах.

    Если же вам только посмотреть на несколько пикселей, то можно и в gdi+ делать скриншот лишь маленькой части, или вообще ничего не копировать и смотреть на цвет пикселей в экранном DC.
    Ответ написан
    1 комментарий
  • Как получить случайные числа в C++?

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

    srand устанавливает состояние генератора псевдослучайных чисел. В качестве seed вы там используете количество миллисекунд, которое целую миллисекунду одинаковое, поэтому состояние генератора у вас в каждой функции rand_offer одно и то же - поэтому числа и генерируются одни и теже. sleep(1) лечит проблему потому, что следующий вызов посчитает другое значение count_ms.
    Ответ написан
    Комментировать
  • Таблица истинности С++. Почему здесь разные результаты?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    ( x == z) || (!x || (y && z)) == 0 означает ( x == z) || ( (!x || (y && z)) == 0 ).
    Приоритет у сравнения выше, чем у ||, которое, по идее, есть лишь часть считаемого выражения. Поэтому у вас полечается не "выражение == 0" а "выражение1" или "выражение2 == 0".
    Возьмите все ваше выражение в скобки и все заработает.

    Во втором куске кода у вас 2 отдельных выражение сравнивается с 0 и скобочки у вас там расставлены правильно.
    Ответ написан
    1 комментарий
  • Как реализовать операторы в классе математического вектора?

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

    Вектора можно перемножать. Скалярное или вектороное произведения. Чаще скалярное ставят на operator*, а векторное на какое-нибудь operator^

    Операторы сравнения обычно делают лексикографически, покомпонентно. Сравнили первое число - у какого вектора больше - тот и больше. Если числа равны, сравниваем вторые компоненты. И т.д. Но это делают редко, потому что смысла вектора сортировать особо нет. Лексикографический порядок пользы особо не приносит.
    Ответ написан
    9 комментариев
  • Как сделать чтоб одна вункция роботала всегда а другая паралельно каждую секунду?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    {
      thread gameThread(game_loop, ref(star_pleced), ref(staircase_placed), ref(c), ref(t_placed), ref(r_placed), ref(p_placed), rows, cols, ref(map));
      thread monsterThread(monster_move, ref(map));
      gameThread.join();
      monsterThread.join();
      refresh();
    } while ((c = getch()) != '0');


    Этот код запускает потоки (они один раз исполняются) потом ждет их завершения. И это в цикле.
    Проблема в том, что на каждой итерации этого цикла вы будете ждать, пока monster thread спит.

    Потоки тут вообще бесполезны, вы с тем же успехом можете просто вызвать функции напрямую.

    Потоки должны быть запущены один раз и работать в фоне. Тот, который каждую секунду что-то делает, должен внутри содержать цикл и работать бесконечно, на каждой итерации засыпать на 1 секунду.
    Ответ написан
    Комментировать
  • Как исправить ошибку -nan(ind) в С++?

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

    Другая опасность в вашем коде: логарифм отрицательных чисел. Закомментируйте log в вашем выражении, если результат где-то отрицательный - функцию в этом значении x тупо не вычеслить - оно вне области определения.
    Ответ написан
  • Возможна ли гонка данных при отправке их на сокет?

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

    Вот эта часть кода, что по вашему делает? Почему sendto возвращает количество байт, а не код ошибки?

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

    Это связано с тем, что сокеты работают на низком уровне и не гарантируют сохранение порядка отправленных данных. Когда два приложения отправляют данные одновременно, они могут перемешиваться в процессе передачи по сети и приходить в произвольном порядке.


    А это очередная галлюцинация ГПТ. Забудьте эти слова - они не имеют ничего общего с реальностью.

    Попробуйте строки ваши сделать побольше - в пару миллионов символов, вот тут-то вам мешанина и будет приходить.
    Ответ написан
    4 комментария
  • Входит в бесконечный цыкл,как исправить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    После while (collision && try_counter <= 100); вставьте:
    if (try_counter > 100) break;

    Добавьте отладочный вывод в каждый цикл - посмотрите, а в каком же цикле оно висьнет-то.
    Вам еще понадобиться try_counter в цикл по монстрам (while (map[py][px] != ' ')).

    А вообще, очень странный цикл вот:
    do
            {
                center_y = ry + (r_size_y / 2);
                center_x = rx + (r_size_x / 2);
            } while (map[center_y][center_x] != ' ');


    Тут явно какая-то ошибка, потому что center_x и center_y на каждой итерации получатся одинаковые и цикл или сразу закончится, или повиснет.
    Ответ написан
  • Возможно ли избежать ошибку чтения в массиве если алгоритм задействует ячейку которой нет?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Для игры "жизнь" есть несколько вариантов:
    1) Увеличить поле на 2 клетки по каждому измерению, поле будет храниться с 1, а индексы 0 и n+1 - всегда будут пустыми. Потребление памяти это почти не увеличит, а код упростит.
    2) Если соседние клетки считаются циклами, то можно границы области 3x3 пересечь с полем:
    for (int nx = max(0, x-1); nx < min(x+2, n); ++nx) {
      for (int ny = max(0, y-1); ny < min(y+2, n); ++ny) {
        if (nx == x && ny == y) continue;
        // {nx, ny} - сосед в поле, обрабатываем его.
      }
    }

    Можно код чуть ускорить, предподсчитав границы.
    3) Более читаемый, но чуть более медленный метод - явно проверять, а не за границей ли соседняя клетка:
    for (int nx = x-1; nx <= x+1; ++nx) {
      for (int ny = y-1; ny <= y+1; ++ny) {
        if ((nx == x && ny == y) || nx < 0 || ny < 0 || nx >= n || ny >= n) continue;
        // {nx, ny} - соседняя клетка.
      }
    }


    Я бы просто раздул поле - так код сильно проще.

    Но вотрой метод так легко реализуется только тут, где нужно именно количетсво живых соседей и можно просто игнорировать клетки вне поля.
    Ответ написан
    Комментировать
  • Консоль игра, попадает в бесконечный цикл,что тут не так?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы случайным образом генерируете координаты комнаты в цикле, пока вам не повезет выбрать полностью пустое место (while (collision == true);).

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

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

    Еще можно сделать немного по другому - вместо случайного выбора места и потом проверки на пересечение, найдите все места, куда комнату можно впихнуть и из их списка выбирайте случайное одним rand(). Тут уже не будет цикла, завершающегося только когда вам повезло. Но тут тоже может быть проблема, что мест для размещения новой комнаты вообще нет. Или перезапускайте с нуля расстановку комнат, или требуйте, чтобы они были маленькие. Еще можно их ставить в порядке от больших к маленьким.
    Ответ написан
    2 комментария