|
Программирование >> Аргументация конструирования
расположении переменных в памяти tinclude <3tdio,h> ttinclude <iostream.h> indnt intArgc, char* pszArgs[]) { int ir.l; int n; long 1; float f; double d; int ш2; ЕЫВОД даатеричном виде cout.setf (ios: :hex); выводить адреса переменных no очереди, чтобы показать размер каждой переменной J- = Ох (long) £ml << ; \n &n = Ox (longl&n < =; \n 5l = Ox (long)SI <<; \n Sf = Ox (long) uf < v \n id = Ox (long)id < = \n cout << cout << << << << Ox (long) £,m2 <<c \n return 0 , волнуйтесь, если программа будет возвращать разные значения при каждом запуске. Просто каждый раз программа хранит переменные по разным адресам. Важна только связь между адресами переменных. Сравнив расположение переменных, можно заключить, что п занимает четыре байта, 1 также занимает четыре и т.д. (в соответствии с приведенной таблицей). iJ* И GNU C + + , и Visual C + + выделяют одинаковое количество памяти под переменные одного типа. использование/А:аза/1е.4еи Переменная-указатель содержит адрес, обычно это адрес другой В табл. 8.2 приведены основные операторы для работы с указателями. Таблица 8.2. Операторы для работы суказателями переменной. ОПЕРАТОР НАЗНАЧЕНИЕ ньй) Получить адрес переменной * (унарный) Операция разыменования - возвращает переменную, на которую указы- вает указатель (в выражении). Указатель на даннтй тип (в объявлении) Пример работы с операторами приведен в следующем листинге: Глава 8. Первое знакомство с указателями в C++ void fn () in iiitVar; iriL* pintVar; pi ntvar Var; pmtVar указывает на intVar *p:ntVar = 10; сохраичет 10 Б переменой типа int } по адресу, находящемуся в pintVar Функция fn () начинается с объявления переменной intVar; в следующей строке объявляется pir.tVar - указатель на неременную тина int. Указатели объявляются как обычные переменнь[е, но в объявление добавляется унарный оператор *, который может быть использован совместно с именем любого тина. В данной строке этот символ иснользуется вместе с именем фундаментального тина int. Однако этот оператор может использоваться для добавления к любому имени переменной типа. При написании программ желательно придерживаться соглашений об именах, в соответствии с которыми первый символ в названии переменной указывает на ее тип. Например, можно использовать для int, d для double и т.д. С учетом этого соглашения имена указателей далее в книге будут начинаться с буквы р. Унарный оператор & в выражении означает взять адрес переменной . Таким образом, в первой строке приведенного кода находится команда сохранения адреса переменной intVar в переменной pintVar. Представим себе, что функция fn <} начинается с адреса 0x100, переменная расположена по адресу 0x102, а указатель pintVar - 0x106 (такое расположение намного проще результатов работы программы Layout; на самом деле вряд ли переменные будут храниться в памяти именно в таком порядке). Первая команда программы сохраняет значение в указателе pintVar. Вторая строка отвечает за присвоение значения 10 переменной, хранящейся но адресу, который содержится в указателе pintVar (в нем находится число 0x102, т.е. адрес переменной intVar). Сравнение указателей и почтовых адресов Указатели похожи на адреса домов. Ваш дом имеет уникальный адрес, и каждый байт в памяти компьютера тоже имеет уникальный адрес. Почтовый адрес содержит набор цифр и букв. Например, он может выглядеть так: 123 Main Street (конечно же, это не мой адрес! Я не люблю нашествий поклонников, если только они не женского пола). Адрес переменной в памяти содержит только цифры (например, 123456). Можно хранить диван в доме по адресу 123 Main Street, и точно так же можно хранить число в памяти по адресу 0x123456. Можно взять лист бумаги и написать на нем адрес - 123 Main Street. Теперь диван хранится в доме, который находится по адресу, написанному на листке бумаги. Так работают сотрудники службы доставки: они доставляют диваны по адресу, который указан в бланке заказа, независимо от того, какой именно адрес записан в бланке (я ни в коем случае не смеюсь над работ-пиками службы доставки - просто это самый удобный способ объяснить указатели). Использовав синтаксис С++, это можно записать так: House myHouse; House houseZVddress; houseAddress = &rr.yHouse; houseAddress = coucii; Эта запись обозначает следующее: является домом, a houseAddress - адресом дома. Надо записать адрес дома myHouse в указатель houseAddress и доставить диван по адресу, который находится в указателе houseAddress. Теперь используем вместо дома переменную типа int: int mylnt; int* intAddress; intAddress = Smylnt; intAddress = 10; Аналогично предыдущей записи, это поясняется так int - переменная типа int. Слелует сохранить адрес raylnt в указателе intAddress и записать 10 в переменную, которая находится по адресу, указанному в intAddress. Использование разных типов указателей Каждое выражение, как и переменная, имеет свой тип и значение. Тип выражения sintVar - указатель на переменную типа int, т.е. это выражение имеет тип int*. При сравнении его с объявлением указателя pintVar становится очевидно, что они одинаковы: int* pintVar = SintVar; обе части этого присвоения имеют тип *int Аналогично pintVar еет тип int*, a *pintVar - тип int: *pintVar =10 обе части этого присвоения еют int Тип переменной, на которую указывает pintVar, - int. Это эквивалентно тому, что если nouseAddress ЯВЛЯСТСЯ адрССОМ ДОМа, то, как ни странно, houseAddress указывает дом. Указатели на переменные других типов объявляются точно так же: double dDubleVar double* odoubleVar = sdoubleVar *pdoubleVar =10.0 В компьютере класса Pentium размер указателя равен четырем байтам, независимо от того, на переменную какого типа он указывает14. Очень важно следить за соответствием типов указателей. Представьте, что может произойти, если компилятор в точности выполнит такой набор команд: int nl; int* pintVar; pintVar = &nl; *pintVar = 100.0; Последняя строка требует, чтобы адресу, выделенному под переменную размером в четыре байта, было записано значение, имеющее размер восемь байтов. На самом деле ничего страшного не произойдет, поскольку в этом случае компилятор приведет 100.0 к типу int перед тем, как выполнить присвоение. Привести переменную одного типа к другому явным образом можно так: int iVar; double dVar - 10.0; iVar - (int)dVar; Так же можно привести и указатель одного типа к другому: int* piVar; double dVar = 10.0; double* pdVar; piVar = (lnt*)pdVar; Вообще говоря, размер указателя зависит не только от типа процессора, но и от операционной системы, используемого компилятора и так называемой модели памяти создаваемой программы. - Прим. ред.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |