АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Использование указателей разных типов

Читайте также:
  1. III. Использование альфа-каналов
  2. MS EXCEL. Использование электронного табличного процессора excel: построение графиков. Взаимодействие excel с другими приложениями windows.
  3. V. Рабочее время и его использование
  4. Анализ относительных показателей (коэффициентов) - расчет отношений между отдельными позициями отчета или позициями разных форм отчетности, определение взаимосвязи показателей.
  5. Анализ ритмичности с использованием коэффициента вариации
  6. Анализ типов значений слова
  7. Анализ финансовой устойчивости предприятия с использованием коэффициентов.
  8. Анализ финансовой устойчивости с использованием абсолютных показателей.
  9. Антипов Юрий
  10. Безопасность и эффективность разных методов контрацепции
  11. Боксеры различных типов тактики ведения боя и способы противодействия им. Отличительные особенности их манеры ведения боя.
  12. В блок-секционной схеме законченной единицей типового проектирования жилых зданий является блок-секция – повторяющаяся часть дома, сгруппированная вокруг лестнично-лифтового узла.

Каждое выражение, как и переменная имеет свой тип и значение. Если тип выражения SintVar - указатель на переменную типа int, т.е. имеет тип int*, то его значение может быть присвоено указателю pintVar:

int* pintVar = SintVar; // обе части этого присвоения

// int* имеют тип

Аналогично, если pintVar имеет тип int*, то значение *pintVar имеет тип int, т.е. выражение

*pintVar = 10;

не содержит ошибки, т.к. его обе части имеют тип int.

Это аналогично тому, что если houseAddress является адресом дома, то его имя и значение houseAddress определяют - конкретный дом.

Указатели на переменные других типов объявляются точно так же:

double doubleVar;

double* pdouble = &doubleVar;

*pdouble = 10.0;

Размер памяти, отводимой для указателя, как правило, не зависит от типа переменной, на которую он указывает.

Важно следить за соответствием типов указателей и элементов данных, на которые они указывают. Например:

int n1;

int* pintVar;

pintVar = &n1;

*pintVar = 100.0;

Последняя строка требует, чтобы по адресу, выделенному под переменную размером в четыре байта (тип int) было записано число типа float, занимающее 8 байтов. На самом деле ничего страшного не произойдёт. Компилятор произведёт преобразование числа 100.0 к типу int перед тем, как выполнить присвоение.

Приведение переменной одного типа к другому может быть явным образом:

int iVar;

double dVar = 10.0;

iVar = (int) dVar;

Так же можно преобразовать указатель одного типа к другому:

int* piVar;

double dVar = 10.0;

double* pdVar;

piVar = (int*)pdVar;

Трудно предсказать, что может произойти, если переменные одного типа будут сохранены по адресам, выделенным под переменные другого типа. Сохранение переменных, имеющих большую длину, может привести к уничтожению переменных, расположенных рядом. Рассмотрим пример, иллюстрирующий подобную ситуацию

// LayOutError - программа демонстрирующая результат

// неаккуратного обращения с указателями

#include <windows.h>

#include <stdlib.h>

#include <string.h>

#include <tchar.h>

#include <iostream>

#include <stdio.h>

using namespace std;

int main(int intArgc, char* pszArgs[])

{

int upper =0;

int n = 0;

int lower = 0;

SetConsoleCP(1251); // руссификация ввода

SetConsoleOutputCP(1251); // и вывода

// выводим значения объявленных переменных

cout << "upper = " << upper <<"\n";

cout << "n = " << n <<"\n";

cout << "lower = " << lower <<"\n";

// сохраняем значение типа double

// в памяти, выделенной для int

cout << "\nСохранение double в int\n";

double* pD =(double*) &n;

*pD = 13.0;

// показываем результаты

cout << "upper = " << upper <<"\n";

cout << "n = " << n <<"\n";

cout << "lower = " << lower <<"\n";

cout << "pD = " << pD << "\n";

cout << "*pD = " << *pD << "\n";

return 0;

}

Результат выполнения этой программы:

В трёх первых строках функции main() объявляются три переменные типа int. Если допустить, что в памяти эти переменные находятся друг за другом, то следующие строки выводят их значения, которые, как и следовало ожидать оказываются равными нулю.

После присвоения *pD = 13.0; "число, имеющее тип double, записывается в переменную n, имеющую тип int. Затем все три переменные снова выводятся на экран." [1].

Далее, как говорится в [1], "после записи действительного числа в целочисленную переменную n переменная upper должна быть "забитой" каким-то мусором". Но в реальности вывод значений трёх переменных остались равными 0, как видно из приведённого выше листинга решения.

"Типизация указателей предохраняет программиста от неприятностей, связанных с сохранением данных большего размера в меньшем объёме памяти." [1]


1 | 2 | 3 | 4 | 5 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.)