Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Производные типы. Тип указатель: указатели на объектыСодержание книги
Поиск на нашем сайте
Цель работы: изучить тип указатель и соотношения между именами, адресами и значениями переменных, научиться использовать указатели в программных кодах на языке C++.
Теоретические сведения В языке С++ разрешено использование наряду со стандартными типами производные типы, полученные на основе более простых базовых типов. Производные типы можно условно подразделить на две группы: Непосредственно производные типы. Эти типы являются производными от некоторых существующих типов, реализуя типы указателей, ссылки, функции преобразования типов. В группу непосредственно производных типов входят: · массивы; · указатели; · ссылки; · перечисления. Составные производные типы. В группу составных производных типов входят: · классы; · структуры; · объединения.
Переименование типов В некоторых программных кодах бывает удобно вводить новые обозначения имен отдельных используемых типов данных. Задавать новое имя типу можно с помощью ключевого слова typedef. Синтаксис: typedef Тип НовоеИмяТипа[Размерность]; Например: typedef unsigned int UNIT; typedef char Msg[100]; Такое имя можно затем использовать так же, как и стандартное имя типа: UNIT a,b,c;//переменные типа unsigned int Msg str[10];//массив из 10 строк по 100 символов
Рассмотрим тип указатель. Указатели являются специальными объектами в программах на С++. Они предназначены для хранения адресов памяти. Пример: Когда компилятор обрабатывает оператор определения переменной, например, int i=10;, то в памяти выделяется участок памяти в соответствии с типом переменной (int=> 2 байта) и записывает в этот участок указанное значение. Все обращения к этой переменной компилятор заменит на адрес области памяти, в которой хранится эта переменная. Операция &a является операцией взятия адреса ее операнда.
Рис. Адресация в С++
Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями. Указатель – именованный объект, предназначенный для хранения адреса области памяти (объекта, непоименованной области оперативной памяти либо точки входа в функцию). Указатель не является самостоятельным типом, он всегда связан с каким-то другим типом. Указатели делятся на две категории: · указатели на объекты; · указатели на функции. Эти категории указателей отличаются друг от друга свойствами и правилами манипулирования. Каждый указатель имеет соответствующий тип.
Указатели на объекты В общем случае синтаксис определения указателя на объект: Тип*Описатель При определении указателя специфицируется имя указателя-переменной (в дальнейшем указатель) и тип объекта, на который он ссылается. Тип задает тип объекта, адрес которого будет содержать эта переменная и может соответствовать базовому, пустому (свободному, родовому, то есть типу void), перечислению, структурному типу и типу объединения. Реально указатель на void ни на что не указывает, но обладает способностью указывать на все что угодно после его типизирования каким-либо объектом. Описатель – это идентификатор, определяющий имя объявляемой переменой типа указатель или конструкция, которая организует непосредственно доступ к памяти. Описателю обязательно должна предшествовать звездочка (*). Знак '*' является унарной операцией косвенной адресации, его операнд – указатель, а результат – адрес объекта, на который указывает операнд. Адресация является косвенной, так как обращение к области памяти осуществляется не напрямую по адресу (например, 1А2В), а через объект, которому в памяти соответствует определенный участок. Объем памяти, который выделяется для хранения данных, определяется типом данных и моделью памяти. Для приведенной на рисунке модели памяти адресом переменной типа char с именем ch является 1А2В, адресом переменной типа int с именем date является 1А2C, адресом переменной типа float с именем summa является 1А2E.
Рис. Адресация типов в С++
Примеры определения указателей: int *P; /*указатель Р может содержать адрес объекта типа int*/ float *s; /*указатель s может содержать адрес объекта типа float*/
Синтаксис указателя на объект базового типа: Тип*ИмяУказателя; где ИмяУказателя – идентификатор.
Например, char *s; //переменная s – указатель на объект типа char double *x; /*переменная х – указатель на объект типа double, вещественного числа с плавающей точкой удвоенной точности*/ int *k, *ff; //k, ff – указатели на объекты целого типа int *p, y; /*р – указатель на объект типа int, y – целочисленная переменная и не является указателем*/ int x, *p; /*х – целочисленная переменная и не является указателем, р – указатель на объект типа int*/
Указатель может быть константой или переменной, а также указывать на константу или переменную. Например: int i;//целая переменная const int ci=1; //целая константа
int *pi; //указатель на целую переменную const int *pci; //указатель на целую константу
int *const cpi; //указатель-константа на целую переменную const int *const cpc; //указатель-константа на целую константу
При объявлении указателя его можно сразу проинициализировать (задать значение): int *pi=&i; //указатель на целую переменную const int *pci=&ci; //указатель на целую константу
int *const cpi=&i; //указатель-константа на целую переменную const int *const cpc=&ci; //указатель-константа на целую константу
Если модификатор const относится к указателю (т.е. находится между именем указателя и *), то он запрещает изменение значения указателя, а если он находится слева от типа (т.е. слева от *), то он запрещает изменение значения, на которое указывает указатель.
Способы инициализации указателя 1. Присваивание указателю адреса области памяти существующего объекта: · с помощью операции получения адреса: int a=5; int *p=&a;
· с помощью проинициализированного указателя int *r=p;
2. Присваивание указателю адреса области памяти в явном виде: char *cp=(char*)0х В800 0000; где 0х В800 0000 – шестнадцатеричная константа, (char*) – операция приведения типа.
3. Присваивание указателю пустого значения: int *N=NULL; или int *N=0; Спецификатор указателя при форматированном выводе Если на экран необходимо вывести адрес, следует применять спецификатор %p. %p – спецификатор указателя. Этот спецификатор формата заставляет функцию printf() выводить на экран адрес, формат которого совместим с типом адресации, принятой в компьютере.
Операции с указателями С указателями можно выполнять следующие операции: · разыменование (*) – получение значения величины, адрес которой хранится в указателе; · взятие адреса (&); · присваивание; · арифметические операции § сложение указателя только с константой, § вычитание: допускается разность указателей и разность указателя и константы, § инкремент (++) увеличивает значение указателя на величину sizeof(тип); § декремент (--) уменьшает значение указателя на величину sizeof(тип); · сравнение; · приведение типов. Пример 1. Указатели различных типов указывают на одно и то же место в памяти. Однако при разыменовании получаются разные результаты. // Выбор данных из памяти с помощью разных указателей // Использование функций приведения типов #include <iostream.h> void main(){ unsigned long L=12345678; char *cp=(char*)&L; int *ip=(int*)&L; long *lp=(long*)&L;
cout <<"\n&L = "<<&L; cout <<"\nL = "<<L; cout <<"\n*cp = "<<*cp; cout <<"\n*ip = "<<*ip; cout <<"\n*lp = "<<*lp; } Пример 2. //Операции над указателями #include <iostream.h> void main(){ int a,c,b; int *ca, *cb; int *sa, *sb, *sc; cout << "a = "; cin >> a; cout << "b = "; cin >> b; c=a+b;
sb=&b;//инициализация указателей через взятие адреса sa=&a; *sc=c;//инициализация указателя через обращение к переменной ca=sa;//инициализация указателей через другой указатель cb=sb; *sa=12;//инициализация указателя через константу
cout << "\n*ca = " << *ca; cout << "\n*sa = " << *sa; cout << "\n*cb = " << *cb; cout << "\n*sb = " << *sb; cout << "\n*sc = " << *sc;
cout << "\nca = " << ca; cout << "\ncb = " << cb; cout << "\nsc = " << sc;
cout << "\na = " << a; cout << "\nb = " << b; cout << "\nc = " << c;
cout << "\n&a = " << &a; cout << "\n&b = " << &b; cout << "\n&c = " << &c;
cout << "\n*&a = " << *&a;
cout << "\n*cb-*ca = " << *cb-*ca; cout << "\n*cb+*ca = " << *cb+*ca; *cb=+2; //сложение с константой cout << "\ncb = " << cb; cb++; //инкремент cout << "\ncb = " << cb; ca--; //декремент cout << "\ncа = " << cа; /*разность указателей - разность их значений, деленная на размер типа в байтах*/ cout << "\ncb-ca = " << cb-ca; } Указатели одного и того же типа можно сравнивать с помощью стандартных операций сравнения. При этом сравниваются значения указателей, а не значения величин, на которые данные указатели ссылаются. Пример 3. #include <iostream.h> void main() { int x=10; int y=10; int *xptr=&x; int *yptr=&y;
//сравниваем указатели if (xptr == yptr) cout << "Указатели равны\n"; else cout << "Указатели неравны\n";
//сравниваем значения, на которое указывает указатель if (*xptr == *yptr) { cout << "Значения равны\n"; } else { cout << "Значения неравны\n";} } В приведенном примере результат первой операции сравнения будет ложным, а второй – истинным, поскольку переменные x и y имеют одно и то же значение. Задания 1. Наберите код программы из Примера 2. Выполните компиляцию и запуск программы. 2. В программе определите и инициализируйте переменную типа double, указатель double * и указатель типа void *. Присвойте указателям адрес переменной. Напечатайте адрес переменной, значения указателей и значения, получаемые при разыменовании указателей. Чтобы продемонстрировать роли и последовательность выполнения унарных операций получения адреса & и разыменования *, выведите на печать значение выражения *&имя_переменной. 3. Определите и инициализируйте переменные разных типов (char, int, double) и один указатель типа void *. Последовательно присваивая указателю адреса переменных разных типов, выведите значения переменных с помощью разыменования указателя. Домашние задания 1. Наберите коды программ из Примеров 1 и 3. Выполните компиляцию и запуск программ. 2. Определите и инициализируйте переменную типа double. Определите указатели char *, int *, double *, void *, инициализируйте их адресом переменной. Напечатайте значения указателей, их размеры и длины участков памяти, которые связаны с выражениями, разыменовывающими указатели. Лабораторная работа 23
|
||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-09-13; просмотров: 239; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.99.221 (0.007 с.) |