Я читаю «Стандартную библиотеку С» П. Дж. Плаугера, которая действительно интересна. Книга объясняет не только как использовать библиотеку, но и как она реализована.
Я закончил чтение ctype.h
раздела и в шапке функции объявлены как макросы и функции. Например
int isdigit(int);
но и
#define isdigit(c) (_Ctype[(int)(c)] & _DI)
Я не понимаю, почему ОБА используются?
Кроме того, если я попытаюсь воссоздать свой собственный пользовательский ctype
заголовок и реализацию, я могу успешно скомпилировать только после удаления макроса (закомментируйте определение).
Этот аспект не был действительно объяснен в книге. Может кто-нибудь объяснить, пожалуйста?
Ответы:
Макрос (предположительно) более эффективен, поскольку не требует вызова функции. Его можно оптимизировать проще, поскольку он включает в себя поиск смещения указателя.
Вызов функции позволяет создавать ссылки на одну и ту же библиотеку, даже если программа была скомпилирована без определения макроса - если она была скомпилирована с другим заголовком или просто с мошенническим объявлением внутри исходного файла. Если, например, у вас есть компилятор, у которого есть чья-то «улучшенная» версия ctype.h, у которой нет макроса, функция все равно будет существовать во время выполнения для использования.
Если мы посмотрим на стандарт:
Это означает, что если вы напишите:
или
тогда вы вызываете реальную функцию, а не макрос. Вы также можете по закону написать:
или (в исходном файле нет
#include <ctype.h>
прямого или транзитивного):источник
extern int isdigit(int)
, например.