Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций -=Вычислительная техника и прог...docx
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
1.84 Mб
Скачать

3.4.3. Составные указатели

Пример:

Здесь объявляется массив из 10 указателей на функции без параметров, возвращающих указатели на int.

По умолчанию скобки [] и () имеют одинаковый приоритет, больший, чем * и рассматриваются слева направо. Для изменения порядка используют круглые скобки. Таким образом, порядок приоритета в приведенном примере составного указателя показан цифрами снизу.

Для сложных описаний используют правило «изнутри наружу»:

1) если справа от имени '[]' — это массив,

если '()' — функция;

2) если слева '*', то это указатель на проинтерпретированную ранее конструкцию;

3) если справа встречается ')', то необходимо применить приведённые выше правила внутри скобок, а затем переходить наружу;

4) в последнюю очередь интерпретируется спецификатор типа.

3.4.4. Операции над указателями

Над указателями разрешается выполнять следующие операции:

— реадресация или косвенное обращение к объекту (*);

— присваивание;

— сложение с константой;

— вычитание;

— инкремент (++);

— декремент (– –);

— сравнивание;

— приведение типов.

Кроме выше перечисленных операций, часто используется операция взятия адреса (&).

Операция реадресации — предназначена для доступа к величине, адрес которой хранится в указателе. Операцию можно использовать для получения и изменения величины.

Пример:

char a ; // объявление переменной типа char

char *p=new char ; // выделение памяти под указатель и

// под динамическую переменную типа char

*p=''Ю'' ; a=*p ; // присваивание значения обеим переменным

На одну и ту же область памяти может ссылаться несколько указателей различных типов.

Пример:

unsigned long int A=0Xcc77ffaa ;

unsigned short int *p_int=(unsigned short int*) &A ;

unsigned char *p_char=(unsigned char *) &A;

printf(''| %x | %x | %x |'' , A , *p_int , *p_char);

… }

Результат выполнения:

| cc77ffaa | ffaa | aa |

Примечание.

Присваивание без приведения типов допускается для указателей:

— типа void*;

— одного типа.

Арифметические операции с указателями — сложение с константой, вычитание, инкремент, декремент.

Операции применимы только к указателям одного типа и имеют смысл при работе со структурами данных (массивами).

Операции автоматически учитывают размер типов величин, адресуемых указателями.

Операции умножения, деления или сложения указателей не существует!

Инкремент — ++ перемещает указатель к следующему элементу структуры данных (массива).

Декремент — – – перемещает указатель к предыдущему элементу.

Значение указателя изменяется на величину sizeof(тип) в байтах.

Пример:

short *p=new short[5] ; //объявление указателя на массив

p++ ; // массив p увеличивается на 2 (байта)

long *q=new long[5] ; // объявление указателя на массив

q++ ; // q увеличивается на 4 (байта)

Разность двух указателей — это разность их значений, делённая на размер типа в байтах.

Например, разность указателя на 3-й элемент массива и на 6-й элемент равна 3.

При сложении с константой или других действиях следует учитывать приоритеты выполнения операций.

Пример:

1) *p++=10 ; /*  */ *p=10 ; p++ ;

// Два одинаковых по смыслу выражения,

// в которых вначале по адресу *p запишется 10,

// а потом указатель увеличивается на 1xsizeof(тип).

2) (*p)++; // Выражение увеличивает содержимое ячейки памяти.

Операция получения (взятия) адреса & — применима к величинам, имеющим имя и размещенным в ОЗУ.

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