Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)


 

 

 

 



Динамическая память. Указатели и массивы. Ссылочный тип



Если размер объекта или массива заранее неизвестен (например, изображение), или размер объекта слишком большой, чтобы создавать его внутри функции, значит настало время воспользоваться механизмом динамической памяти С++, использующую отдельную область памяти называемой кучей.

Для этого вам необходимо знать всего два оператора:

· new - выделение памяти, если выделение памяти не произошло возвращается нулевой указатель;

· delete - освобождение памяти, не во всех компиляторах после освобождения памяти указателю присваивается 0.


#include <iostream>using namespace std; int main() {// создание объекта типа int со значением 45// и сохранение его адреса в указателе obj int* obj = new int(45); // освободили память на которую указывал objcout<<"*obj="<<*obj<<endl;delete obj; // елементы массива нельзя инициализировать// им задается значение по умолчанию// в случае классов вызывается конструктор по умолчаниюint* array = new int[10];cout<<"array:";for(unsigned int i=0; i<10; i++) cout<<array[i]<<" ";cout<<endl;delete [] array; // для избежания возможных ошибок// указателю лучше присвоить 0 (при доступе // к нулевому указателю генерируется системная ошибка,// а значит ошибка не останется незамеченной)array=0; ...}

Указатели являются одной из сильных сторон С++. Грамотное их применение позволяет повысить скорость выполнения программы и более эффективно использовать память. Например, во многих случаях в качестве аргументов функции лучше использовать указатели на объект, чем каждый раз создавать их копии.

С указателями используются следующие операции:

· & - взятие адреса переменной;

· * - разъименование указателя, т.е. получение доступа к объекту;

· -> - разъименование члена структуры;

· [] - индексация, доступ к элементу массива, при этом считается, что указатель содержит адрес 0 элемента.

Операция индексации может быть реализована с помощью адресной арифметики, где применяются операции ++,--, и +, -.

Можно создавать указатели на любые типы за исключением ссылок и битовых полей. Указатель может указывать не только на данные, но и на область кода, т.е. на функцию.

Массив - множество объектов одного типа расположенных в памяти последовательно. Индексация - операция доступа к элементу массива. Элементы нумеруются от 0.

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

#include <iostream>using namespace std; // массивы по 10 элементов типа intint array1[10]; // не инициализированный массив int array2[]= {1,2,3,4,5,6,7,8,9,0};//инициализированный массив (заданы значения каждого элемента)// объявления двухмерных массивовint array3[5][6]; int array4[2][3]={ {0,1,2}, {2,1,0} };// строки в С завершаются 0, более подробно см. строкиchar* str1="Hello, world"; // указатель на строку "Hello, world"char str2[]="Hello, world"; // массив символовchar str3[]={'H','e','l','l','o',',',' ','w','o','r','l','d','0' }; int * iptrarray[10]; // массив указателей типа int int (*iarrayptr)[10]; // указатель на массив из 10 элементов типа intint main(){int* iptr;cout<<"sizeof(iptr)=" <<sizeof(iptr) <<endl;cout<<"sizeof(array1)="<<sizeof(array1)<<endl;cout<<"array2[11]="<<array2[11]<<endl;return 0;}

Ссылки как и указатели хранят адрес объекта, но с автоматическим доступом к самому объекту, т.е. по сути они являются синонимами переменных на которые ссылаются. При определении ссылочной переменной инициализирующее выражение обязательно. Из следующего примера видно, что ссылки чуточку удобнее указателей.

#include <iostream>using namespace std; void swap_ref(int &a, int &b) { int c=a; a=b; b=c; }void swap_ptr(int *a, int *b){ int c=*a; *a=*b; *b=c; }int main(){int A=10,B=20;cout << "A="<<A<<" B="<<B<<endl;swap_ref(A,B);cout << "after swap_ref(A,B): A="<<A<<" B="<<B<<endl;swap_ptr(&A,&B);cout << "after swap_ptr(&A,&B): A="<<A<<" B="<<B<<endl;return 0;}

 

 

12. Доступ к глобальным переменным, скрытым локальными переменными с тем же именем (оператор ::).

В С++ предусмотрен доступ к глобальным переменным, скрытым локальными переменными с тем же именем. Операция разрешения области видимости :: позволяет в таких ситуациях воспользоваться глобальной переменной.

Например:
int x=5;
void main() { int x=3;
printf("Локальная x= %d\n",x); printf("Глобальная x= %d\n",:x); }

В описаниях кроме имен переменных и имен типов используются модификаторы : * - указатель, () - функция и [] - массив, причем в описаниях сложных объектов модификаторов может быть много,что затрудняет чтение и запись таких конструкций. Для правильной интерпретации описаний используются следующие правила приоритетов.
1) чем ближе модификатор к имени, тем выше его приоритет;
2) [] и () имеют более высокий приоритет, чем *;
3) можно использовать круглые скобки для повышения приоритета
модификатора. *.
Модификаторы доступа volatile и const позволяют сообщить компилятору об изменчивости или постоянстве определяемого объекта. Если переменная описана как const, то она недоступна в других модулях проекта, подобно статическим переменным, и не может быть изменена в процессе выполнения программы. Константа должна быть инициализирована при описании. С помощью модификатора const создаются типизированные именованные константы, которые в отличие от символических констант, определенных директивой #define, подлежат контролю типов.

Например:
const double PI=3.141528; const char yes='Y';
Одно из важных применений переменных типа const - защита параметров функции от модификации, если аргумент передается по ссылке. Модификатор volatile сообщает компилятору, что значение таких подвижных объектов может быть изменено скрытно от компилятора каким-либо фоновым процессом. Например, при обработке прерывания глобальная переменная, содержащая системное время компьютера, может изменить свое значение. Компилятор не должен помещать такие переменные в регистровую память.
Пример объявления : volatile unsigned timer;

 



Просмотров 850

Эта страница нарушает авторские права




allrefrs.su - 2024 год. Все права принадлежат их авторам!