Программирование >>  Структурное программирование 

1 ... 113 114 115 [ 116 ] 117 118 119 ... 342


Демонстрация операции sizeof tinclude <iostream.h>

main() {

int array[20],

*ptr = array;

cout

sizeof(char) =

sizeof(char) << endl

<<

sizeof(short) =

sizeof(short) << endl

sizeof(int) =

sizeof (int) << endl

sizeof(long) =

sizeof (long) << endl

sizeof (float) =

sizeof(float) << endl

<<

sizeof(double) =

sizeof(double) endl

<<

sizeof(long double) =

sizeof (long double) << endl

sizeof array =

sizeof array << endl

sizeof ptr =

sizeof ptr endl

endl ;

return 0;

sizeof(char) = 1 sizeof(short) = 2 sizeof(int) = 2 sizeof(long) = 4 sizeof(float) = 4 sizeof (dovible) = 8 sizeof (long dovible) = 10 sizeof array = 40 sizeof ptr = 2

Рис. 5.17. Использование операции sizeof для определения размеров аандартных типов

данных

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

Типичная ошибка программирования 5.5

Пропуск скобок в операции sizeof, когда операндом является имя типа, вызывает синтаксическую ошибку.

5.7. Выражения и арифметические действия

с указателями

Указатели могут применяться как операнды в арифметических выражениях, выражениях присваивания и выражениях сравнения. Однако, не все операции, обычно используемые в этих выражениях, разрешены применительно к переменным указателям. Этот раздел описывает, какие операции могут иметь в качестве операндов указатели и как эти операции используются.



С указателями может выполняться ограниченное количество арифметических операций. Указатель можно увеличивать (++), уменьшать (~), складывать с указателем целые числа (-f- или -1-=), вычитать из него целые числа (- или -=) или вычитать один указатель из другого.

Допустим, что объявлен массив int v[10] и его первый элемент находится в памяти в ячейке 3000. Допустим, что указателю vPtr было присвоено начальное значение путем указания на v[0], т.е. значение vPtr равно 3000. Рис. 5.18 схематически отображает эту ситуацию для машины с 4-байтовыми целыми. Заметим, что указателю vPtr можно было дать начальное значение указанием на массив v с помощью одного из следующих операторов

vPtr = v; vPtr = &v[0];

ячейка

3000 3004 3008 3012 3016


v[0]

v[l]

v[2]

v[3]

v[4]

переменная указатель vPtr

Рис. 5.18. Массив v и переменная указатель vPtr, указывающая на v

Замечание по мобильности 5.3

Большинство современных компьютеров имеет 2-х или 4-х байтовые целые. Некоторые из более новых машин имеют 8-байтовые целые. Поскольку результат арифметических действий с указателями зависит от размера объектов, на которые указывает указатель, арифметические действия с указателями являются машин-нозависимыми.

В общепринятой арифметике сложение 3000 + 2 дает значение 3002. Это нормально, но не в случае арифметических действий с указателями. Когда целое складывается или вычитается из указателя, указатель не просто увеличивается или уменьшается на это целое, но это целое предварительно умножается на размер объекта, на который ссылается указатель. Количество байтов зависит от типа данных. Например, оператор

vPtr += 2;

выработал бы значение 3008 (3000 -I- 2 * 4) в предположении, что целое хранится в 4 байтах памяти. В массиве v указатель vPtr теперь указал бы на v[2] (рис. 5.19). Если целое хранится в 2 байтах памяти, то предыдущие вычисления имели бы результатом в памяти ячейку 3004 (3000 -f- 2 * 2). Если бы массив имел другой тип данных, предыдущий оператор увеличивал бы указатель на количеством байтов, вдвое превышающее число байтов, необхо-



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

Если указатель vPtr был увеличен до значения 3016, указывающего на v[4], оператор

vPtr -= 4;

вернул бы vPtr обратно к значению 3000 - к началу массива. Если указатель увеличивается или уменьшается на 1, можно использовать операции инкремента (++) или декремента (-). Каждый из операторов

++vPtr; vPtr ++;

увеличивает указатель так, что он указывает на следующий элемент массива. Каждый из операторов

-vPtr; vPtr-;

уменьшает указатель так, что он указывает на предыдущий элемент массива.

ячейка

3000 3004 3008 3012 3016

v[0]

v[l]

v[2]

v[3]

v[4]

переменная указатель vPtr

Рис. 5.19. Указатель vPtr после выполнения арифметических действий над указателями

Переменные указатели можно вычитать один из другого. Например, если vPtr содержит ячейку 3000, а v2Ptr содержит адрес 3008, оператор

X = v2Ptr - vPtr;

присвоит X значение разности номеров элементов массива, на которые указывают vPtr и v2Ptr, в данном случае 2. Арифметика указателей теряет смысл, если она выполняется не над массивами. Мы не можем предполагать, чтобы две переменные одинакового типа хранятся в памяти вплотную друг к другу, если они не соседствуют в массиве.

Типичная ошибка программирования 5.6

Использование арифметических дейавий с указателями, не ссылающимися на элементы массива.



1 ... 113 114 115 [ 116 ] 117 118 119 ... 342

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика