Средство typedef
используется для создания псевдонимов для типов. Например,
typedef int *iptr;
создает имя iptr
как синоним типа int *
, поэтому вы можете объявлять указатели, используя
iptr p, q;
вместо того, чтобы писать
int *p, *q;
Синтаксис объявления C немного сложнее, чем думает большинство людей, особенно там, где задействованы указатели. Основные правила:
T *p; // p is a pointer to T
T *a[N]; // a is an array of pointer to T
T *f(); // f is a function returning pointer to T
T (*a)[N]; // a is a pointer to an array of T
T (*f)(); // f is a pointer to a function returning T
T const *p; // p is a pointer to const T
const T *p; // same as above
T * const p; // p is a const pointer to T
Все может быть сколь угодно сложным — у вас могут быть массивы указателей на функции:
T (*a[N])();
или функции, возвращающие указатели на массивы:
T (*f())[N];
или еще хуже зверства. Объявления указателей функций становятся более уродливыми, когда в миксе есть параметры; к счастью, вам нужно указать в объявлении только типы параметров, а не имена:
typedef Value (*NativeFn)(int, Value*);
делает вещи немного более легкими для понимания.
Это объявление создает NativeFn
как синоним указателя типа на функцию, принимающую int
и Value *
и возвращающую Value
.
Предположим, у вас есть функция, определенная как
Value foo( int argcCount, Value *args )
{
Value result;
...
return result;
}
Если вы хотите создать указатель на эту функцию с именем fptr
, вы обычно объявляете ее как
Value (*fptr)(int, Value *) = foo;
Однако приведенное выше объявление typedef
позволяет вам написать
NativeFn fptr = foo;
При этом используйте typedef
экономно. Проблема в том, что, хотя он может создавать более простые для чтения способы объявления некоторых элементов, он также скрывает некоторую потенциально полезную информацию. Например, несмотря на приведенный выше пример iptr
, лучше не скрывать указатели за определениями типов — если кому-то нужно использовать унарный оператор *
для p
или q
, чтобы использовать их правильно, тогда эта информация должна быть быть в декларации этих предметов. Если кому-то когда-нибудь понадобится вызвать объект, на который указывает fptr
, ему нужно знать тип возвращаемого значения, количество и типы параметров и т. д., но вся эта информация отсутствует в объявлении, которое использует имя typedef.
11.08.2020