Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab_cpp.doc
Скачиваний:
10
Добавлен:
07.06.2015
Размер:
2.81 Mб
Скачать

Основные операции с указателями

Наиболее важные операции с указателями: операция обращения по адресу "*" (называется также разыменованием указателя, разадресацией, операцией косвенной адресации) и операция определения адреса "&". Операция обращения по адресу служит для доступа к данным описанного типа, т.е. для присвоения и считывания данных.

Пример:

int*x; int d; // не путать разадресацию со звёздочкой при объявлении указателя

int у = *х // у = 4;

В первой строке переменной-указателю х присваивается адрес, где хранится значение переменной d во второй строке переменной у присваивается разыменованное значение указателя х, т.е. значение 4. Если первую операцию написать без адреса, т.е. х = d х объявлен как int*x), то х будет указывать на ячейку памяти с адресом ??:4 (?? - в зависимости от модели памяти) и значение переменной у будет равно значению, которое хранится по указанному адресу.

Операция определения адреса & возвращает адрес памяти своего операнда (переменной, константы, функции и т. д.). Формат получения адреса следующий:

адрес = & переменная;

Пример: int x, *y; y = &a; // указатель y содержит адрес х

Кроме того, указатели можно присваивать друг другу, если они одного типа.

Пример: int a, *x, *y; x =y;

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

Указатели и целые величины

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

char*a = "Slovo", c;

c = *(a+3); // c = 'v'

char*a, *b = "ABCDE";

a = b + 2; c = *(- - a;

char k = *a; int d = b-a)

Динамическое размещение указателей в памяти

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

Выделение (если есть возможность) памяти и присвоение её адреса указателю, по которому можно работать с описанным типом осуществляется библиотечной функцией malloc ( ) или alloc(), (заголовочный файл <mem.h>), которую необходимо предварительно включить в программу директивой # include. Эти функции при последующих выделениях памяти предотвращают конфликты между указателями.

Формат использования данной функции:

указатель = (тип_указателя*) malloc (размер_выделяемой_памяти_байт);

Указатель на один тип может быть преобразован в указатель на другой тип. При этом обеспечивается возможность преобразования указателя на объект данного размера в указатель на объект меньшего размера в указатель на объект меньшего размера и обратного без изменений.

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

double*dp;

d = (double*) malloc (sizeof(double)); // функция malloc () выделяет память

free dp: *dp = 22. / 7.0 // освобождение динамических выделений памяти.

При использовании функции обеспечивается преобразование возвращаемого значения из указателя на тип void в указатель на тип double.

Пример

/* ЗАНЯТИЕ N 8

Выполнил студент группы ......... Петров Ю.В.

Применение указателей при работе с переменными

различных типов, изменение значений переменных по адресу

и по ссылке. Примеры операций с указателями */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <alloc.h>

int a; //Объявление глобальной переменной типа int

int main(void)

{char c1,c2,buf[20]; //buf-указатель на тип char

char *pc;

char *pst="\"slovo\"";//Объявление указателей на тип char

int *pi= &a;

float *pf, f=26.6; //Объявление указателя на тип float

double *pd, d; //Объявление указателя на тип double

double &sd= d; //Объявление ccылки на тип double

void *pv; //Объявление указателя на тип void

char *pchar=(char *)malloc(20);//Выделение памяти в куче

clrscr(); // Объявление функции void *malloc(size_t size);

pc=&c1; pf=&f; pd=&d;

printf(" Ввод переменной c1 типа char: ");

scanf("%c",pc); //Функция ввода данных, & - операция взятия

//адреса отсутствует

printf(" Вывод переменной c1 типа char: ");

printf("%c\n",*pc);

fflush(stdin);

pc=&c2;

printf(" Ввод переменной c2 типа char: ");

scanf("%c",pc); //Функция ввода данных, & - операция взятия

//адреса отсутствует

printf(" Вывод переменной c2 типа char: ");

printf("%c\n",*pc);

printf("\n Ввод переменной (a) типа int: ");

scanf("%d",pi);

a+=5; ++*pi; //Изменение а = а+5+1

printf(" \t Вывод (a) после изменения а=а+5+1\n");

printf(" Формат вывода (int): +6d #6o #8x\n");

printf("\t\t |%+6d|%#6o|%#8x|\n ",a,*pi,*pi);

printf("\n Вывод исходной cтроки: %s\n",pst);

pc=pst;

printf(" Вывод cтроки в цикле:\n");

while(*pc!='\0') { printf(" %s",pc); pc++; }

printf("\n Ввод cтроки в массив: ");

scanf("%s",buf);

pv=buf; //Использование указателя (pv) на тип void

printf(" Вывод cтроки из массива: %s\n",(char *)pv); //pv -void

printf(" Ввод cтроки в динамическую память: ");

scanf("%s",pchar);

printf(" Вывод cтроки из динамической памяти: %s\n",pchar);

printf(" Ввод переменных типа float and double (через пробел):\n");

printf("\t\t ");

scanf("%f %lf",pf,pd);

pv=pf; //Использование указателя (pv) на тип void

*pf=*(float *)pv*10; //f*=10;

*pd=sd+*(float *)pv; //Использование ccылки (sd) на тип double

pv=pd; //d+=f;

printf("\t Вывод результатов расчета f*=10 d+=f\n");

printf(" Формат вывода (float): 10.6f 10.6e +10.6g\n");

printf("\t\t |%10.6f|%10.6e|%+10.6g|\n",f,*pf,*pf);

printf(" Формат вывода (double): 10.8lf 10.8e 10.8g\n");

printf("\t\t |%10.8lf|%10.8e|%+10.8g|\n ",*pd,*(double *)pv,sd);

getche();

return 0;

}

/* Ввод переменной c1 типа char: w

Вывод переменной c1 типа char: w

Ввод переменной c2 типа char: t

Вывод переменной c2 типа char: t

Ввод переменной (a) типа int: 40

Вывод (a) после изменения а=а+5+1

Формат вывода (int): +6d #6o #8x

| +46| 056| 0x2e|

Вывод исходной cтроки: "slovo"

Вывод cтроки в цикле:

"slovo" slovo" lovo" ovo" vo" o" "

Ввод cтроки в массив: unsigned

Вывод cтроки из массива: unsigned

Ввод cтроки в динамическую память: dinamo

Вывод cтроки из динамической памяти: dinamo

Ввод переменных типа float and double (через пробел):

1.5 20.4

Вывод результатов расчета *pf=*pf*10; *pd=*pd+f;

Формат вывода (float): 10.6f 10.6e +10.6g

| 15.000000|1.500000e+01| +15|

Формат вывода (double): 10.8lf 10.8e 10.8g

|35.40000000|3.54000000e+01| +35.4|

*/

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