======Заметки по С/С++====== =====Инициализация переменных===== // Привычная инициализация double value1 = 3.14; // C++11, инициализация фигурными скобками не позволяется неявное преобразование. double value2 = {3.14}; double value3 {3.14}; // uniform initialization // Ошибка компиляции, при несовпадении типа: int value4 = {3.14}; int value5 {3.14}; // C++11, AUTO - автоматический вывод типа при инициализации auto value = 3.14 // double =====Константы===== // Константы времени компиляции - значения известны на момент компиляции const double myConst1 {1}; // предпочтительнее использовать const перед типом данных int const myConst2 {2}; // Допустимо в С++, но лучше использовать вариант 1 // C++11, Явное объявление константы времени компиляции, чтобы компилятор не выводил constexpr int myConst3 {3}; constexpr int myConst4 = myConst1 + myConst2 + myConst3; // Константа времени исполнения - не известна при компиляции int age; std::cin >> age; const int usersAge (age); // Указатель на константу const int *pConstValue; const int constValue = 3; pConstValue = &constValue; // Константный указатель на переменную int varValue; int *const pVarValue = &varValue; // Возвращает указатель на символ, который нельзя менять const char∗ strchr(const char∗ p, char c); // Константа в параметрах функции показывает, что переменная не будет изменяться внутри функции void printInteger(const int age) { std::cout << age; } // enum - Набор именованных целочисленных констант enum day {sun, mon, tue, wen, thu, fri, sat}; enum number {a=54, b, c=60, d=c+5}; // Макрос (СИ), минусы: // - не отображается при отладке // - глобальная область видимости // - не указан явно тип #define MAX_COUNT 10 При программировании микроконтроллеров константные данные могут лежать в памяти ROM/FLASH. Поэтому программа не может их менять физически, а может лишь читать. Ссылки: [[https://evileg.com/ru/post/254/|"EVILEG: C++ - Урок 003. Константы"]] =====Перечисления, ENUM===== // Глобальная видимость значений enum MyColors { Red, Green, Blue } int activeColor = Blue; // С ограниченной областью видимости - MyColors enum class MyColors { Red, Green, Blue } int activeColor = MyColors::Blue; MyColors activeColor = MyColors::Blue; // Задание типа для хранения значения enum class MyColors : char { Red, Green, Blue } Ссылки: [[https://evileg.com/ru/post/279/|"EVILEG: C++ - Урок 008. Перечисления"]] =====Массивы===== // Объявление массива const int N = 8; constexpr int Square(int n) { return n * n; } int arr[N]; int arr_sqr[Square(N)]; // Инициализация массива int arr[3] = {1, 2, 3}; // обычная int arr[] = {1, 2, 3}; // с выводом длины int arr[3] {1, 2, 3}; // С++11, uniform initialization // Объявление типа - массив typedef int ArrInt4_t[4]; // обычное using ArrInt4_t = int[4]; // С++11 // Получаем аналоги: ArrInt4_t a, b; int a[4], b[4]; // Размер int a[4]{ 4, 3, 2, 1 }; sizeof(a) // 16,размер массива в байтах std::size(a) // 4, количество элементов в массиве (С++17) // C++11, Сортировка с помощью std::begin() и std::end() std::sort(std::begin(a), std::end(a)); ===C++11, Range-For-Statement=== // 1 - Значение каждого элемента массива копируется в x и выводится int arr[] = {0,1,2,3,4,5,6,7,8,9}; for (auto x : arr) cout << x << '\n'; for (auto x : {10,21,32,43,54,65}) cout << x << '\n'; // 2 - Обращение к элементу по ссылке (вместо копирования) - позволяет менять элемент for (auto& x : arr) ++x; // increment for (const auto& x : arr) cout << x << '\n'; // Предпочтительней, если менять элемент не нужно // Работает с контейнерами имеющими .begin() и .end() vector v; for (int i = 0; i < 10; ++i) v.push_back(i + 3.1415); for( const auto &j : v ) cout << j << " "; std::map MAP({{1, 1}, {2, 2}, {3, 3}}); for (auto i : MAP) std::cout << '{' << i.first << ", " << i.second << "}\n"; ===Вместо массивов СИ рекомендуется использовать класс-контейнер std::array, С++11.=== // std::array - объявление с инициализацией std::array a{1, 2, 3, 4}; for (int i = 0; i < a.size(); ++i) std::cout << a[i] << ' '; for (auto it = a.begin(); it != a.end(); ++it) std::cout << *it << ' '; for (auto t : a) std::cout << t << ' '; // std::vector<> - вместо динамического массива **std::array** - это оболочка над массивом в стиле Си, но с сохранением длины массива. //(Если в функцию передавать обычный массив СИ, то теряется информация о длине и ее необходимо передавать дополнительным параметром - передается только указатель. Тоже самое при экспорте массива в глобальное пространство. При использовании std::array "потери" длины не происходит, длина хранится в объекте.)// * Если std::array создается внутри функции, то массив аллоцируется в стеке. Необходимо разумно использовать небольшой размер стека - не выделять массивы больше нескольких килобайт! * Если std::array объявлен вне функции, то он аллоцируется в статической памяти. std::array совместим с алгоритмами STL! **std::vector** - динамический массив, аллоцируется в куче - может менять длину в процессе исполнения программы Ссылки: * [[https://evileg.com/ru/post/265/|"EVILEG: C++ - Урок 005. Указатели, Массивы и Циклы"]] * [[https://habr.com/ru/post/495444/|"Habr: Массивы в C++"]] =====Как пропустить строку при разборе текста функцией sscanf (СИ)===== Необязательный символ подавления присвоения "*": scanf() считывает входные данные в соответствии со спецификацией преобразования, но отбрасывает входные данные. Соответствующий аргумент указателя не требуется, и эта спецификация не включается в число успешных назначений, возвращаемых scanf() Например scanf("%*s") используется пропуска комментариев в коде драйвера Linux для 1923KX028: rd_cnt = sscanf(core_buff, "--- Scheduler 1 settings: ---\n%*s" "Scheduler algo type: %d\n" "Sch2 input to which Sch1 is going: %d\n" "Weight queue of Sch2 input which Sch1 is going: %d\n" "--- Scheduler 2 settings: ---\n%*s" "Scheduler algo type: %d\n", &shed0_algor, &shed0_pos, &shed0_weight, &shed1_algor ); Можно вычитывать текст построчно, параметр **%n** вернет указатель чтения в буфере: uint8_t i; uint8_t doClear; for (i = 0; i < lines_count; i++) { rd_cnt = sscanf(&core_buff[rd_pos], "Queue weight: %hhd\n%n", &doClear, &rd_pos); if (rd_cnt == 1) { // нашлась строка по шаблону // делаем что хотим с doClear break; } }