Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab_C-04.doc
Скачиваний:
1
Добавлен:
21.11.2019
Размер:
88.58 Кб
Скачать

Размер указателя и указываемого объекта

В языке Си указатели — это переменные, которые предназначены для хранения адресов объектов программы.

Как любые переменные, указатели должны быть определены. Они могут быть определены или объявлены на внешнем (глобальном) или внутреннем (локальном) уровнях, иметь любой из классов памяти, ссылаться на любой тип данных.

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

Результатом выполнения операции разадресации указателя является значение объекта, на который он ссылается. И, чтобы оперировать с этим значением, компилятору недостаточно знать адрес, ему нужно знать тип объекта.

Поэтому при определении указатели связываются с определенным типом данных, и их характеризуют как "указатель на <тип_данных>". Здесь <тип_данных> — это любой базовый или производный тип.

Например, определение float *px; вводит в программу объект px, имеющий тип "указатель на float".

Замечание

Реальный размер указателя (как переменной) в байтах зависит от используемого адресного пространства. В 16-разрядных приложениях для операционной системы MS-DOS размер адресного пространства для хранения данных и кода определяется специальным параметром компилятора — моделью памяти. Модель памяти в BC++ 3.1 устанавливается в пункте меню

Options | Compiler | Code Generation...

Например, в модели памяти Small для данных используются двухбайтовые адреса, а в модели Large — четырехбайтовые.

ЗАДАНИЕ 2 (адресная арифметика)

Написать программу, в которой определяются переменные типов char, int, double.

Для каждой переменной программа выводит (в строку) ее адрес и значения выражений "адрес + 2" и "адрес – 1" (какой тип имеют эти значения?).

В отчете результаты привести в виде таблицы с колонками

Tip (тип)

adr (адрес)

adr + 2

adr –1

char

. . .

. . .

. . .

. . .

. . .

. . .

. . .

Пояснить полученные результаты.

Замечания

1. Для вывода на экран адресов в форматной строке функции printf необходимо использовать спецификацию %p (от pointer — указатель).

2. Вычисляемые выражения adr+2 и adr-1 не имеют практического смысла, они используются только для проверки правил адресной арифметики. Осмысленное использование адресной арифметики потребуется при выполнении задания 3.

Операция приведения типа

Приведение типа — это представление данных одного типа как данных другого типа. Приведение типа часто предусматривается компилятором неявно. Например, при вычислении z

int x=3;

float y=0.15, z;

z=x+y;

компилятор сначала приведет операнды к одному типу, и только потом сложит их. По умолчанию он выполняет только безопасные преобразования, несвязанные с потерей информации. Очевидно, преобразование от более короткого (int) к более длинному типу (float), является безопасным.

Помимо этого, в программах может потребоваться выполнять явные преобразования, которые указываются программистом с помощью операции приведения типа.

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

(<тип_данных>) выражение.

Операция приведения типа является унарной.

Ее результат вычисляется как значение операнда (выражения), представленное в ввиде заданного преобразованием типа.

При этом само выражение не меняется. Например, в условиях приведенного примера при вычислении выражения (float)x значение x не изменится (т.е. останется 3), но результатом вычисления будет 3.0.

Приводимое выражение может иметь любой базовый или производный тип, в том числе и адресный.

Замечание

Явные преобразования могут быть достаточно произвольными, например, предусматривать потенциально опасные действия, такие как "укорачивание" данных (преобразование значения типа long к типу int и т.п.). За осмысленность явных преобразований ответственность несет программист.

ЗАДАНИЕ 3

1. Проверить, какие результаты будут получены при выполнении следующего фрагмента программы, и объяснить, почему (файл lab4_2.c)?

int x=8, y=3;

float z1, z2;

z1=x/y;

z2=(float)x/y;

printf("x/y=%f\n",z1);

printf("(float)x/y=%f\n",z2);

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