Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Указатели и адреса

Указатели

Указатели и ссылки

Указатель - это адрес памяти, распределяемой для размещения идентификатора (в качестве идентификатора может выступать имя переменной, массива, структуры, строкового литерала). В том случае, если переменная объявлена как указатель, то она содержит адрес памяти, по которому может находиться скалярная величина любого типа. При объявлении переменной типа указатель, необходимо определить тип объекта данных, адрес которых будет содержать переменная, и имя указателя с предшествующей звездочкой (или группой звездочек).

Форма записи:

Спецификатор-типа [ модификатор ] * описатель.

Спецификатор-типа задает тип объекта и может быть любого основного типа, типа структуры, смеси (об этом будет сказано ниже). Задавая вместо спецификатора-типа ключевое слово void, можно своеобразным образом отсрочить спецификацию типа, на который ссылается указатель. Переменная, объявляемая как указатель на тип void, может быть использована для ссылки на объект любого типа. Однако для того, чтобы можно было выполнить арифметические и логические операции над указателями или над объектами, на которые они указывают, необходимо при выполнении каждой операции явно определить тип объектов. Такие определения типов может быть выполнено с помощью операции приведения типов.

Предположим, что х - переменная, например, типа int, а рх – указатель:

int x=-3;

int *px;

 

Унарная операция &(взятие адреса) выдает адрес объекта, так что оператор

px = &x;

присваивает адрес x переменной px; говорят, что px "указывает" на x. Операция & применима только к переменным и элементам массива.

 

 

Для

int *U;

register int reg1;

недопустимы конструкции вида:

U=&(х-1); /* результатом выражения является число, находящееся в программном

стеке, его адрес не может быть получен */

U= &3; /* с константой 3 не связана ни одна ячейка памяти */

U=&reg1; /* нельзя получить адрес регистровой переменной, т.к. располагается не в

памяти, а в регистрах процессора */

Унарная операция * (разыменования) рассматривает свой операнд как адрес конечной цели и обращается по этому адресу, чтобы извлечь содержимое. Следовательно, если y тоже имеет тип int, то

int x=-3, y; int *px; px=&x; y = *px;

присваивает y содержимое того, на что указывает px, т.е. само значение переменной х.

Описание указателя говорит о том, что комбинация *px имеет тип int. Это означает, что если px появляется в контексте *px, то это эквивалентно переменной типа int. Фактически синтаксис описания переменной имитирует синтаксис выражений, в которых эта переменная может появляться. Это замечание полезно во всех случаях, связанных со сложными описаниями. Например,

double atof(), *dp;

говорит, что atof() и *dp имеют в выражениях значения типа double.

Вы должны также заметить, что из этого описания следует, что указатель может указывать только на определенный вид объектов.

Перед использованием описанного указателя надо обязательно задать ему адрес переменной (постоянной), на которую он будет указывать.

Указатели могут входить в выражения. Например, если px указывает на целое x, то *px может появляться в любом контексте, где может встретиться x. Так оператор

y = *px + 1;

присваивает y значение, на 1 большее значения x;

printf("%d ", *px)

печатает текущее значение x;

d = sqrt(double) *px)

получает в d квадратный корень из x, причем до передачи функции sqrt значение x преобразуется к типу double. (смотрите главу 2).

В выражениях вида

y = *px + 1;

унарные операции * и & связаны со своим операндом более крепко, чем арифметические операции, так что такое выражение берет то значение, на которое указывает рх, прибавляет 1 и присваивает результат переменной y. Мы вскоре вернемся к тому, что может означать выражение

y = *(px + 1);

Ссылки на указатели могут появляться и в левой части присваивания. Если px указывает на x, то

*px = 0;

полагает х равным нулю, а

*px += 1;

увеличивает его на единицу, как и выражение

(*px) + 1; или *px + 1;

Круглые скобки необязательны, т.к. у операции разыменования приоритет выше, чем у операции сложения.

И наконец, так как указатели являются переменными, то с ними можно обращаться, как и с остальными переменными. Если py - другой указатель на переменную типа int, то

py = px;

копирует содержимое рх в py, в результате чего py указывает на то же, что и px.

Самостоятельная проработка:

В качестве модификаторов при объявлении указателя могут выступать ключевые слова const, near, far, huge. Ключевое слово const указывает, что указатель не может быть изменен в программе. Размер переменной объявленной как указатель, зависит от архитектуры компьютера и от используемой модели памяти, для которой будет компилироваться программа. Указатели на различные типы данных не обязательно должны иметь одинаковую длину.

Примеры:

unsigned int * a; /* переменная а представляет собой указательна тип unsigned int (целые числа без знака) */ double * x; /* переменная х указывает на тип данных с плавающей точкой удвоенной точности */ char * fuffer; /* объявляется указатель с именем fuffer который указывает на переменную типа char */double nomer;void *addres;addres = & nomer;(double *)addres ++;/* Переменная addres объявлена как указатель на объект любого типа. Поэтому ей можно присвоить адрес любого объекта (& - операция вычисления адреса). Однако, как было отмечено выше, ни одна арифметическая операция не может быть выполнена над указателем, пока не будет явно определен тип данных, на которые он указывает. Это можно сделать, используя операцию приведения типа (double *) для преобразования addres к указателю на тип double, а затем увеличение адреса. */const * dr;/* Переменная dr объявлена как указатель на константное выражение, т.е. значение указателя может изменяться в процессе выполнения программы, а величина, на которую он указывает, нет. */unsigned char * const w = &obj./* Переменная w объявлена как константный указатель на данные типа char unsigned. Это означает, что на протяжение всей программы w будет указывать на одну и ту же область памяти. Содержание же этой области может быть изменено. */
<== предыдущая лекция | следующая лекция ==>
Человек как жертва неблагоприятных условий социализации | Указатели и аргументы функций
Поделиться с друзьями:


Дата добавления: 2014-01-15; Просмотров: 433; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.