С нет контроля соответствия типов,
char_ptr = void_ptr; /* Правильно в С, но ошибка в C++ */
char_ptr = int_ptr; /* Предупреждение в С, ошибка в C++ */
Поскольку в С нет контроля соответствия типов, указателю может быть присвоено произвольное выражение. Нет никакой гарантии, что указуемый объект имеет ожидаемый тип; фактически значение указателя могло бы даже не быть адресом в отведенной программе области памяти. В лучшем случае это приведет к аварийному сбою программы из-за неправильной адресации, и вы получите соответствующее сообщение от операционной системы. В худшем случае это может привести к разрушению данных операционной системы. Ошибки в указателях очень трудно выявлять при отладке, потому что сложно разобраться в абсолютных адресах, которые показывает отладчик. Решение состоит в более строгом контроле соответствия типов для указателей, как это делается в Ada и C++.
Синтаксис
Синтаксические конструкции, связанные с указателями, иногда могут вводить в заблуждение, поэтому очень важно хорошо их понимать. Раскрытие указателей, индексация массивов и выбор полей записей — это средства доступа к данным внутри структур данных. В языке Pascal синтаксис самый ясный: каждая из этих трех операций обозначается отдельным символом, который пишется после переменной. В следующем примере Ptr объявлен как указатель на массив записей с целочисленным полем:
type Rec_Type =
record
Pascal |
end;
type Array_Type = array[1 ..100] of Rec_Type;
type Ptr_Type = Array_Type;
Ptr: Ptr_Type;
Ptr (*Указатель на массив записей с целочисленным полем *)
Ptrt (*Массив записей с целочисленным полем *)
Ptrt [78] (*3апись с целочисленным полем *)
Ptrt [78].Field ("Целочисленное поле *)
В языке С символ раскрытия ссылки (*) является префиксным оператором, поэтому приведенный пример записывался бы так:
typedef struct {