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

    mayton2019
    @mayton2019
    Bigdata Engineer
    Ноль - это хорошо. Отсутствие ошибок. Если ты хочешь возвращать какие-то
    статусные коды из функции main - то ее надо объявить как-то так

    int main(int argc, char **argv) {
       return 555;
    }

    И тогда операционка увидит 555 и можно делать какую-то логику принятия решений. В Windows кажется переменная %errorlevel% отвечает за статусы.
    Ответ написан
    Комментировать
  • Крестики-нолики.Проблемы с ходом Х?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Нет-нет дружище этот код надо выбросить. Переписывать или улучшать его нет смысла. Он плох. У тебя есть координатная сетка. Но ты почему-то не пользуешся этим а вычисляешь какие-то частные случаи.

    Вообще в изучении программирования - копирование чужого кода - это не плохо. Это вполне себе метод. Только скопировать нужно разобравшись как новый код работает. И сравнить его со своим решением. Я тоже так делал когда изучал бейсик для БД1001 или для Sinclair. Я просто копировал всякие текстовые игры-квесты и потом изменял и улучшал их.

    Найди любые крестики-нолики на С++. И в качестве критерия - код должен быть хотя-бы короче чем твой.
    Ответ написан
    Комментировать
  • Что написать на C++ для практики?

    mayton2019
    @mayton2019
    Bigdata Engineer
    У меня периодически возникает одна и таже задача - очень быстро искать нужный текст в логах. Логи большие. Могут быть по терабайту. Россыпь файлов типа

    application/log-2023-02-16-12-30.log
    application/log-2023-01.gz

    Загружать их в эластик - некогда обычно. Тут работа такая что нужно за час разобратсья и логи потом можно
    выкинуть.

    Вот есть сделать предложение - создать утилиту igrep (index-grep) которая при первом пуске - быстро проиндексирует по датам и словам.
    И при полседующих будет искать быстро. И диапазон учитывать например.

    Классический греп не подходит. Он все равно ищет линейно. Не учитывая даты. А мне надо так.

    $ igrep time=-12h level=ERROR Tomcat Network Error
    Вот. Здесь я как-бы захотел поискать все события за 12 часов назад уровня ошибки и содержащие
    два ключевых слова.

    Сами файлы обычно внутри структурированы так. Это почти всегда шаблон.
    2023-02-16T00:00:01,000 [Info] Server started.
    Есть метка времени. Уровень события. И текст события. Много-строчники (стектрейсы) можно соединять в одну строку. О длине самих файлов - ничего не известно. Могут быть от мелких (дневных) до архивов.

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

    UPD.
    Ответ написан
    Комментировать
  • Вопрос по оформлению кода C++?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Вопрос по оформлению кода C++?

    Если делаешь себе пет-проекты или фрилансишь - то безразлично. Делай как читабельно лично
    для тебя. Из best-practices. Старайся уменьшать количество вложенных for/if/else. Для
    уменьшения - делай декомпозицию на функции. И добавляй guard-expressions с выходом
    в return сразу когда какое-то условие выполняется. Часто это уменьшает число вложенной логики.
    break - как аналог guard только для циклов.

    Если ты зашел в корпорацию - то первое что ты увидишь - это тонны легаси кода и корпоративные
    требования (локализованные под проект) о том как надо писать. Конвенции. Соглашения.
    И просто договорняки в команде. Например у нас было такое что в проекте мы после пары
    багов решили писать switch/case с комменарием в секции default ВСЕГДА в том случае
    когда default не содержал логики. Тоесть программист как-бы подтверждал что все
    кейсы учтены и мы ничего не потеряли в проверках.
    switch(weekday) {
      case SAT: 
         onSaturday();
      default:
         // Nothing to do!
    }

    Фигурные скобочки и пробелы обычно подсвечивают корпоративные плагины в IDE с настройками.
    Еще вариант что стиль чекается во время процедур CD/CI и выдает ошибки или предупреждения
    о нарушении стиля. Тоесть сильно упарываться сейчас этим вопросом не стоит. Когда тебя
    прижмет - привычка писать правильно появится очень быстро. За считанные недели.

    Следующий пример цикла - просто неудачен.
    for (int a = 0; a < 10; a++) {
        if (a == 5) {
            break;
        }
        std::cout << "Не то значение" << std::endl;
    }

    Здесь можно доказать что он на самом деле сводится к циклу от 0 до 4. И вообще без проверки внутри.

    Видишь очень важно правильно подбирать учебные примеры.
    Ответ написан
    1 комментарий
  • Как убрать ненужную функцию?

    mayton2019
    @mayton2019
    Bigdata Engineer
    С такими костылями тебе проще свою функцию min написать.

    С макропроцессором - у тебя просто растет цикломатическая сложность самого процесса компилляции. Вот у тебя щас 2 кейса. Есть мин или нет. А потом будет больше кейсов. И потом другой программист, читающий твой код захочет тебя убить :)
    Ответ написан
    4 комментария
  • Как преобразовывать тип данных?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Ремарка по поводу этого кода.
    void division(){
            int divi = static_cast <float> (a) / b;
            if(b != 0){
                cout << divi;
            }
        }

    В расчетах с floating point результат деления 0.0/0 вполне себе определен. Это неопределенность (NaN) и она вполне себе легальна в домене вещественных чисел. Или бесконечность разных знаков (Inf) если только знаменатель равен нулю. По неясным причинам автор отвергает этот результат.
    Более того в ответе будет напечатано

    cout<<"Деление:";

    и тишина. Неясно отработал метод или нет. Это дефект приложения.

    Как бороть такую проблему. В целых числах - никак. Нет легального способа. Я обычно делаю Optional
    std::optional<int> safe_div(int x, int y) {
       .....
    }

    Опционал - это коробочка в которой либо лежит число либо не лежит. Вызывающая сторона соотв
    обязана исполнить протокол вскрытия этой коробочки. Проверить что она непустая.

    Или можно попробовать монаду Either где можно указать причину ошибки.
    Не знаю есть ли это в С++ но должно быть. Во всех нормальных языках должно быть.

    Float/Double - это коварные типы данных. Они доставляют немало хлопот для bigdata. И с ними надо быть
    аккуратными. Главное правило - кастинг из floating point в целые числа в общем случае не работает. Нужно
    думать над отработой исключений всегда. Тоже самое касается диапазонов. Они коварны. И можно терять
    занчимые разраяды на конверсиях. Ответственность за эти действия ВСЕГДА лежит на программисте.
    Ответ написан
    Комментировать
  • Где ошибка в коде переворота двумерного массива?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Ну и хомутов ты тут повесил. Проверь что она переворачивается два раза.
    Ответ написан
    3 комментария
  • Что добавить в код, чтобы текстовая строка прорисовывалась в окне с дополнительным эффектами(Указано ниже с какими, Win 32 C++)?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Тяжелую задачку ты зацепил. Я не знаю есть ли в классическом Win32GDI такие функции чтоб вдоль curve печатать текст.

    Но вот есть пример с печатью под произвольным углом. Попробуй ее приспособить.

    https://learn.microsoft.com/en-us/windows/win32/gd...
    Ответ написан
  • Как сократить код с подпрограмой?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Исходник стартовал с включения заголовка
    #include <iostream>
    Тоесть поднят флаг С++. А дальше идет типичный С-код. Зачем так?
    По идее надо затаскивать vector и лямбды для суммирования.
    Это было бы идеологически правильно.
    Ответ написан
    Комментировать
  • Как сохранить значения нескольких переменных в С++ 17?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Используй пару (pair).

    using namespace std;
    
    pair<int,int> getInfo(int x, int y) {
      return { x+1, y+2 };
    }
    Ответ написан
    6 комментариев
  • Где ошибка? Почему массив выводится в линию?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Кажется вот этот вывод перевода строки стоит не там.
    }cout << "\n";

    Вообще... олимпиадный код где сплошняком идет стена вычислений вперемешку с выводом читать трудно.
    Разбей хотя-бы на 3 функции. Ввод. Расчеты. И вывод результата.
    Ответ написан
    Комментировать
  • Как пару в очередь добавить?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Что такое пара в рамках решаемой тобой задачи? Можно ли это заменить на:
    q.push(x);
    q.push(y);
    Ответ написан
    Комментировать
  • Почему не печатает каждую секунду вывод?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Как-то так надо.
    for (int i = 0; i <= 3; i++) {
            std::cout << i << "..." << std::flush;
            sleep(1);
        };

    (отредактировано)
    Ответ написан
  • Как решить проблему в коде не запускается код, основные операции над бинарным деревом?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Это не бинарное дерево. Ерунда какая-то. Обычно когда объявляют такое дерево -то считают что это
    бинарное дерево поиска. И в нем должны быть функции для расстановки узлов относительно значения Data.

    Здесь что? Непонятно. Рандомным образом раскидали? Зачем?
    Ответ написан
    Комментировать
  • Как учить C++ если будешь знать С?

    mayton2019
    @mayton2019
    Bigdata Engineer
    то с какого аспекта или момента учить C++

    Нет такого момента или аспекта. Просто учишь и все. Языки похожи по синтаксису. Но начиная с каких-то 80х
    годов С++ стал отдельным форком и сегодня это два разных языка которые не должны быть под-множествами
    друг друга. Кроме С++ еще придется изучать и библиотеки STL/Boost и это отдельная тема.
    Ответ написан
    Комментировать
  • В строке все элементы в десятичной системе счисления заменить в шестнадцатеричной системе?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Это - курс молого бойца. Почти всегда первый урок информатики начинается с систем счисления.
    Десятичные. Двоичные. Хекс. Octal. Позиционные. Римская (непозиционная). Унарную можно
    рассмотреть как экзотику. Но имеюшую теоретически большую значимость.

    Работа со строками. Считай вторая лекция по информатике. Вот. Что еще тут добавить.

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

    Я-бы помогал удочкой рыбу ловить. Но готовую рыбу не давал-бы.
    Ответ написан
    Комментировать
  • Почему Clang (с -O3) не векторизует данный цикл?

    mayton2019
    @mayton2019
    Bigdata Engineer
    В первом варианте был массив четверок int или массив 128 битных элементов.
    Во втором случае - два независимых массивка 64х битных элементов которые в памяти
    расположены достаточно далеко и для них скорее всего не нашлось такой векторной
    команды которая-бы адресовалась к паре 64 + 64.
    Ответ написан
    9 комментариев
  • Как узнать размер массива, который был передан в шаблонную функцию?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Передавай вторым параметром size

    auto func(T arr, int size) -> T

    Или договорись сам с собой что в конце каждого массива будет стоять магическое число (-1 например)
    как признак конца.

    int testArr[N] = { 12, 44, 55, 12, 21, 43, 93, 93, 19, 293, 1939 ,1939, -1};
    Ответ написан
  • Почему именно при таком обращении к матрице мы получаем все ее элементы?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Ты работаешь скорее всего не с матрицей а с зубчатым массивом (jagged array). Или его еще называют
    массив массивов. Кстати строки этого массива вовсе не обязаны быть равными. Тоесть не квадрат.
    Их можно делать разного размера. И если смотреть на них сбоку - то получается картинка "зубов".

    *(*(matrix + i) + j)
    в данном выражении идет 2 разыменования. Первый - прыжок на зуб. И второе - прыжок к нужной ячейке
    массива зуба.

    В альтернативном варианте - можно создать просто массив из 100 элементов и доступ получать по формуле

    matrix = new int[100];
    cout << matrix[j + i * 10]


    И этот подход более рациональный с точки зрения менеджера памяти. Мы выделяем 1 кусок а не 10.
    Что вобщем экономит память т.к. аллокатор может резервировать больше памяти чем мы запрашиваем.
    И с точки зрения когерентности по памяти это лучше т.к. мы точно знаем что соседние строки матрицы
    лежат физически рядом а не разбросаны черт знает где.
    Ответ написан
    3 комментария