Макросы в языке Си

#define

Объявление макроса начинается со знака решетки # и ключевого слова define В простейшем макросе заменяется имя на значение


#define AR_SIZE 10   // AR_SIZE в теле программы будет заменяться на 10
Может использоваться как простейшая функция, Каждую переменную необходимо оборачивать в скобки, иначе могут быть проблемы в составных выражениях.

#include <stdio.h> // printf()
#define MUL1(x, y) (x * y) // Неправильно
#define MUL2(x, y) ((x) * (y)) // Правильно
int main(){
    printf("%d \n", MUL1(3 + 3, 10)); // Выводит 33
    printf("%d \n", MUL2(3 + 3, 10)); // Выводит 60
}

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


#include <stdio.h>
#define ABS(x) ((x) < 0 ? -(x) : (x))   // Возвращает абсолютное число
int main(){
  int x = 5;
  int result = ABS(x++); // Вызываем макрос
  printf("result = %d \n", result); // result = 6
  printf("x = %d \n", x);   // x = 7
}

#undef

Удаляет предыдущее определение макроса директивой #define


#include <stdio.h> //printf()
#define PI 3.14
int main(){
    printf("%f \n", PI); // Выведет 3.14000 
    #undef PI
    printf("%f \n", PI); // Ошибка 'PI undeclared'
}

#include


#include <stdio.h>  // Включение заголовка из компилятора
#include "func.c"     // Включение пользовательского заголовка
Условная компиляция #if, #elif, #else, #endif

#if константное выражение  
   группа операций  
#elif константное выражение  // #elif может быть много (на один if)
   группа операций  
#else  // #else может быть только один (на один if)
   группа операций  
#endif  // #endif обязательно завершает #if

#ifdef, #ifndef


#ifndef __IMAGE_H__    // Если не определен макрос __IMAGE_H__ (не включался данный файл директивой #include)
#define __IMAGE_H__  // Определяем макрос __IMAGE_H__

// код заголовочного файла

#endif 

#pragma once

Защита от повторного включения заголовочного файла может быть сделана более современным способом чем ifndef .. define. Большинство компиляторов поддерживают директиву предотвращающую множественное включение одного h файла


#pragma once

__FILE__

Макрос FILE заменяется на название файла в коде которого он вызван.


printf("%s \n", __FILE__); //> ..\test\main.c

__LINE__

Макрос LINE заменяется на номер строки кода файла в котором он вызван. Полезно для логирования или отладки.


printf("%d \n", __LINE__); //> 5

__DATE__

Выводит текущую дату.


printf("%s \n", __DATE__); //> Dec 30 2022

__TIME__

Выводит текущее время.


printf("%s \n", __TIME__); //> 23:03:48

__STDC_VERSION__

Выводит используемую версию стандарта Си в формате YYYYMM, где YYYY - год выпуска, а MM - месяц выпуска версии стандарта.


printf("%ld \n", __STDC_VERSION__); //> 199901

__VERSION__

Выводит версию GNU C.


printf("%s \n", __VERSION__); //> 8.1.0
2023-03-16



Понравилась страница?
Добавить в закладки
Или поделиться!

Связанные темы

Ключевое слово extern в языке Си
Инкапсуляция в языке Си
Макросы в языке Си
Достоинства и недостатки языка Си