Как работают макросы getchar() и putchar()?

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

Я читал здесь и там (программирование на Си Современный подход, К. Н. Кинг), что мы можем определить эти две функции как макросы.

Поскольку я немного новичок в C, я не могу обернуть голову, как эти два можно определить как макрос?

4 ответа

Существует два типа макросов: макросы простой замены и функционально-подобные макросы.

Макросы подстановки заменяют один экземпляр символа другим. Например:

#define LEN 10
char str[LEN];

После предварительной обработки это становится:

char str[10];

Функциональный макрос может принимать параметры, которые можно подключить к тому, что подставляется:

#define MAX(a,b) ((a) > (b) ? (a) : (b))
int x = MAX(2,3);

После предварительной обработки:

int x = ((2) > (3) ? (2) : (3));

В случае getchar а также putchar, они могут быть определены следующим образом:

#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)

Существует в основном три типа макросов препроцессора:

  1. Простой определяется без какого-либо значения. Например

    #define THIS_IS_A_MACRO
    

    Этот вид макросов используется для условной компиляции.

  2. Символические константы. Например

    #define SOME_SYMBOLIC_CONSTANT  123
    

    Эти макросы - это то, о чем вы думаете.

  3. Функциональные макросы. Враг пример

    #define SOME_MACRO(a_macro_argument)  printf("Macro invoked with argument %d\n", a_macro_argument)
    

    Этот тип макроса очень похож на функции, но заменяется препроцессором в исходном коде до того, как синтаксический анализатор компилятора увидит код, а аргументы макроса заменены их действительными значениями.

Давайте возьмем функциональный макрос и как он будет расширен препроцессором:

SOME_MACRO(123);

Выше будет заменено как

printf("Macro invoked with argument %d\n", 123);

Полностью зависит от реализации. Они также могут быть функциональными.

Стандарты не требуют ничего явного о типе реализации. Но вы можете проверить здесь это указывает Any function declared in a header may be additionally implemented..., как указал Евгений.Ш

Проще говоря, в библиотеке может быть функция или также макрос (для getchar). Классически, макрос для getchar() было бы #define getchar() getc(stdin), а также getc() также может быть макрос.

Стандарт говорит, что функция getc эквивалентна функции fgetc, за исключением того, что если она реализована как макрос, она может оценивать поток более одного раза, поэтому аргумент никогда не должен быть выражением с побочными эффектами.

Теперь это сводится к fgetc в этом случае мы знаем, что это гарантированно функция. Безопасность потока делает его более вероятным.

Таким образом, в C++ никогда не определяйте getchar и putchar как функции-члены класса. В случае, если они определены как макросы в файле stdio.h, компилятор выдаст всевозможные странные ошибки.

      #include <stdio.h>

class My_IO_Device
{
    int putchar (int c); // seemingly innocent
};

я не знаю<cstdio>гарантирует их реализацию в виде функций.

Другие вопросы по тегам