- •Максимов м.Н.
- •3. Скалярные типы и выражения 51
- •5. Адреса, указатели, массивы, память 96
- •6. Функции, указатели, ссылки 133
- •7 Структуры, объединения и классы 171
- •Введение
- •Модуль 1
- •1.2. Этапы подготовки исполняемой программы
- •1.3. Системы счисления
- •Представление чисел от 0 до 16 в разных системах счисления
- •2.1. Общие сведения о программах, лексемах и алфавите
- •2.2. Идентификаторы и служебные слова
- •2.3. Типы данных
- •2.4. Константы
- •Типы, выбираемые компилятором по умолчанию для целых констант
- •ZzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzТаблица 2.3 Данные вещественного типа
- •2.5. Операции
- •2.6. Разделители
- •3. Скалярные типы и выражения
- •3.1. Определение и описание переменных
- •3.2. Явное и неявное преобразование типа
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Список литературы
- •Модуль 2
- •4.1. Последовательно выполняемые операторы
- •4.2. Операторы выбора
- •If( выражение) оператор_1 else оператор_2
- •4.3. Операторы цикла
- •4.4. Операторы передачи управления
- •If (условие) break;
- •4.5. Примеры численного моделирования цепей первого порядка
- •5. Адреса, указатели, массивы, память
- •5.1. Указатели и адреса объектов
- •5.2. Адресная арифметика, типы указателей и операции над ними
- •5.3. Свойства указателя типа void*
- •5.4. Свойства объекта cout
- •5.5. Массивы и указатели
- •5.6. Многомерные массивы, массивы указателей, динамические массивы
- •Проектные задания к модулю
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •6.2. Функции с переменным количеством параметров
- •6.3. Рекурсивные функции
- •6.4. Подставляемые (инлайн-) функции
- •6.5. Функции и массивы
- •6.6. Указатели на функции
- •Void f3(float) (...) // Определение функции
- •Int* f4(char *){...} // Определение функции
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Модуль 4
- •7 Структуры, объединения и классы
- •7.1 Структура как тип и совокупность данных
- •7.3 Объединения разнотипных данных
- •7.4 Деревья
- •7.5 Битовые поля структур и объединений
- •7.6 Компонентные функции структурированных объектов
- •7.7 Расширение действия (перегрузка) стандартных операций
- •7.8 Доступ к компонентам структурированного объекта
- •7.9 Классы и шаблоны
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Список литературы
- •Приложение 1
- •Приложение 2 Стандартная библиотека функций языка Си
5.3. Свойства указателя типа void*
Тип void (пустота, пробел) является основным типом языка программирования Си++, но в отличие от других основных типов с помощью ключевого слова void нельзя создать объект типа void. В основном ключевое слово voidиспользуется для того, чтобы указать на отсутствие параметров функции и/или возвращаемого функцией значения. Например:
void printStr(void){ cout<<“Здравствуй Мир!!”;}
Эта функция не принимает никаких параметров и не возвращает никакого значения.
Указатель типа void* это четырехбайтовый объект, предназначенный для хранения адреса любого типа объектов или адреса фрагмента памяти, т.е. он может указывать на всё что угодно. С этим указателем не связывается информация о том, какой объект находится в памяти, начиная с записанного в нем адреса. Именно поэтому нельзя применить к указателю типа void* операцию доступа по адресу (*). У компилятора нет информации, сколько байт отведено под объект, на который указывает указатель типа void*, и как информацию в этих байтах интерпретировать. Указатель типа void* единственный тип указателя, для которого определено преобразование типа по умолчанию. Пример:
void* buf; //Определение указателя buf типа void*.
inta= 5;
doublek= 5.5;
buf = &a; /*Преобразование типа по умолчанию. На самом деле выполняется выражение buf = (void*)&a; компилятор по умолчанию добавляет (void*). В buf записывается адрес переменной а. И теперь только программист знает, что buf указывает на объект типа int. */
cout<<*buf; /*ошибка, операция разыменования не определена над указателями типа void*/
cout<<(*(int*) buf); /*Явное преобразование типа. Создаётся неименованный указатель типа int, который инициализируется адресом, хранящимся в buf. К неименованному указателю int* применяется операция разыменования и на экране печатается значение переменной a.*/
buf = &k; /*Преобразование типа по умолчанию. В buf записывается адрес переменной k.*/
cout<<*(double*)buf;//На экране печатается значение переменной k.
cout<<*(int*) buf; /*На экране печатается неизвестно, что, так как buf в данный момент указывает на объект типа double, а не на объект типа int.*/
double * pd; // определение указателя pd типа double*
pd = buf; /*Ошибка. Операция неявного преобразования типа над указателями типа double* не определена. Компилятор выдаст сообщение «Не могу переконвертировать void* в double*.*/
pd= (double*)buf;//Ошибки нет. Явное преобразование типа.
cout<< *pd; //Печать значения переменной k
При определении указателя как он сам, так и объект, на который он указывает, могут быть определены как константы.
Таблица 5.1
Способы определения указателя
1 |
type* имя_указателя = инициализатор; ни указатель, ни объект, на который он указывает, константами не являются, их можно изменять |
int i = 1; int* pi = &i; pi = 2; /* операция разрешена, pi указывает не на константу; pi = pi +1; операция разрешена, pi не константа */
|
2 |
type* const имя_указателя = инициализатор; указатель является константой т.е. его нельзя перестроить на другой объект; объект, на который настроен указатель, изменить можно |
int i = 1; int* const pi = &i; *pi = 2;ошибки нет, значение переменной i изменено с помощью указателя pi (i = 2); pi = pi +1; ошибка, значение указателя константа, его изменить нельзя |
3 |
type const* имя_указателя = инициализатор; указатель не является константой; объект, на который настроен указатель, изменить нельзя он константа |
int i = 1; int* const pi = &i; *pi = 2;ошибка, значение переменной i изменить с помощью указателя нельзя; pi = pi +1; операция разрешена pi не константа |
4 |
type const * const имя_указателя = инициализатор; указатель и объект, на который он указывает являются константами их изменить нельзя |
int i = 1; int const* const pi = &i; *pi = 2;ошибка, значение переменной i изменить с помощью указателя нельзя; pi = pi +1; ошибка, pi константа |