7. Что такое указатель и для чего он нужен? |
Автор ARV | ||||||
18.12.2009 г. | ||||||
Указатель - это особый вид переменной. Если обычная переменная хранит значение, то указатель хранит адрес ячейки памяти, в которых что-то хранится. От обычных переменных указатель можно отличить по символу «звездочка» перед идентификатором при определении указателя: int *iptr; // указатель iptr на переменную типа int Следует разделять значение указателя и значение по указателю. Значение указателя есть адрес ячейки, а значение по указателю - значение из ячеек по этому адресу. Значение указателю надо присваивать с использованием оператора взятия адреса переменной &: int *iptr; // объявляем указатель на int Теперь обращение по указателю iptr приведет к тому, что будет использовано значение переменной var2. Кстати, можно присвоить указателю и константное значение, т.е. так: iptr = 0x012F; Но в этом случае во-первых, компилятор выдаст предупреждение, а во-вторых, вы должны четко осознавать последствия работы со значением памяти, на которую этот указатель указывает, т.е. с ячейками по адресу 0x012F. Кстати, избежать предупреждения компилятора можно очень просто: задав принудительно тип константы, как «пустой указатель», т.е. указатель, который указывает «куда-то»: iptr = (void*)0x012F; Для обращения по указателю используется операция разименования указателя, выражающаяся в том, перед идентификатором указателя записывается символ «звездочка»: *iptr = 12; // теперь окажется, что var2 == 12 Значение по указателю можно использовать, как обычную переменную, т.е. для работы с ним можно использовать все операторы, допустимые для переменных. А вот с операциями над самим указателем есть ряд тонкостей, главная из которых заключается в том, что указатель изменяется на величину, кратную размеру в байтах того типа, на который он указывает. Рассмотрим пример: int *iptr = (void*)0x100; Вопрос: чему равен nptr? Правильный ответ не 0x101, а 0x102, так как размер типа int равен 2 байта. Самое интересное, что в Си нет разницы между указателем и массивом, кроме как в форме определения переменных! Следующие 2 определения абсолютно идентичны: char *str; // указатель на строку Соответственно, идентификатор любого массива есть ни что иное, как указатель на данные, тип которых определен при описании массива. Отсюда вытекает ряд способов использования указателя по аналогии с массивом, например, можно обращаться по указателю: int *iptr = (void*)0x100; В результате выполнения этих операторов окажется, что в памяти по адресу 0x100 хранится число 9, по адресу 0x102 хранится 10 и по адресу 0x104 хранится 11. Использование указателей позволяет манипулировать содержимым памяти данных совершенно произвольным образом! Именно эта возможность является одним из наиболее сильных средств языка Си, и именно с этой возможностью связано наибольшее количество проблем в программах, на Си написанных! char array[10] = {1,2,3,4,5,6,7,8,9,10}; В приведенном примере нет ни одной ошибки, но к каким последствиям он приведет?! «Неожиданно» переменная var окажется обнуленной... Добавить в любимые (0) | Просмотров: 12594
Только зарегистрированные пользователи могут оставлять коментарии. |
« Пред. | След. » |
---|