Арифметические операции над адресами
Над адресами в языке Си определены следующие операции:
-суммирование, можно добавлять к указателю целое значение;
-вычитание, можно вычитать указатели или вычитать из указателя целое число.
Однако при выполнении арифметических операций есть некоторые особенности. Рассмотрим их на следующем примере.
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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!