Все потоки
Поиск
Написать публикацию
Обновить
179.82

C++ *

Типизированный язык программирования

Сначала показывать
Порог рейтинга
Уровень сложности

Поделить нельзя — умножить или алгоритм быстрого деления по методу Ньютона-Рафсона

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров14K


Все мы в школе проходили деление «столбиком» — простой алгоритм, который несложно реализовать, вот только не очень быстрый. В прошлый раз мы рассматривали, как компилятор оптимизирует деление в случаях, когда делитель известен во время компиляции, но применение его напрямую, чтоб оптимизировать деление для делителей, определямых в run-time, невозможно: вычисление констант сдвига и умножения само по себе требует деления.

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

Дружим iPhone и ESP32. Часть 1. ESP Arduino Core

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров4.9K

В данной части статьи я простым языком поведаю вам о том, как написать собственный BLE сервис на микроконтроллере ESP32 для дальнейшего управления непосредственно с iPhone, а так же раскрою пару фишек, благодаря которым вы сохраните себе своё время и нервы.

Читать далее

Чистый код: Принцип открытости закрытости (OCP)

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров6.5K

Принцип открытости/закрытости гласит, что программные объекты (классы, методы, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации.

Идеальной реализацией данного принципа является интерфейс. Ничего лишнего, нечего модифицировать, можно только расширять.

Читать далее

В поисках оптимальной модели итераторов

Время на прочтение7 мин
Количество просмотров3.9K

В процессе разработки мини-библиотеки файлового ввода я изучал код реализации функций/методов работы с файлами в стандартных библиотеках различных языков программирования, в том числе и Rust.

Глаз зацепился за реализацию итератора чтения файла по строкам. Для реализации итератора в Rust достаточно определения всего одной функции next()!
Это маленькое открытие сподвигло меня к изучению того, как реализованы итераторы в других языках программирования.

В данной статье я поделюсь результатами этого небольшого исследования, а также представлю новую модель итераторов, которую я планирую сделать основной для языка 11l, и которую можно уже сейчас использовать в C++ проектах посредством простого адаптера (вот пример использования).
Читать дальше →

История POSIX: путь к портируемому ПО

Время на прочтение8 мин
Количество просмотров8.8K

В ранние годы развития компьютеров программисты могли лишь мечтать о портируемости. Все программы писались непосредственно в машинном коде для каждой компьютерной архитектуры, на которой они должны были работать. Языки ассемблера с мнемоническими именами каждой команды CPU и другие удобства сильно упростили жизнь программистов, но программы по-прежнему были привязаны к архитектуре. Тогда ещё не изобрели операционных систем, поэтому программа не только управляла всей компьютерной системой, но и должна была инициализировать всю периферию, а также управлять ею. На самом деле, такие низкоуровневые программы реализовывали драйверы для каждого используемого ими устройства. И каждый раз, когда программу нужно было перенести на оборудование с другой архитектурой, она в буквальном смысле переписывалась с учётом различий архитектуры набора команд CPU, структуры памяти и так далее.

Именно так произошло с Unix, который изначально был написан Кеном Томпсоном на языке ассемблера более пятидесяти лет назад. Первые версии Unix писались для платформы PDP-7, а для портирования его на PDP-11 нужно было переписывать код. Когда Дэннис Ритчи создал язык программирования C, и вместе с Томпсоном они переписали на нём основную часть кода Unix, внезапно оказалась возможной портируемость ПО. Тому были две главные причины. Во-первых, код, написанный на языке высокого уровня, не зависит от платформы, потому что компиляторы транслируют его в язык ассемблера целевой архитектуры. Это ещё важнее для целевых платформ на основе процессоров RISC, так как они требуют написания гораздо большего количества ассемблерных команд, чем процессоры CISC. Даже при портировании Unix на другую платформу основная сложность заключалась лишь в адаптации зависящих от архитектуры частей кода. С другой стороны, сама операционная система абстрагирует все особенности оборудования от пользовательской программы.

Программистам не нужно реализовывать многозадачность, управление памятью и драйверы для используемых ими устройств, потому что всё это часть ядра ОС и работает в адресном пространстве ядра. Пользовательские программы работают в пользовательском адресном пространстве и получают доступ ко всем предоставляемым ОС функциям при помощи интерфейса системных вызовов. В ОС реального времени, например, в Zephyr OS ситуация немного отличается, но принцип изоляции и защиты памяти для пользовательских программ сохраняется. Это приводит к двум выводам:

Читать далее

3D рендер с редактором карт в Консоли (Часть 2)

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров3.1K

Сегодня я собираюсь продолжить рассказ про свой 3D рендер в командной строке Windows и разобрать те темы, которых не коснулся в 1 Части.

На этот раз в статье будет больше кода и меньше математики (а также много скриншотов).

Читать далее

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

Уровень сложностиСредний
Время на прочтение15 мин
Количество просмотров6.3K

Знаете, я никогда не задумывался, насколько плоха или хороша инициализация переменных в языке C++. Я просто использовал ее. И не имел никаких проблем. Но недавно я посмотрел пару видео, пролистал несколько статей и да, я должен признать… она действительно ужасна. Один очень серьезный человек даже сказал, что мы, как сообщество программистов, виновны в том, что C++ не настолько хорош, насколько он мог бы быть.

Ну ладно, давайте включим воображение и посмотрим, что мы могли бы изменить, чтобы улучшить данную ситуацию. Тех, кто уже понял о чем речь, сразу хочу успокоить. Слишком глубоко в эту кроличью нору мы не полезем. Разберем лишь то, с чем сталкивается каждый, а также гипотетические способы наведения во всем этом какого-то минимального порядка.

Читать далее

Устройство системы чит-кодов в The Simpsons: Hit & Run

Уровень сложностиСредний
Время на прочтение13 мин
Количество просмотров1.1K

Приветствую всех мододелов и интересующихся!

Сегодня я хочу обсудить внутреннее устройство системы чит-кодов в The Simpsons: Hit & Run 2003.

Статья будет разбита на 4 части, в первых трех из которых будет обсуждаться устройство самой системы чит-кодов, а в заключительной четвертой части будет рассказано, как добавить свои чит-коды в игру.

Читать далее

Гарри Поттер и имя типа в компайлтайм

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров3.3K

Пару лет назад я написал статью про получение имен элементов enum в моих любимых плюсах без использования typeid, макросов и черной магии, а то и вообще в компайлтайм. Хотя нет, немного магии там все же было. Это был интересный опыт, но особого применения в проде я так и не нашел, хотя коллеги начали активно использовать эту возможность чтобы итерироваться по enum в поисках нужного элемента по его строковому представлению. Оно конечно задумывалось наоборот, но как говорится, пасту в тюбик обратно не запихнешь, пользуются и то радость. И тут в домашнем игровом движке мне понадобился похожий функционал получения имени структуры или класса в компайлтайм, можно конечно было сделать через typeid, но в релизной сборке rtti планируется отключать, так что этот вариант не подходит. А конвертировать имя структуры в строку все же хочется. При чем тут Гарри и для чего это все нужно в конце статьи.

Wingardium Leviofa

Как извлечь данные из Linux с помощью C++ и Qt. На примере приложения с прогнозом погоды

Уровень сложностиСредний
Время на прочтение10 мин
Количество просмотров7K

Привет, Хабр! Меня зовут Михаил, я backend-разработчик в SimbirSoft. Хочу поделиться с вами опытом получения различной информации в ОС Linux для использования в своих целях.

Представьте, что нам нужно написать приложение «Погода», которое берёт из сети температуру, влажность и прочие параметры и отображает для пользователя. Было бы неплохо, чтобы оно само определяло, где мы находимся. Но как это сделать? Легко!

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

- навигационные данные (долготу, широту, высоту);

- сведения о сетевом соединении (название, тип, уровень сигнала Wi-Fi);

- заряд батареи;

- информацию о хранилище (сколько занято/сколько всего).                                                                  

Стек используемых технологий – C++ в связке с библиотекой Qt (5.12). Задача казалась довольно простой. Но первое впечатление очень часто обманчиво. Особенно в тех случаях, когда вам не приходилось решать подобные задачи. Но обо всём по порядку. Рассмотрим вывод разных видов информации.

👉 Читать далее

Система управления памятью в The Simpsons: Hit & Run 2003

Уровень сложностиСредний
Время на прочтение17 мин
Количество просмотров2.8K

Привет!

Сегодня я хотел бы обсудить систему управления памятью в игре The Simpsons: Hit & Run 2003. Статья будет состоять из двух частей, в первой из которых будет обсуждаться само использование такой системы управления памятью, а во второй будет рассказано о внутреннем устройстве этой системы.

Читать далее

3D рендер с редактором карт в Консоли (Часть 1)

Уровень сложностиСредний
Время на прочтение13 мин
Количество просмотров6.9K

Привет!

Сегодня я опишу в подробностях , как я писал полноценный рендер с редактором карт в командной строке без каких-либо графических библиотек. В этой статье я объясню те идеи и математические модели, которые использовались мной при создании данных программ с минимальными вставками кода.

Читать далее

Работа с кодом на C++ в Swift

Время на прочтение9 мин
Количество просмотров2.6K

Привет, Хабр! Меня зовут Иван Мясников, я CTO проекта «Виртуальный ассистент» в МТС Диджитал. Встраивание кода С++ в приложения для iOS — достаточно трудная задача. Еще сложнее собрать SDK для дальнейшей поставки в сторонние приложения, используя логику на С++ совместно со Swift. В этой статье я расскажу, как мы создавали такой SDK так, чтобы он встраивался в любое приложение без танцев с целевой архитектурой процессора.

Встраивание C++ в Swift позволяет использовать один код на разных платформах и ускорить некоторые задачи, где Swift не хватает быстродействия. У нас есть библиотека на C++ для работы с ML на Tensorflow Lite. И эту библиотеку мы хотели встроить на Android, iOS, Linux под различные платформы и архитектуры процессора без переписывания логики оттуда на Kotlin, Swift или что-нибудь еще. В этой статье я расскажу, как мы заставили код на C++ работать в iOS и какие тут есть тонкости и ограничения. Я ориентировался на читателей, у которых может не быть экспертизы в iOS или в C++, и старался не погружаться в глубокие дебри. Этот материал познакомит с решениями, к которым мы пришли экспериментально, подбирая подходящие варианты под нашу задачу.

Читать далее

Ближайшие события

Видео экстензометр

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров1.7K

В 2010 году я начал работать в одной небольшой компании по производству испытательных машин (машины для физико-механических испытаний на растяжение, сжатие), там я в основном занимался разработкой программного обеспечения для управления испытательными машинами, а также сбором и анализом полученных данных.

Читать далее

Чистый код: Принцип единственной ответственности (SRP)

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров6.8K

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

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

Читать далее

Logger C++

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров11K

Этот проект представляет собой простую и гибкую библиотеку для логирования на C++. Библиотека поддерживает разные уровни логирования, форматирование сообщений и возможность записи логов в разные потоки.

Читать далее)

Конструкторы, деструкторы, операторы — частые практики при программировании на C++

Уровень сложностиСредний
Время на прочтение16 мин
Количество просмотров9.2K

Данная статья служит шпаргалкой при написании классов с различными перегрузками операторов на примере тривиального класса строки (и ещё нескольких). Описанное здесь позволяет избежать копирования кода из одного конструктора или оператора в другой, что значительно снижает вероятность появления ошибок, но может привести к незначительному уменьшению производительности.

Читать далее

Пилим движок Arcanum. Урок 02. Работа с файлами игры, рисуем первый спрайт

Уровень сложностиПростой
Время на прочтение9 мин
Количество просмотров4.6K

В данном уроке, я опишу формат архивов игры, напишу код, для загрузки файлов и выведем первый спрайт. Я расскажу и покажу, как движок работает с файлами, загружает графику и рисует спрайты игры. Так же расскажу о тестых для игры, которые ускоряют написание кода и его изменение.

Читать

strlcpy, или как CPU противоречат здравому смыслу

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров17K

Один из моих старых постов о strlcpy недавно вызвал обсуждения на различных форумах. Вероятно, с этим как-то связан выпуск новой версии POSIX. Многие авторы приводили один контраргумент, который я слышал и раньше:

«В общем случае, когда исходная строка умещается в конечный буфер, strlcpy будет обходить строку только один раз, а strlen + memcpy будут обходить её дважды».

