Самопроверка

Вопрос 36. Определите константу через макрос.

Вопрос 37. Используя возможности препроцессора, напишите макрос, который принимает два числа и возвращает их сумму.

Вопрос 38. Зачем нужны «защитные скобки» в заголовочном файле?

Вопрос 39. В каком случае стоит использовать модификатор volatile?

Вопрос 40. Как вы знаете, ключевое слово static позволяет создать переменную в статической области памяти, т. е. память под переменную выделяется до входа в main(). Что будет, если данный модификатор применить к локальной переменной внутри функции?

Вопрос 41. Чем хороша и чем плоха рекурсия?

Вопрос 42. Что делает ключевое слово register?

Вопрос 43. Как создать трехмерный массив в стеке?

Вопрос 44. Чем массив строк хуже массива указателей на строки?

Вопрос 45. Используя структуру, определите тип комплексного числа (оно содержит мнимую и реальную часть).

Вопрос 46. Почему от использования goto стоит отказаться?

Вопрос 47. Стоит ли использовать стандартную библиотеку во встраиваемых системах? Если да, то когда это уместно?

Все задачки в данном разделе достаточно простые, и их не так много (чтобы не раздувать книгу — это всё же не задачник по программированию). Если вам хочется порешать что-то посложнее, обратите внимание на сайты с олимпиадными задачами: они, как правило, содержат автоматическую систему проверки кода. Например, советую обратиться к сайту Timus Online Judge. На сайте gowrikumar.com в разделе C Puzzle собраны головоломки, характерные для языка Си.

Если до этого моменты вы не программировали, можно пройти два интерактивных курса на hexlet.io: «Введение в программирование»; и «Введение в Си». Они, однако, не относятся ко встраиваемым системам.

Задача 1. Создайте функцию, принимающую два целочисленных числа uint32_t и возвращающую их разность.

Задача 2. Используя тернальный оператор, перепишите следующий участок кода:

if (adc > 17)
BOOST_ON();
else
BOOST_OFF();

Задача 3. Числа Фибоначчи — это ряд чисел, в котором каждое последующее число описывается суммой двух предыдущих: 1, 1, 2, 3, 5, 8 и т.д. Рассчитать n-е число можно по формуле:

Fn = Fn-1 + Fn-2

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

Задача 4. Перепишите функцию поиска числа Фибоначчи, используя рекурсию.

Задача 5. Промышленность не выпускает резисторы и конденсаторы произвольных номиналов, а используют так называемый E-ряд. Наиболее распространенный ряд — E24. Напишите функцию, которая принимает значение от 1,0 до 9,9 и в ответ выдает наиболее близкое значение из этого ряда.

float e24_get(float value) {
static const float e24[] = {
1.0f, 1.1f, 1.2f, 1.3f, 1.5f,
1.6f, 1.8f, 2.0f, 2.2f, 2.4f,
2.7f, 3.0f, 3.3f, 3.6f, 3.9f,
4.3f, 4.7f, 5.1f, 5.6f, 6.2f,
6.8f, 7.5f, 8.2f, 9.1f,
};
// ...
return value;
}

Для примера: допустим, мы рассчитали для некоторого делителя напряжения номиналы 10,3 кОм и 14,7 кОм. Тогда резисторы, которые мы сможем купить в магазине согласно этому ряду, будут номиналами 10 и 15 кОм соответственно.

Задача 6. На вход функции uint32_t check(char ch) приходит буква. Если это буква a, то функция возвращает 2. Если это буквы b, c или z, то возвращается цифра 7. В остальных случаях возвращается число 42. Напишите такую функцию.

Задача 7. Напишите функцию, которая меняет местами значения двух переменных (с использованием дополнительной). Помните, что в функцию можно передавать аргументы как по значению, так и по адресу.

Задача 8. Одним из часто встречаемых и нужных алгоритмов является сортировка элементов массива. За долгое время было придумано множество алгоритмов с разной производительностью и требованиям к памяти. Попробуйте реализовать алгоритм сортировки пузырьком. Его описание также можно найти на Википедии.

Задача 9. Наряду с выбором алгоритма, на производительность сильно влияет и структура данных, которую выбирает программист. Подобные структуры довольно часто входят в состав стандартных библиотек языка, но поскольку мы не будем использовать стандартную библиотеку во встраиваемой системе, иметь реализацию структуры весьма полезно. Разработайте модули для работы с двусвязным списком (англ. linked list), стеком и очередью. Подробное их описание можно найти на Википедии.


Изменено:

Язык Си: 6 комментариев

  1. >Вместо нуля может быть почти любой другой символ. Плюс и минус работают по-другому. Для выравнивания числа по по левому краю, а не по правому, перед числом нужно поставить знак минус.
    Лишне по

  2. Термин «регистр ядра» довольно специфичен. Звучит не привычно. А почему не использовать термин CPU или процессор или на худой конец микроконтроллер?

  3. Смысл статических переменных вне функции мне кажется не раскрыт. Такой модификатор делает переменную недоступной из других единиц трансляции. Т.е. не будет конфликта имен между разными .с файлами.

  4. #ifdef STM8
    ind.i = 250;
    #elif STM32
    ind.j = 1027;

    Точно #elif ? Что-то мне подсказывает, что здесь должно быть либо #else #ifdef STM32, либо просто #ifdef STM32

  5. «printf(«a\t: 10\n\r»);
    printf(«ab\t: 11\n\r»);
    printf(«abc\t: 12\n\r»);
    // a___: 10
    // ab__: 10
    // abc_: 10″

    Не понял, почему 10 в выводе в каждой строке?

  6. «Для вывода чисел с плавающей запятой приведённые выше опции так же работают, но добавляются и другие. Например, если нам нужно ограничиться выводом сотых, нужно написать точку и цифру 2. При чём обратите внимание число будет округлятся в большую сторону.

    float pi = 3.1415926;
    printf(«%.0f\n\r», pi); // 3
    printf(«%.1f\n\r», pi); // 3.1
    printf(«%.2f\n\r», pi); // 3.14
    printf(«%.3f\n\r», pi); // 3.142
    printf(«%.4f\n\r», pi); // 3.1416″

    В то же время:
    «printf(«%.1f\n\r», pi); // 3.1
    printf(«%.2f\n\r», pi); // 3.14″

    Насколько я вижу, округление происходит по математическим правилам, в том числе при округлении пятерки. Где ошибка: в примере или в описании?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

This site uses Akismet to reduce spam. Learn how your comment data is processed.