
Лига программистов C/C++
Книга по C++, которую ты обязан прочитать в 2025 году
Я почему-то уверен, что она у тебя уже есть. Либо в списке литературы для самообразования, либо где-то среди скачанных pdf, а может, даже в печатном виде. Возможно, ты даже начинал её читать, но… работа, таски, собеседования… деньги вроде и так платят… и ты так и не осилил Мейерса "Эффективный и современный С++".
А ведь именно эта книга — ключ, который поможет тебе пробить потолок уровня middle и начать движение к senior.
Да, можно скачать список из 400 популярных вопросов, выучить их и бодро ответить на вопрос: «Расскажи про std::unique_ptr». А потом тебе прилетает дополнительный вопрос: «А как изменится размер std::unique_ptr при использовании пользовательского удалителя?» Иии… Я не буду додумывать твой уровень знаний. Попробуй сам ответить на этот вопрос и поставь себе оценку🙂
И это только один из примеров тонких нюансов, которые описаны в этой книге и которые реально спрашивают на собеседованиях.
Ещё одна сильная сторона книги: почти каждая фича современного C++ иллюстрируется примерами её использования в реальном проде. А это большая редкость для технической литературы.
Хватит откладывать эту книгу на «потом». Поставь цель на этот год и, наконец-то, найди время, чтобы прочитать 300 страниц "Эффективного и современного С++".
Скрытие программы из панели задач
Привет всем ребятам с пикабу! Сегодня столкнулся с проблемой, что мне нужно было сделать так, чтобы я вводил PID процесса, или хотя-бы имя самого процесса, вместо имени окна чтобы скрыть, или показать его в панели задач. Пробовал сам - не получилось. Спросил ChatGpt - нерабочая тарабарщина. Просьба помочь чем сможете, буду благодарен любому совету!
Вот сам код: #include <windows.h>
#include <iostream>
#include <string>
int main()
{
int choice;
std::string programName;
HWND hwnd;
std::cout << "Choose an option:\n";
std::cout << "(1) Hide Window\n";
std::cout << "(2) Show Window\n";
std::cin >> choice;
std::cin.ignore();
switch (choice) {
case 1:
std::cout << "Enter the Window Name to hide: ";
std::getline(std::cin, programName);
hwnd = FindWindowA(NULL, programName.c_str());
if (hwnd == NULL) {
std::cout << "Program not found." << std::endl;
return 1;
}
ShowWindow(hwnd, SW_HIDE);
std::cout << "Window '" << programName << "' was hidden." << std::endl;
break;
case 2:
std::cout << "Enter the Window Name to show: ";
std::getline(std::cin, programName);
hwnd = FindWindowA(NULL, programName.c_str());
if (hwnd == NULL) {
std::cout << "Program not found." << std::endl;
return 1;
}
ShowWindow(hwnd, SW_SHOW);
std::cout << "Window '" << programName << "' is now visible." << std::endl;
break;
default:
std::cout << "Invalid option selected." << std::endl;
return 1;
}
return 0;
}
Помогите с шифрованием на C++
Столкнулся сегодня с проблемой. Мне нужно сделать так, чтобы когда консоль была открыта, то у меня там отображался мой текст TriggerBot и AimAssist, а в памяти оно бы шифровалось. Пример: в консоли у меня есть "анимация" TriggerBot, но когда я сканирую память (к примеру с помощью Process Hacker или Cheat Engine), то в поиске строк в памяти вместо "TriggerBot", у меня бы там писалось к примеру hhajhfgdsghf==. Я сначала думал об VMP Protect, но решил, что он мне практически не поможет, поэтому решил обратиться к вам. Просьба помочь чем сможете, буду благодарен любому за помощь. Вот код:
#include <iostream>
#include <windows.h>
void fadeInText(const std::string& text) {
for (int i = 0; i <= 10; ++i) {
std::cout << "\r";
for (int j = 0; j < i; ++j) {
std::cout << text[j];
}
Sleep(50);
}
}
void fadeOutText(const std::string& text) {
for (int i = 10; i >= 0; --i) {
std::cout << "\r";
for (int j = 0; j < i; ++j) {
std::cout << text[j];
}
Sleep(50);
}
std::cout << "\r";
}
int main() {
std::string aimAssist = "AimAssist";
std::string triggerBot = "TriggerBot";
while (true) {
fadeInText(aimAssist);
Sleep(1000);
fadeOutText(aimAssist);
fadeInText(triggerBot);
Sleep(1000);
fadeOutText(triggerBot);
}
return 0;
}
Сборка MS-DOS 4.0
Автор текста: dlinyj
Совсем недавно появилась следующая новость: На GitHub опубликован исходный код MS-DOS 4.00 под лицензией MIT. Раз появились исходные коды, стало сразу интересно: а можно ли собрать эту операционную систему?
Задача оказалась нетривиальной и совсем неочевидной. Оказывается, что исходные файлы DOS не так-то уж и легко переносятся в git, и уж как минимум, не как текстовые файлы в кодировке UTF-8. Но, к счастью, в отличие от утечек исходников MS-DOS 6.0, здесь имеется полный комплект файлов и инструментов, достаточный для корректной сборки и тестирования. Остались сущие нюансы, которые попили много крови.
Поэтому я, как и многие — начал свои эксперименты по сборке MS-DOS 4.0, с исправлением ошибок, а также возможностью исследования исходных кодов и тестирования их на реальном железе.
В статье же изложено краткое руководство по сборке и созданию загрузочной дискетки.
❯ Инструментарий
Собирать всё буду в Linux Mint (читай Ubuntu). Средой DOS для сборки выбрал dosbox, к сожалению, это не самый лучший вариант, потому что там идёт замедление частоты (чтобы старые программы корректно работали), поэтому сборка идёт достаточно долго. Лучше всего использовать любой удобный DOS, запущенный в виртуальной машине.
Для создания загрузочной дискеты и тестирования полученной сборки буду задействовать виртуальную машину qemu. А чтобы получить дискеты с готовым образом, я буду использовать установочную дискету MS-DOS 4.0 (найденную тут см. 4.00 OEM [Sampo]).
Прежде чем пойдём дальше — важное замечание:
Никаких чужих прав задеть не собираюсь, все модификации кода были сделаны исключительно в юмористических целях, и не подлежат распространению. Модифицированные исходники удалены.
❯ В чём сложности сборки?
Проблемы две:
Некорректная инициализация переменных среды (в самом bat-файле SETENV.BAT содержится ошибки или опечатки).
Проблемы с кодировкой при переносе кода с дискеток DOS в GIT с кодировкой UTF-8.
Первая проблема легко исправляется даже самостоятельно, при беглом анализе исходного кода. Она легко вскрывается при сборке, дальше просто необходимо внести правки, либо создать свой обновлённый bat-файл, который будет инициализировать переменные среды окружения.
Значительно сложнее обстоят дела с тем, что в части кода, при переносе в UTF-8, побились некоторые символы. У меня была попытка сборки, которую я описывал у себя в ЖЖ, и, в конце концов, я получил вот это:
Это достаточно частая и болезненная проблема со старыми исходниками времён DOS. С аналогичной задачей я столкнулся и при попытке собрать программу RAM View. Об этом пути и исправлении проблемы, я подробно написал в статье Правка чужого кода.
Здесь же мы исключим ручной труд и автоматизируем исправление проблем с кодировками.
❯ Подготовительные операции перед сборкой
Итак, шаги по сборке ДОС. Клонируем оригинальный репозиторий:
git clone https://github.com/microsoft/MS-DOS.git
Исправляем проблемы с кодировками:
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/MAPPER/GETMSG.ASM
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/SELECT/SELECT2.ASM
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/SELECT/USA.INF
Переходим в рабочую папку:
cd MS-DOS/v4.0
Перекодируем все текстовые файлы в формат MS-DOS:
find -iname '*.bat' -o -iname '*.asm' -o -iname '*.skl' -o -iname 'zero.dat' -o -iname 'locscr' | xargs unix2dos -f
find -iname '*.BAT' -o -iname '*.ASM' -o -iname '*.SKL' -o -iname 'ZERO.DAT' -o -iname 'LOCSCR' | xargs unix2dos -f
и создаём там обновлённый бат-файл для переменных среды окружения, следующего содержания:
$ cat src/e.bat
@Echo off
echo setting up system to build the MS-DOS 4.01 SOURCE BAK...
set CL=
set LINK=
set MASM=
set COUNTRY=usa-ms
set BAKROOT=e:
rem BAKROOT points to the home drive/directory of the sources.
set LIB=%BAKROOT%\src\tools\bld\lib
set INIT=%BAKROOT%\src\tools
set INCLUDE=%BAKROOT%\src\tools\bld\inc
set PATH=%BAKROOT%\src\tools;%PATH%
В принципе этих операций достаточно для сборки, а то что ниже — это лично моё хулиганство, чтобы продемонстрировать, что DOS в действительности собрался, и нет подмены файлов. Я заменяю компанию Microsoft своим ником:
find -name "*.ASM" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.INC" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.H" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.MAC" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.MSG" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.C" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.CLB" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.SKL" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
Всё, теперь исходники подготовлены, для того чтобы их можно было корректно собрать.
❯ Сборка
Собирать буду в dosbox, как показала практика — это не самое лучшее решение, сборка занимает около часа, что, мягко скажем, раздражает.
Запускаю dosbox:
dosbox
Далее в нём монтирую текущую директорию как диск E.
mount e: ./
И переходим на диск e, запускаем в dosbox бат-файл, который инициализирует среду окружения, и начинаем сборку:
e:
cd SRC
e.bat
и запускаем сборку командой nmake:
Если вы делаете это в dosbox, то можно пойти погулять. Окончанием сборки будет выглядеть следующим образом:
После этого надо скопировать все собранные файлы в один каталог. Создаём каталог «4» в корне диска и копируем все бинарники специальным скриптом:
mkdir \4
CPY.BAT \4
Далее самое интересное:проверка того, что файлы запускаются. Для этого надо сделать так, чтобы dosbox прикидывался старым ДОСом. Выполняем следующую команду:
ver set 4.0
После переходим в каталог\4и можно выполнить в нёмcommand.com:
Хулиганство сработало, ДОС собрался и прикидывается, будто бы я его разработал. Дело стало за малым — протестировать это на реальном железе.
❯ Создание загрузочной дискетки
Дальше я думал просто примонтировать в dosbox пустой образ дискетки, и прямо из собранных файлов выполнить перенос системных файлов командой:
sys <path> a:
Но, факир был пьян, и фокус не удался. Поэтому решил MBR (Master Boot Record) позаимствовать с загрузочной дискетки DOS 4.0. К сожалению, MBR от MS-DOS 6.22 у меня не заработал.
Скачиваем установочные дискетки, попутно создаём пустую дискетку командой:
truncate --size 1474560 fdd.img
Загружаемся с установочной дискетки и ставим наш пустой образ 1,44 МБ дискетки в дисковод B, с помощью qemu:
qemu-system-i386 -fda Disk01.img -fdb fdd.img
Отменяем установку и форматируем дискету с переносом системных файлов:
По окончании можно закрывать окно qemu. Возвращаемся к окну с dosbox и монтируем полученный образ дискетки, с помощью следующей команды:
imgmount a: <path to fdd.img> -t floppy
И потом просто вручную переносим файлы COMMAND.COM, IO.SYS и MSDOS.SYS на дискету:
Всё, образ готов. Можно его протестировать в виртуальной машине, или даже записать на настоящую дискету и загрузиться!
Для запуска в qemu следует использовать следующую команду:
qemu-system-i386 -fda fdd.img
Записать на дискетку можно командой dd, я использую USB-FDD дисковод.
sudo dd if=fdd.img of=/dev/sdk status=progress
И, да! Эта система успешно работает на реальном железе. В данном случае проверка идёт на 386 компьютере.
❯ Выводы
Не буду лукавить, сборка MS-DOS 4.0 оказалась не столь простой. Пришлось посмотреть некоторые видео, пошерстить различные репозитории. Но всё же это прекрасный опыт, который позволяет заглянуть внутрь исторических исходников и покопаться в них.
Давняя утечка MS-DOS 6.0 была неполной, и собрать его не представлялось возможным. А теперь у исследователей есть готовый инструментарий, для того чтобы попрактиковаться в разработки каких-то своих модулей старой операционной системы.
Конечно же, я по-настоящему жду, когда же обнародуют исходники MS-DOS 6.22, так как ещё надеюсь увидеть их на своём веку.
Удачи вам в ваших экспериментах!
❯ Полезные ссылки:
Написано специально для Timeweb Cloud и читателей Пикабу. Подписывайтесь на наш блог, чтобы не пропустить новые интересные статьи.
Облачные сервисы Timeweb Cloud — это реферальная ссылка, которая может помочь поддержать наши проекты.
Проблема с подключением библиотек
Всем привет, я тут совсем новенький, хотел бы войти в программирование на C++, сначала изучив C.
Для этого я поставил Eclipse(хз какой именно, скачал во flathub) и Code Blocks через терминал с оф.сайта (хотелось бы в дальнейшем пользоваться только Eclipse).
ОС у меня, к слову, linux Ubuntu 22.04, но хакером меня это не сделало от слова совсем.
В общем, возникла проблема с подключением сторонних библиотек(или правильнее headers, я хз) в обоих IDE, когда я хотел заменить мс-досовскую conio.h на родную curses.h или ncerses.h
такие получились пироги в Eclipse:
gcc linker:
gcc compiler:
а вот, что внутри ncursesw:
что об этом думает Code::Blocks:
если пытаюсь подключить другие библиотеки, тоже не работает:
Последняя программа на С++ тоже не запускается.
При попытках подключения типа #include <../../../../usr/include/ncursesw/ncurses.h> тоже беда.
Хотя, если переписать код в блокнот и запустить в терминале, то всё работает:



Подскажите как мне быть с IDEшками.
Ещё хотелось бы найти здесь неравнодушного человека, который бы помогал в случаях, когда возникают трудности. Напишите в комментах, кто готов.
Админы, не удаляйте пост пппжжжжж, я думаю новичкам будет полезно...
Почему игнорируется условие IF
Привет всем. Прошу помочь знающих людей. Пробую немного разобраться в программировании микроконтроллеров на С++. Создал программу тестера батареек. Функция Void loop состоит по сути из трех условий:
1) если напряжение на батарейке больше 1,6 в то горит зеленый светодиод (newLed),
2) если от 1,4 до 1,6в, то горит желтый светодиод (okLed),
3) и все остальное - горит красный (oldLed).
Загрузке в ардуину происходит немного другое. Программа начинает бесконечный цикл и , даже без подключения проверяемой батарейки)загорается красный (ну это понятно, т.к. нулевое напряжение соответствует третьему условию), но далее программа возвращается к первому условию и загорается зеленый светодиод. И так бесконечно происходит игнорирование условия IF, по которому зеленый светодиод включается только когда более 1,6 в.
#define newLed 2
#define okLed 4
#define oldLed 6
int analogValue = 0;
float voltage = 0;
int ledDelay = 2000;
void setup()
{
pinMode(newLed,OUTPUT);
pinMode(okLed,OUTPUT);
pinMode(oldLed,OUTPUT);
}
void loop()
{
analogValue = analogRead(0);
voltage = 0.0048*analogValue;
if (voltage >= 1.6)
{ digitalWrite(newLed, HIGH);
delay(ledDelay);
digitalWrite(newLed, LOW);
}
else if(voltage < 1.6 && voltage > 1.4)
{
digitalWrite(okLed, HIGH);
delay(ledDelay);
digitalWrite(okLed, LOW);
}
else
{
digitalWrite(oldLed, HIGH);
delay(ledDelay);
digitalWrite(oldLed, LOW);
}}
_______________________________
кстати такое поведение ардуины заметил не только в этой программе. Там где программы состоят из условий IF постоянно игнорируется первое условие (оно постоянно выполняется). При загрузке скетча в симулятор Arduino в интернете пограммы работают корректно. В чем может быть дело?
SayoriOS или о том, как мы пишем свою мини ОС
Небольшое предисловие
Мы пишем ос чисто как хобби, в свободное от всего время, как есть возможность, или как говорят еще "не являемся убийцами Windows и Linux", просто примите это как кто-то коллекционирует разные вещи или рисует картины. А также это мой первый пост на подобных ресурсах как Пикабу. Благодарю.
Почему называется именно SayoriOS?
Это является отсылкой к игре Doki Doki Literature Club, там был один из персонажей, к сожалению, те кто играл в игру поймут более глубокую отсылку.
Как все начиналось?
Кто заглянет к нам на GitHub, может заметить что отсчет идет с версии v0.2.13.1, дело в том что все до версии v0.3.0 было основано на другой ос (её, версию кстати после нашего релиза (v0.2.13.1) удалили), с версии v0.3.0 было проделано множество работы, прошло уже больше года и я хочу вам рассказать чего мы добились за это время.
На каком языке программирования вы пишете ОС?
Решение использовать C было принято в основном из соображений простоты, программирование ядра само по себе достаточно сложная задача. Не все языки программирования предназначены для использования в среде без ядра/ядра, в этом отношении C идеально подходит для задач такого рода. Меньше борьбы с языком за то, чтобы он работал в среде ядра, означало больше внимания к реальному проекту.
Почему вы пишете именно x86 битную версию, а не x64?
Ограничение себя 32-битной версией x86 также было намеренным и опять-таки во имя простоты. x86_64 намного сложнее, чем 32-разрядный x86, и мы (команда) хотели сначала получить некоторый опыт работы с последним, прежде чем переходить к 64-разрядному режиму.
Немного о действующих лицах
Никита Пиминов - собственно я, как создатель и инициализатор проекта
Андрей Павленко - второй разработчик, написал почти все драйвера для ос
Дима Радеев - добавил поддержку звука ошибок
Даниил Лебедев - добавил поддержку Rust в ядре
Рустем Гимадутдинов - добавил поддержку мыши PS/2
А теперь перейдем к краткому ChangeLog'у
v0.3.0 - Релиз 09.11.2022



