5. Проблемы, связанные с указателями
5. Проблемы, связанные с указателями Самые распространенные проблемами при использовании указателей: 1) попытка работать с указателем, не содержащим адреса ОП, выделенной под переменную; 2) потеря значения указателя из-за присваивания ему нового 3) неосвобождение ОП, запрошенной с помощью функции выделения динамической памяти. При объявлении указателя на значение любого типа ОП для адресуемого значения не резервируется. Выделяется только ОП для переменной-указателя, но указатель при этом не получает никакого значения. Рассмотрим пример, содержащий грубую ошибку – попытку работать с неинициализированным указателем: int *х; //указателю х выделена ОП, но х не содержит адреса ОП для //конкретной переменной *x=123; //ошибка Присваивание ошибочно, так как указатель х не получил значения адреса, по которому должно быть расположено значение 123. Не вдаваясь в подробности, можно сказать, что неинициализированное значение указателя может быть недопустимым значением адресов, что может привести к нарушению работоспособности всей программы. Компилятор не обнаруживает эту ошибку. Это должен делать разработчик программы. Исправить ситуацию можно с помощью одной из функций выделения динамической памяти, например функции malloc(). Форма обращения к функции malloc(): < имя_указателя> = (< тип_указателя> )malloc(< объем_ОП> ); где < имя_указателя> – имя переменной-указателя; < тип_указателя> – тип значения, возвращаемого функцией malloc(); < объем_ОП> – количество байтов ОП, выделяемой адресуемой переменной. Например, х=(int*)malloc(sizeof(int)); При этом из кучи выделяется 4 байта ОП для целого значения, а адрес его размещения заносится в указатель х. При таком выделении памяти работоспособность программы не нарушается. Аргумент функции malloc() определяет объем ОП для целого значения с помощью операции определения объема ОП для размещения значения целого типа sizeof(int). Операция (int*), записанная перед функцией, означает, что адрес, возвращаемый функцией malloc(), рассматривается как указатель на переменную целого типа. Это операция приведения типов.
Таким образом, ошибки не будет при использовании операторов: int *х; //x – имя указателя x=(int*)malloc(sizeof(int)); //выделена ОП целому значению, на которое указывает х, и переменой х //присваивается адрес выделенной ОП *x=123; // переменная, на которую указывает х, получила значение // 123 Освобождение ОП в куче выполняет функция free(). Ее аргументом является имя указателя, содержащего адрес освобождаемой и ранее выделенной динамической памяти, например free(x); 6. Поразрядные операции Каждая переменная, объявленная в программе занимает в ОП некоторый участок, который содержит столько байт, сколько требует для размещения в ОП тип переменной. В свою очередь каждый байт – совокупность из восьми бит. Бит – это минимальная единица хранения информации в памяти компьютера. В языке С++ изменять значение переменной можно не только при помощи операции присваивания (т. е. целиком), но и с помощью поразрядных операций (по битам). Поразрядные операции называют побитовыми операциями – операции, с помощью которых можно изменять значение переменной по битам. Побитовыми операциями являются проверка (логические), сдвиг и присвоение значения битам данных. Такие операции могут осуществляться только над переменными типа int или char. Побитовые операции и результаты их работы приведены в табл. 7.
При помощи операций легко проверить «состояние» того или иного бита переменной. Для этого на переменную «накладывают» маску – переменную, которая содержит проверяемую последовательность 0 и 1. Типы маски и переменной, на которую накладывается маска, должны совпадать. Наложение осуществляется при помощи операций ^, &, | :
~00110010 == 11001101
Кроме поразрядных операций (см. табл. 7) существуют две побитовые операции сдвига: < < – операция сдвига всех битов переменной влево; > > – операция сдвига всех битов переменной вправо. При использовании этих операций указывается число разрядов, на которое происходит сдвиг битов вправо или влево. Побитовый сдвиг не является циклическим, т. е. если при сдвиге битов произошел выход за границы участка ОП, где размещена изменяемая переменная, то вышедшие за границу биты теряются. С помощью операций сдвига можно умножать или делить переменную на число, кратное двум. Форма записи этих операций: < имя_переменной> > > < количество_разрядов>; < имя_переменной> < < < количество_разрядов>; Например, p=p> > 3; //значение переменной p уменьшается в 23 = 8 раз c=c< < 4; // значение переменной p увеличивается в 24 = 16 раз Наиболее часто побитовые операции используются при системном программировании. Однако они бывают полезны и при решении прикладных задач.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|