Под этим аргументом скрывается допущение о том, что однократный обход строки выполняется быстрее. И, честно говоря, это вполне разумное допущение. Но справедливо ли оно? Об этом мы и поговорим в статье.

Читать далее

Что значит инициализировать int в C++?

Уровень сложностиСредний
Время на прочтение10 мин
Количество просмотров16K

Недавно я получил по почте от Сэма Джонсона этот вопрос. Вот слегка отредактированное письмо Сэма:

«Возьмём для примера этот код в локальной области видимости функции:

int a;

a = 5;

Многие люди считают, что инициализация происходит в строке 1, потому что веб-сайты наподобие cppreference дают такое определение: "Инициализация переменной предоставляет его начальное значение на момент создания".

Однако я убеждён, что инициализация происходит в строке 2, потому что [в разных хороших книгах по C++] инициализация определяется как первое существенное значение, попадающее в переменную.

Можете ли вы сказать, какая строка считается инициализацией?»

Отличный вопрос. На Cppreference написано правильно, и для всех классовых типов ответ прост: объект инициализируется в строке 1 вызовом его стандартного конструктора.

Но (а вы ведь знали, что будет «но») для локального объекта фундаментального встроенного типа наподобие int ответ будет... чуть более сложным. И именно поэтому Сэм задал этот вопрос, ведь он знает, что язык достаточно свободно обращается с инициализацией таких локальных объектов по историческим причинам, имевшим в то время смысл.

Короткий ответ: вполне допустимо говорить, что переменная получает своё исходное значение в строке 2. Но заметьте, что я намеренно не сказал «Объект инициализируется в строке 2», к тому же и код, и этот ответ обходят молчанием более важный вопрос: «Ну ладно, а что, если код между строками 1 и 2 попробует считать значение объекта?»

Читать далее

Вклад авторов