Скриншоты версии v0.3.0
Как я и говорил ранее, самое большое обновление было тут.
У нас наконец-то тогда появилась поддержка потоков, можно было выполнять сразу два дело одновременно, но тогда очень ощутима потеря производительности. Для драйвера клавиатуры мы завезли поддержку русских букв, что и сейчас, что и до этого, смена раскладки находиться на F1. Самое интересно тогда было связанно с файлами, было сделано что-то подобие своей файловой системы, и аналог своего формата изображений Duke.
v0.3.1 - Релиз 16.12.2022



Скриншоты версии v0.3.1
У этого релиза, визуальных отличий почти не было, была добавлено поддержка мыши, благодаря Рустему Гимадутдинову, пофиксили большинство предупреждений, добавили поддержку дробных чисел, а также вернули поддержку ELF.
v0.3.2 - Релиз 02.04.2023
В этой версии ситуация уже по лучше :) Опять же исправили множество багов (и добавили новых)
Появилась поддержка нормальных шрифтов PSF
Поддержка PCI
Поддержка звука через AC97 (в QEMU работает в нормально, в VBox'e заикается ,а на реальном железе не тестировалось)
Обновили местами интерфейс
Добавили Parallel Desktop - это прототип рабочего стола
v0.3.3 - Релиз 08.10.2023



Скриншоты версии v0.3.3
У этого релиза, также визуальных отличий почти не было, были только небольшие фишки
Добавлена система триггеров (событий)
Поддержка setjmp/longjmp
Поддержка температуры процессора
Первые шаги ACPI
Поддержка SSE
Определение других процессорных ядер
Научились работать с жесткими дисками, IDE PIO, ATAPI Дисководы, а также с Floppy (RW)
Добавлена поддержка vsprintf(), sprintf(), asprintf(), vasprintf()
Ну и пофиксили некоторые моменты, и некоторые другие фишки
v0.3.4 - Релиз 31.12.2023







Скриншоты версии v0.3.4
Это был наш предновогодний релиз, и вот список изменений:
Наконец, новый менеджер памяти, со старым были большие проблемы, и именно он создавал большинство багов в ос
Исправили детектор имени процессора, раньше выводилась пустота
Исправлена работа на видеокартах с Cirrus
Добавлена поддержка IDE-дисков (в режиме DMA) и частичная поддержка SATA
Переписали полностью, функционал который отвечал за файлы, теперь этим занимается менеджер файловых систем и дисков (nvfs | dpm | fsm)
Туда же подключили все устройства (виртуальный диск, диски, floppy)
Удалили sefs (был наш аналог файловой системы) и аналог Targa, заменив собственно TarFS + Targa (с 4ю режимами)
Добавили базовую поддержку libstring и libvector
Добавили проигрыватель miniplay (Воспроизводит wav файлы)
Добавили поддержку JavaScript (port elk) => JSE
Начата работа над сетью
Добавлен эмулятор GameBoy, правда производительность у него очень низкая.
Буду рад обратной связи!
Благодарю всех за внимание!
Ссылка на GitHub: https://github.com/pimnik98/SayoriOS
Мы в VK: https://vk.com/sayorios
И телеграм: https://t.me/sayorios
В соц.сетях, можете найти мемы касаемо разработки, и сами новости.
Всех с наступившим Новым Годом и наступающим Рождеством.