![]()
Главная Обратная связь Дисциплины:
Архитектура (936) ![]()
|
Динамическая память. Указатели и массивы. Ссылочный тип
Если размер объекта или массива заранее неизвестен (например, изображение), или размер объекта слишком большой, чтобы создавать его внутри функции, значит настало время воспользоваться механизмом динамической памяти С++, использующую отдельную область памяти называемой кучей. Для этого вам необходимо знать всего два оператора: · 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. Доступ к глобальным переменным, скрытым локальными переменными с тем же именем (оператор ::). В С++ предусмотрен доступ к глобальным переменным, скрытым локальными переменными с тем же именем. Операция разрешения области видимости :: позволяет в таких ситуациях воспользоваться глобальной переменной. Например: В описаниях кроме имен переменных и имен типов используются модификаторы : * - указатель, () - функция и [] - массив, причем в описаниях сложных объектов модификаторов может быть много,что затрудняет чтение и запись таких конструкций. Для правильной интерпретации описаний используются следующие правила приоритетов. Например:
![]() |