|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Преобразование типа указателяУказатель можно преобразовать к другому типу. Эти преобразования бывают двух видов: с использованием указателя типа void * и без его использования. В языке С допускается присваивание указателя типа void * указателю любого другого типа (и наоборот) без явного преобразования типа указателя. Тип указателя void * используется, если тип объекта неизвестен. Например, использование типа void * в качестве параметра функции позволяет передавать в функцию указатель на объект любого типа, при этом сообщение об ошибке не генерируется. Также он полезен для ссылки на произвольный участок памяти, независимо от размещенных там объектов. В отличие от void *, преобразования всех остальных типов указателей должны быть всегда явными (т.е. должна быть указана операция приведения типов). Однако следует учитывать, что преобразование одного типа указателя к другому может вызвать непредсказуемое поведение программы. Например, в следующей программе делается попытка присвоить значение х переменной у посредством указателя р. При компиляции программы сообщение об ошибке не генерируется, однако результат работы программы неверен. #include <stdio.h> int main(void){ double x = 100.1, y; int *p; /* В следующем операторе указателю на целое p (присваивается значение, ссылающееся на double. */ p = (int *) &x; /* Следующий оператор работает не так, как ожидается. */ y = *p; /* attempt to assign y the value x through p */ /* Следующий оператор не выведет число 100.1. */ printf("Значение x равно: %f (Это не так!)", y); return 0;}Обратите внимание на то, что операция приведения типов применяется в операторе присваивания адреса переменной х(он имеет тип double *) указателю p, тип которого int *. Преобразование типа выполнено корректно, однако программа работает не так, как ожидается (по крайней мере, в большинстве оболочек). Для разъяснения проблемы предположим, что переменная int занимает в памяти 4 байта, а double — 8 байтов. Указатель p объявлен как указатель на целую переменную (т.е. типа int), поэтому оператор присваивания y = *р;передаст переменной y только 4 байта информации, а не 8 байтов, необходимых для double. Несмотря на то, что p ссылается на объект double, оператор присваивания выполнит действие с объектом типа int, потому что p объявлен как указатель на int. Поэтому такое использование указателя p неправильное. Приведенный пример подтверждает то, что операции с указателями выполняются в зависимости от базового типа указателей. Синтаксически допускается ссылка на объект с типом, отличным от типа указателя, однако при этом указатель будет "думать", что он ссылается на объект своего типа. Таким образом, операции с указателями управляются типом указателя, а не типом объекта, на который он ссылается. Разрешен еще один тип преобразований: преобразование целого в указатель и наоборот. В этом случае необходимо применить операцию приведения типов (явное преобразование типа). Однако пользоваться этим средством нужно очень осторожно, потому что при этом легко получить непредсказуемое поведение программы. Явное преобразование типа не обязательно, если преобразуется нуль, то есть нулевой указатель. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.) |