Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0495976_C19D7_shpory_s.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.82 Mб
Скачать
  1. Динамическая память. Указатели и массивы. Ссылочный тип.

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

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

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

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

#include <iostream>

using namespace std;

int main() {

// создание объекта типа int со значением 45

// и сохранение его адреса в указателе obj

int* obj = new int(45);

// освободили память на которую указывал obj

cout<<"*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 элементов типа int

int 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 элементов типа int

int 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;}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]