Лексические основы языка C ++. Алфавит и лексемы языка C++. Операторы C++. Массивы и указатели, страница 7

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

     “Обратный” порядок размещения объектов в памяти объясняется тем, что на этапе компиляции имена объектов, требующих распределения памяти, помещаются в стек. На этапе выполнения программы они извлекаются в обратном порядке.