Арифметические операции над адресами



Над адресами в языке Си определены следующие операции:

-суммирование, можно добавлять к указателю целое значение;

-вычитание, можно вычитать указатели или вычитать из указателя целое число.

Однако при выполнении арифметических операций есть некоторые особенности. Рассмотрим их на следующем примере.

 

double *p1;

float *p2;

int *i;

p1++;

 

p2++;

i++;

}

Операция p1++ увеличивает значение адреса на 8, операция p2++ увеличивает значение адреса на 4, а операция i++ на 2. Операции адресной арифметики выполняются следующим образом:

-операция увеличения приводит к тому, что указатель будет слаться на следующий объект базового типа (для p1 – это double, для p2 – float, для i – int);

- операция уменьшения приводит к тому, что указатель, ссылается на предыдущий объект базового типа.

-после операции p1=p1+n, указатель будет передвинут на n объектов базового типа; p1+n как бы адресует n-й элемент массива, если p1 – адрес начала массива.

 

7.5. Использование адресов и указателей при работе с массивами.

Динамические массивы.

Динамический массив – массив переменной длины, память под который выделяется в процессе выполнения программы. При каждом запуске программы, можно определять массив с разным количеством элементов, после того как массив не используется, память можно освободить, затем опять выделить и т.д.

С помощью указателей в Си можно выделить участок памяти (динамический массив) заданного размера для хранения данных определенного типа. Для этого необходимо выполнить следующие действия:

1.Описать указатель (например, переменную p) определенного типа.

2.Начиная с адреса, определенного указателем, с помощью функций calloc, malloc или операции new выделить участок памяти определенного размера. После этого p будет адресом первого элемента выделенного участка оперативной памяти (0-й элемент массива), p+1 будет адресовать – следующий элемент в выделенном участке памяти (1-й элемент динамического массива), …, p+i является адресом i-го элемента. Необходимо только следить, чтобы не выйти за границы выделенного участка памяти.

 

К i-му элементу динамического массива p можно обратиться одним из двух способов

 

*(p+i) или p[i]

3.Когда участок памяти будет не нужен, его можно освободить с помощью функции free(), операции delete.

Перед подробным описанием работы с динамическими переменными, рассмотрим функции calloc, malloc, realloc и free и операции new и delete.

Единственным параметром функции malloc является целое беззнаковое значение, определяющее размер выделяемого участка памяти в байтах. Функция malloc возвращает бестиповый указатель (void *) на выделенный участок памяти. Обращение к функции malloc имеет вид

void *malloc(n);

здесь n определяет размер выделяемого участка памяти в байтах, функция вернет значение NULL, если выделить память не удалось и указатель на выделенный участок памяти, при успешном выделении.

 

ПРИМЕР. Найти сумму элементов динамического массива вещественных чисел.

#include "stdafx.h"

#include <iostream.h>

#include <malloc.h>

int main()

{

int i,n;

float *a,s;

cout<<"n=";

cin>>n;

a=(float *)malloc(n*sizeof(float));

cout << "Vvedite massiv A";

for(i=0;i<n;i++)

// cin>>a[i];

cin>>*(a+i);

for(s=0,i=0;i<n;i++)

//s+=a[i];

s+=*(a+i);

cout << "S="<<s;

free(a);

return 0;

}

 

Кроме функции malloc для выделения памяти в Си есть функция calloc. Ее особенностью является обнуление всех выделенных элементов. Обращение к функции имеет вид:

void *calloc (num, size);

Функция calloc выделяет num элементов по size байт и возвращает указатель на выделенный участок или NULL при невозможности выделить память.

 

#include "stdafx.h"

#include <iostream.h>

#include <malloc.h>

int main()

{

int i,n;

float *a,s;

cout<<"n=";

cin>>n;

a=(float *)calloc(n,sizeof(float));

cout << "Vvedite massiv A";

for(i=0;i<n;i++)

cin>>*(a+i);

for(s=0,i=0;i<n;i++)

s+=*(a+i);

cout << "S="<<s;

free(a);

return 0;

}

 

Функция realloc изменяет размер выделенной ранее памяти, обращение к ней имеет вид:

char *realloc(void *p, size);

Функция изменяет размер участка памяти, на который указывает p, новый размер участка памяти size. Если при этом пришлось изменять месторасположение участка памяти, то новое его месторасположение и возвращается в качестве результата. Если в качестве p передается NULL, то функция realloc работает аналогично функции malloc.

Для освобождения выделенной памяти используется функция free. Обращение к ней имеет вид

void free( void *p);

Освобождает память, выделенную память, p – указатель на участок память, ранее выделенный функциями calloc, malloc или realloc.

Для выделения памяти в С++ есть еще операция new.

Для выделения памяти под n элементов типа float можно поступить так.

int n;

float *a;

cin>>n;

a=new float[n];

int main()

{

int i,n;

float *a,s;

cout<<"n=";

cin>>n;

a=new float[n];

cout << "Vvedite massiv A";

for(i=0;i<n;i++)

// cin>>a[i];

cin>>*(a+i);

for(s=0,i=0;i<n;i++)

//s+=a[i];

s+=*(a+i);

cout << "S="<<s;

delete [] a;

return 0;

}


Дата добавления: 2019-09-13; просмотров: 198; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!