typedef
определяет имя для типа. Так
typedef void *COMPLEX;
COMPLEX z;
эквивалентно
void *z;
Тип указателя обычно указывает, на какие данные указывает указатель. void *
является исключением: это способ иметь указатель без указания типа значения, на которое он указывает. Вы можете свободно назначать любой тип указателя на void *
указатель и обратно.
void *
указатели обычно используются в общих библиотечных функциях, которые должны работать с данными любого типа. Например, рассмотрим стандартную библиотечную функцию memcpy
:
void *memcpy(void *dest, const void *src, size_t n);
Вы передаете этой функции указатель на объект любого типа src
, указатель на другой объект (который обычно, но не всегда, того же типа) dest
и количество байтов для копирования. Функция копирует байты, ей все равно, что означают байты, поэтому достаточно передать два указателя на неопределенный тип.
Использование void *
здесь не является хорошей или обычной практикой программирования. Комплексное число представляется как его действительная часть и ее мнимая часть:
struct COMPLEX_IMPL { double a; double b; };
Типичная библиотека комплексных чисел сделала бы это типом COMPLEX
.
Код, который вы опубликовали, скрывает реализацию типа COMPLEX
. Тот факт, что комплексные числа реализованы в виде структуры, содержащей два элемента double
, очевиден только в complex.c
. Пользователи библиотеки видят только, что COMPLEX
является указателем на что-то. Это форма абстракции данных : скрытие подробностей представления типа данных. Но это плохо сделано: с этим определением любой указатель на что-либо может быть назначен на COMPLEX
. Обычным способом является использование неполной структуры , которая объявлена и явно является структурой, но члены которой не указаны. В complex.h
вы бы написали:
struct COMPLEX_IMPL;
typedef struct COMPLEX_IMPL *COMPLEX;
Таким образом, единственный способ юридически создать COMPLEX_IMPL
- через функции, предоставляемые complex.h
, но переменная типа COMPLEX
явно указывает на представление комплексного числа, определенного в complex.c
.
О, а this
- обычное имя переменной.