Данный репозиторий предназначен для Лабораторных работ по дисциплине "Основы Алгоритмизации и Программирования". И, вероятно, в будущем как капсула времени.
- Установка Linux на VMWare Workstation
- Первоначальная настройка и установка необходимого ПО и пакетов
- Задание
- Санитайзеры
- Блок-схемы
- GoogleTest
- Отладка
Особых трудностей здесь у меня не возникло, так как с VMWare Workstation уже был знаком около 4 лет. Выбрал Ubuntu потому что дистрибутивом уже пользовался ранее, да и образ был скачан. У кого-то может возникнуть вопрос "А почему не вторая система?", ответ прост - я привык работать с тем же VSCode, CMake, да и с остальными инструментами разработки на Windows, кроме того мне удобно, когда я могу моментально посмотреть как ведет себя программа на разных системах.
P.S. В последнее время мне всё чаще хочется поставить Linux второй системой, видимо я начинаю становиться человеком.
Естественно самой первой командой было sudo apt update
, ну а дальше поехало
sudo apt install git cmake libgtest-dev -y
- Скачивание VSCode deb файла с официального сайта и установка через
apt
Используя табуляцию и здравый смысл исправил ошибки.
Ранее про санитайзеры ничего не слышал. Обратившись с гуглу я понял, что это антисептик, а ну и ещё инструмент для обнаружения ошибок. Добавляются санитайзеры не сложно.
g++ main.cpp -o main -fsanitize=address
g++ main.cpp -o main -fsanitize=leak
g++ main.cpp -o main -fsanitize=thread
g++ main.cpp -o main -fsanitize=undefined
После компиляции с каждым санитайзером все файлы корректно запускались. Но была проблема, почему-то thread санитайзер выдавал интереснейшую ошибку
FATAL: ThreadSanitizer: unexpected memory mapping 0x5bc8cb71d000-0x5bc8cb71e000
Нашел ответ на StackOverflow (самый дружелюбный форум для программистов). Связано с рандомизацией адресов памяти (ASLR) и решается одной коммандой, правда работает только до перезагрузки системы
sudo sysctl vm.mmap_rnd_bits=30
Но на днях, перед тем как я хотел сдать первую лабу, услышал что нужно доказать наличие санитайзера в скомпилированных файлах. Вспомнил про замечательную команду strings
и отыскал там строку инициализации санитайзера:
__tsan_init
Здесь особо много не скажу. Скачав Visio и прочитав СТП БГУИР 2024-01 составил блок схему.
Найдя документацию и имея базовое знание английского языка нашел Quick start CMake. Вспомнив технику деревни скрытого листа "CTRL+C+C+C CTRL+V" разобрался как устанавливаются и базово работают гугл тесты.
С отладкой в VSCode я был знаком, но услышав про отладку в терминале не на долго впал в ступор. В очередной раз вспомнив про то, как мой друг отлаживал программы на ассемблере в gdb
(земля ему пузом), осознал, что нужно посмотреть гайд. Через 5 минут ютуба уже появились необходимые навыки работы с gdb
.
Посмотрев на количество заданий, я понял: мне не хочется писать тринадцать add_executable()
. Поэтому я использовал for_each()
. Вот сам файл CMakeLists.txt
.
Здесь задания заставили работать мозг, в частности вспомнить что такое математика. Самым сложным заданием оказалось Задание 12, три прекрасных уравнения. Открыв сайт со способами решения данных уравнений засел до 3 часов ночи, но все-таки решил задачу.
Летом 2024 года изучал git по слитому курсу, так что тут проблем особых не было.
Решил создать общий репозиторий ОАиПа и загрузить его на GitHub, но не все так просто. Оказывается, если репозиторий находится внутри другого репозитория, то первый считается подмодулем второго. Из-за того, что в некоторых заданиях были отдельные репозитории, в результате они стали подмодулями. По началу я не придал этому значение, но после того как я решил сделать git push
до меня дошло, подмодули в GitHub это отдельные репозитории которые должны быть загружены. Это меня не устроило, я не хотел забитый GitHub репозиториями отдельных заданий. Перерыв половину интернета, я не придумал ничего лучше, чем переименовать папку .git
внутренних репозиториев на git
.
С самого начала меня заинтересовало меню для каждого задания, так как я уже сталкивался с подобной задачей, у меня появилось виденье таких меню в виде терминала, и этот раз не стал исключением. У любой программы работающей через бесконечный цикл помимо ctrl+c обязана быть команда выхода из программы exit
, так как это терминал, то должна быть команда help
.
~$ help
calc calulate by formula
help commands info
exit exit from program
И команда calc
, которая запускает алгоритм.
Как и во второй лабе, пришлось попотеть с написанием собственного cmath
.
Во время того, как я совершал тщетную попытку сдать 3 лабу, восьмое задание у меня вроде как работало, но только с целыми числами, так как вещественная арифметика запрещена. Послушав советы старшекурсника о том, что мой код должен считать дробные числа и для решения я должен реализовать длинную арифметику, пришел к выводу - мне нужно написать свой вещественный тип. В результате у меня получился bouble
.
Позже оказалось, что вещественные числа не обязательны в данном задании. Но мне всё равно было интересно разобраться как переопределять операторы в языке C++, так что я не считаю это потраченным зря временем.
Придя на второю попытку сдать 3 лабу, первым заданием для всей подгруппы было настроить ssh ключи для GitHub. Ранее я всегда загружал репозитории используя http и токены, которые приходилось где-то записывать и копировать, что было не совсем удобно. Почитав документацию и настроив ssh за 3 минуты, я осознал: пушить на GitHub по ssh это имба вселенского масштаба. После этого я и на винде настроил ssh для GitHub.
Так как в этой лабораторной работе нужно было добавить гугл тесты я решил сделать базовую структуру проекта (также решил, что в последующих лабах тоже буду её делать):
LR4
├── build
├── CMakeLists.txt
├── include
│ └── tools.h
├── src
│ ├── Task_1
│ │ └── main.cpp
│ ├── Task_2
│ │ └── main.cpp
│ ├── Task_3
│ │ └── main.cpp
│ ├── Task_4
│ │ ├── LR4_4.vsdx
│ │ └── main.c
│ ├── Task_5
│ │ ├── LR4_5.vsdx
│ │ └── main.c
│ └── Task_6
│ ├── LR4_6.vsdx
│ └── main.c
└── test
└── gtest.cpp
В чем суть? У меня есть файл tools.h
, в котором я писал функции с алгоритмами для всех заданий и которые тестируются с помощью файла gtest.cpp
. И естественно tools.h
подключается через #include "tools.h"
, папка include считается каталогом подключаемых файлов, определена таковой в CMakeLists.txt
На этот раз половина заданий была написана на C. Поэтому в CMakeLists.txt
два for_each()
, первый для C++ и второй для С.
Ну и опять же услышал: нужно доказать, что Задание 4, 5 и 6 компилируются именно как C, а не C++. То, что CMake при сборке пишет Building C object
мне было не достаточно, поэтому я решил снова воспользоваться strings
и нашел строки:
GNU C17 13.2.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection # в .c файле
GNU C++17 13.2.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection # в .cpp файле
Это как раз доказывает, что .с файлы были скомпилированы как C.
Тестирование запускается через CMake. Составил по 3 теста на каждое задание.
Интересная задача. Естественно алгоритм я сам не писал, я не гений.
Взял три алгоритма с трёх сайтов. Для нечетных квадратов сайтов полным-полно, для четно-четных тоже достаточно, ну а с четно-нечетным у меня возникли небольшие трудности. Через пол часа я все таки нашел сайт с четно-нечетным алгоритмом, но я взял код для Java и переделал его под C.
Разобравшись в том как работают алгоритмы, я начал делать блок-схему для магического квадрата, в результате для четно-четного и четно-нечетного получилось две сардельки.
Дочитав условие задачи до конца, я понял: для магического квадрата 2^32 - 1 порядка мне ОЗУ не хватит. Решил сделать все возможное и слегка оптимизировал код, например для четно-нечетного квадрата выделялся лишний динамический массив.
Так как у меня виртуалка, я скопировал код на винду и решил проверить на что способна моя оперативная пямять. Понахватавшись Segmentation fault
, винда начала "немного" плохо себя чувствовать, в частности начали моргать элементы меню. Чинилось все фиксиками перезагрузкой. В конечном итоге, максимум, который я смог выжать - 40000-ый порядок.
Прочитав начало 5 лабы, у меня возник вопрос, а на какой ОС делать лабу? Путём современных инновационных технологий - телеграмма, выяснил у Вадима Денисовича, что лаба делается на Windows. На винде у меня как раз все инструменты необходимые для лабы были установлены.
Здесь используется такая же структура проекта.
Библиотеки собирал через Visual Studio. По сути первое и второй задание у меня полностью на вижле. Разве что скомпилированная динамическая библиотека потом используются для тестирования через CMake.
Задания 3, 4 и 5 собираются CMake-ом. Для CMake Build используется MSVC.
С какой-то стороны мне 5-ая лаба показалась легче чем 4-ая. Задания 3, 4 и 5 такие же, как и в 4 лабе, а посмотреть видео и разобраться как компилировать библиотеки особых трудностей не вызывает.
Гугл тесты так же организованы, как и в 4 лабе, тоже по 3 штуки, но краевые.