Macros в C: Пособие для начинающих

Здравствуйте, будущие программисты! Сегодня мы окунемся в fascинирующий мир макросов в C. Не волнуйтесь, если вы никогда не писали ни строчки кода — я буду вашим доброжелательным проводником в этом путешествии. К концу этого руководства вы будете удивлены, сколько вы узнали!

C - Macros

Что такое макросы?

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

Объектные макросы

Давайте начнем с simplest формы макросов: объектных макросов.

Определение и синтаксис

Объектные макросы определяются с использованием директивы #define. Вот базовый синтаксис:

#define MACRO_NAME value

Примеры

Давайте рассмотрим несколько примеров:

#define PI 3.14159
#define MAX_STUDENTS 100
#define SCHOOL_NAME "Coder's Academy"

В этих примерах, whenever компилятор видит PI, он заменит его на 3.14159. Точно так же MAX_STUDENTS будет заменен на 100, а SCHOOL_NAME на "Coder's Academy".

Использование в коде

Теперь давайте посмотрим, как мы можем использовать эти макросы в нашем коде:

#include <stdio.h>

#define PI 3.14159
#define MAX_STUDENTS 100

int main() {
float radius = 5.0;
float area = PI * radius * radius;

printf("Площадь круга равна: %.2f\n", area);
printf("Наша школа может вместить %d студентов.\n", MAX_STUDENTS);

return 0;
}

Когда вы запустите эту программу, она выведет:

Площадь круга равна: 78.54
Наша школа может вместить 100 студентов.

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

Функциональные макросы

Теперь давайте поднимем уровень и рассмотрим функциональные макросы. Это макросы, которые выглядят как функции, но работают немного по-другому.

Определение и синтаксис

Синтаксис для функциональных макросов следующий:

#define MACRO_NAME(parameters) (macro_body)

Примеры

Вот несколько примеров:

#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

Использование в коде

Давайте используем эти макросы в программе:

#include <stdio.h>

#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
int num1 = 5, num2 = 7;

printf("Квадрат %d равен %d\n", num1, SQUARE(num1));
printf("Максимальное из %d и %d равно %d\n", num1, num2, MAX(num1, num2));

return 0;
}

Эта программа выведет:

Квадрат 5 равен 25
Максимальное из 5 и 7 равно 7

Обратите внимание, как SQUARE(5) заменяется на ((5) * (5)), а MAX(5, 7) заменяется на ((5) > (7) ? (5) : (7)) перед компиляцией программы.

Цепочечные макросы

Цепочечные макросы occur, когда один макрос использует другой макрос в своейdefinitions. Это как macro inception!

Пример

#define SQUARE(x) ((x) * (x))
#define CUBE(x) (SQUARE(x) * (x))

Здесь CUBE использует SQUARE в своей definitions. When вы используете CUBE(3), он сначала expands к (SQUARE(3) * (3)), а затем further expands к (((3) * (3)) * (3)).

Вариадические макросы

Вариадические макросы super cool, потому что они могут принимать переменное количество аргументов. Они как швейцарские армейские ножи среди макросов!

Синтаксис

#define MACRO_NAME(args...) macro_body

Пример

#include <stdio.h>

#define DEBUG_PRINT(format, ...) printf("Debug: " format "\n", ##__VA_ARGS__)

int main() {
int x = 5;
float y = 3.14;

DEBUG_PRINT("x = %d", x);
DEBUG_PRINT("x = %d, y = %.2f", x, y);

return 0;
}

Это выведет:

Debug: x = 5
Debug: x = 5, y = 3.14

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

Предопределенные макросы

Язык C предоставляет несколько内置 макросов, которые могут быть真的很 полезны. Вот несколько из них:

Макрос Описание
__FILE__ Текущее имя файла
__LINE__ Текущий номер строки
__DATE__ Дата компиляции
__TIME__ Время компиляции
__STDC__ 1, если компилятор соответствует ANSI C

Пример

#include <stdio.h>

int main() {
printf("Этот файл %s\n", __FILE__);
printf("Это строка %d\n", __LINE__);
printf("Скомпилировано %s в %s\n", __DATE__, __TIME__);
return 0;
}

Эта программа выведет что-то вроде:

Этот файл example.c
Это строка 5
Скомпилировано Jul 10 2023 в 15:30:45

И вот и все! Вы только что сделали свои первые шаги в мир макросов в C. Помните, как и любое мощное средство, макросы должны использоваться wisely. Они могут сделать ваш код более эффективным и легким для чтения, но чрезмерное использование может привести к путанице. Практикуйтесь, экспериментируйте, и вскоре вы будете использовать макросы как профи!

Credits: Image by storyset