Задать вопрос
  • Почему не работает перемещение в 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?

    Ответ на вопрос из заголовка - смотри требования в вакансиях на 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 комментарий
  • Как убедиться что атомарные операции будут выполнены точно правильно?

    mayton2019
    @mayton2019
    Bigdata Engineer
    В данном исходнике нет проблемы атомиков. Но здесь есть проблема отсутсвия синхронизации потоков а и b.
    Нужно наладить синхронизацию и дальше атомики станут приносить ощутимую пользу.
    Ответ написан
    Комментировать
  • Как получить адрес памяти переменной в массиве, а не адрес индекса массива?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Все правильно: выводится адрес элемента в массиве. Они два не совпадают, потому что в figure_collection лежит копия line, со своим уникальным адресом в памяти.

    Edit: и вы через массив к исходному line никак не обратитесь, только если не смените тип массива на Figure*
    Ответ написан
    Комментировать
  • Почему вызывается исключение при считывании информации из файла?

    У вас переменная size в main не инициализирована. В ней находится мусор. А вы создаете массивы размера size.
    Ответ написан
    3 комментария
  • Как преобразовывать тип данных?

    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 в целые числа в общем случае не работает. Нужно
    думать над отработой исключений всегда. Тоже самое касается диапазонов. Они коварны. И можно терять
    занчимые разраяды на конверсиях. Ответственность за эти действия ВСЕГДА лежит на программисте.
    Ответ написан
    Комментировать
  • Почему нет доступа к приватному атрибуту?

    У вас оператор является private членом класса. А надо public. О чем и говорит компилятор.
    Ответ написан
    3 комментария
  • Не получается вернуть строку. Как исправить?

    @res2001
    Developer, ex-admin
    1. Лучше бы вы использовали std::string, а не нативные ("сырые") строки.
    2. Нативные строки - это не строки в привычном для С++ смысле (и в смысле интерпретируемых ЯП). У них нет встроенных операций типа конкатенации, выделения подстрок и т.п. Все это реализуется функциями в стиле Си str*
    3. Если вы хотите вернуть сырую строку, то надо:
    3.1. Массив под строку выделять в динамической памяти (или передавать его как параметр в функцию и его заполнять). Сейчас у вас автоматический массив, а он исчезнет, как только отработает оператор return и строка по факту не вернется (хотя вернется указатель, но он будет указывать в место на стеке, в котором уже нет вашей строки).
    3.2. Возвращать char*. Сейчас тип возвращаемого значения в вашей функции char - а это один символ, а не строка.
    4. Размер строки явно будет больше, чем size байт. На сколько больше - нельзя сказать заранее. Поэтому обычно выделяют достаточно большой буфер с запасом, чтоб покрыть все возможные варианты и при добавлении в буфер очередной подстроки контролируют размер буфера - чтоб оставалось место для очередной добавляемого куска и завершающего нулевого символа. Строка может быть равна size только в случае, если все числа в массиве будут состоять из одной десятичной цифры. Да и в этом случае требуется дополнительный байт на нулевой символ. Так что минимальный размер буфера должен быть size+1, реально он должен быть еще больше.
    Ответ написан
    Комментировать
  • Как отдать строку?

    @dima20155
    you don't choose c++. It chooses you
    Если под строкой имеется в виду EffRange - тогда return его.
    Если std::string нет простого пути, так как это не имеет смысла (сложение obj+obj возвращает строку в половине случаев, а в половине obj?)
    Пишите дополнительный метод.
    Также operator+, обычно, возвращает ссылку на объект
    Ответ написан
    2 комментария
  • Аварийное прекращение создания объекта из класса, который является родителем?

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

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

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

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

    Ну какая разница, как у вас там переменная называется sA или sB - результат будет один и тот же.

    Да, может вы путаетесь, но аргумент в функции можно тоже переменовать. Хоть там и написано int masivA(int* a), этот a - это аргумент. Он никак не привязан к массиву a в main(). Туда можно передать и a и b и любой другой массив.
    Ответ написан
    4 комментария
  • Как вставить элемент в строку после определенного условия?

    find_first_of() возвращает либо позицию, либо string::npos. То есть будет срабатывать почти всегда (кроме первого элемента строки). Правильно: if (find_first_of(...) != string::npos).
    Ответ написан
    Комментировать