Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет53/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   49   50   51   52   53   54   55   56   ...   256
Байланысты:
Бьерн Страуструп. Язык программирования С . М Бином, 2011

2.3.4 Тип void 
Тип void синтаксически эквивалентен основным типам, но использовать его можно только в 
производном типе. Объектов типа void не существует. С его помощью задаются указатели на объекты 
неизвестного типа или функции, невозвращающие значение. 
void f();
// f не возвращает значения 
void* pv;
// указатель на объект неизвестного типа 
Указатель произвольного типа можно присваивать переменной типа void*. На первый взгляд этому 
трудно найти применение, поскольку для void* недопустимо косвенное обращение (разыменование). 
Однако, именно на этом ограничении основывается использование типа void*. Он приписывается 
параметрам функций, которые не должны знать истинного типа этих параметров. Тип void* имеют также 
бестиповые объекты, возвращаемые функциями. Для использования таких объектов нужно выполнить 
явную операцию преобразования типа. Такие функции обычно находятся на самых нижних уровнях 
системы, которые управляют аппаратными ресурсами. Приведем пример: 


Бьерн Страуструп.
Язык программирования С++ 
 
53 
void* malloc(unsigned size); 
void free(void*); 
void f() // распределение памяти в стиле Си 

int* pi = (int*)malloc(10*sizeof(int)); 
char* pc = (char*)malloc(10); 
//... 
free(pi); 
free(pc); 

Обозначение: (тип) выражение - используется для задания операции преобразования выражения к 
типу, поэтому перед присваиванием pi тип void*, возвращаемый в первом вызове malloc(), 
преобразуется в тип int. Пример записан в архаичном стиле; лучший стиль управления размещением в 
свободной памяти показан в $$3.2.6. 
2.3.5 Указатели 
Для большинства типов T указатель на T имеет тип T*. Это значит, что переменная типа T* может 
хранить адрес объекта типа T. Указатели на массивы и функции, к сожалению, требуют более сложной 
записи: 
int* pi; 
char** cpp;
// указатель на указатель на char 
int (*vp)[10]; 
/
/ указатель на массив из 10 целых 
int (*fp)(char, char*); 
// указатель на функцию с параметрами 
// char и char*, возвращающую int 
Главная операция над указателями - это косвенное обращение (разыменование), т.е. обращение к 
объекту, на который настроен указатель. Эту операцию обычно называют просто косвенностью. 
Операция косвенности * является префиксной унарной операцией. Например: 
char c1 = 'a'; 
char* p = &c1; 
// p содержит адрес c1 
char c2 = *p; 
// c2 = 'a' 
Переменная, на которую указывает p,- это c1, а значение, которое хранится в c1, равно 'a'. Поэтому 
присваиваемое c2 значение *p есть 'a'. Над указателями можно выполнять и некоторые 
арифметические операции. Ниже в качестве примера представлена функция, подсчитывающая число 
символов в строке, заканчивающейся нулевым символом (который не учитывается): 
int strlen(char* p) 

int i = 0; 
while (*p++) i++; 
return 
i; 

Можно определить длину строки по-другому: сначала найти ее конец, а затем вычесть адрес начала 
строки из адреса ее конца. 
int strlen(char* p) 

char* q = p; 
while (*q++) ; 
return 
q-p-1; 

Широко используются указатели на функции; они особо обсуждаются в $$4.6.9 


Достарыңызбен бөлісу:
1   ...   49   50   51   52   53   54   55   56   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет