char c;
c = * (char *) bp;
int i;
i = * (int *) bp;
# include < stdio.h >
# include < dos.h >
// функция распечатывает значения сегмента и смещения адреса p с помощью макросов,
определенных в файле dos.h
void Disp_pointer (void * p)
{ printf (“%4x:%4x\n“, FP_SEG(P), FP_OFF(P)); }
void main ()
{
char buffer [1024]; void * bp = & buffer;
*(char*)bp=’A’; //запоминание символа через указатель
buffer[1]=’B’; buffer[2]=0;
printf (“адрес буфера= “);
Disp_Pointer(&buffer);
printf(“содержимое буфера=%S“,*(char*)bp);
}
Отображение адреса, содержащегося в указателе, также возможно выполнить следующим образом, но форма представления в этом случае зависит от вида указателя
printf(“%p\n”,bp);
Указатели и динамически размещаемые переменные
Функции динамического выделения, освобождения памяти находятся в файле alloc.h
Функции выделения памяти
void* malloc(int size); //выделяется size байтов памяти
…
char * sp;
sp=(char*) malloc (100);
double * dp;
dp=(double*) malloc (sizeof(double));
.
void* calloc(int n, int size); // n-кол-во, int–размер эл-та
long* lp;
lp=(long*) calloc (10, sizeof(long));
Функция calloc выполняет инициализацию выделенных байтов памяти нулем.
Функции освобождения памяти
free (bp);
Операции управления кучей, встроенные в язык
указатель = new имя типа [инициализатор]
delete указатель
int* h; h=new int(15);
int* h = new int(15);
delete h;
Указатель можно установить на явно заданный адрес памяти
p=(char*) 0xB8000000; //начальный адрес видеопамяти
Как указатели, так и те объекты, на которые они указывают, могут быть объявлены константами.
1) указатель-константа
type * const имя_указателя [инициализатор];
Значение указателя-константы изменить невозможно, поэтому имя такого указателя можно использовать для доступа к фиксированному участку памяти. Содержимое этого участка памяти, полученное с помощью операции раскрытия ссылки, доступно, как для чтения, так и для записи.
void main()
{
char* const comp=(char*)0xF000FFFE;
/ / указатель на байт, в котором находится информация о типе компьютера
printf("\n тип компьютера %x\n",*comp);
comp=NULL; // ошибка!
}
2) указатель на константу
type const* имя_указателя [идентификатор]
Объект, на который указывает указатель, изменить нельзя.
const int z=0;
int const* pi=&z;
*pi=1; // ошибка!
Адресная арифметика над указателями
Операции над указателями
1) раскрытие ссылки
2) приведение типов
3) присваивание
4) получение адреса
5) сложение и вычитание
6) автоинкремент, автодекремент
7) сравнение
1. Приведение типов
Неявное приведение типов разрешено только к родовому указателю void
void* vp;
int* ip;
…
ip=vp; // нельзя
vp=ip; // можно
2. Вычитание указателей
Разрешается только с указателями одного и того же типа. Определяется расстояние между двумя участками памяти в единицах, кратных размеру (в байтах) объекта того типа, с которым связан указатель. Таким образом, разность между указателями, адресующими два смежных объекта любого типа, по абсолютной величине всегда равна 1.
Пр.
void main ()
{
char ac ='f', bc='a';
char* pac=&ac,*pbc=&bc;
long al=3, bl=4
long* pal=&al, *pbl=&bl;
printf("%P%P",pac,pbc);
printf("%d,pac–pbc);
printf("%P%P",pbl,pal);
printf("%d",pbl-pal);
printf("разность числовых значений указателей %d%d",
(int)pac–(int)pbc,(int)pbl–(int)pal);
}
pac=…0ffff pbc=…0ffe
pac-pbc=1
pal=…0ff2; pbl=…0fee
pbl–pal=1
(int)pac–(int)pbc=1 | (int)pbl–(int)pal=-4
“Обратный” порядок размещения объектов в памяти объясняется тем, что на этапе компиляции имена объектов, требующих распределения памяти, помещаются в стек. На этапе выполнения программы они извлекаются в обратном порядке.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.