Операции с указателями
С указателями м. производить след. операции: присваивания, арифметические отношения.
Операция присваивания для указателей аналогична эт. операции для др. типов данных. В отличии от др. типов, при операции присваивания , достаточно, чтобы оба операнда были типа «указатель», но типы этих указателей м.б. различными
Напр-р, …
int a;
int *p=&a, *p1;
*p=8 /* значение 8 заносится по адресу р, т.е. значение переменой а=8*/
р1=р /*переменной р1=р, т.е адрес переменной а*/
Арифм. операции. Допустимы операции +,-(соответственно +=,-=),++,--.
Арифметические действия с указателями учитывают тип переменной на кот. они указывают.
Эти операции изменяют адрес указателя на величину пропорциональную размеру типа данных
напр-р
float f,*pf;
/* указатель на веществ. число, в памяти вещ. занимает 4 байта */
pf=&f; / * напр-р, переменная f хранится по адресу 200, тогда pf=200
pf--; / * pf=196*/
pf+=9; / * pf=196+4*4=212*/
Арифметические операции с указателями (сложение с константой, вычитание, инкремент и декремент) автоматически учитывают размер типа величин, адресуемых указателями. Эти операции применимы только к указателям одного типа и имеют смысл в основном при работе со структурами данных, последовательно размещенными в памяти, например, с массивами.
Инкремент перемещает указатель к следующему элементу массива, декремент — к предыдущему. Фактически значение указателя изменяется на величину sizeof(тип). Если указатель на определенный тип увеличивается или уменьшается на константу, его значение изменяется на величину этой константы, умноженную на размер объекта данного типа, например:
Выражение (*p)++, напротив, инкрементирует значение на которое ссылается указатель.
Пример:
#include <stdio.h>
#include <conio.h>
main()
{ char *s,s1[10];
scanf("%s",s1);
s=s1;
printf("%c \n",*s);
s+=4;
printf("%c",*s);
s++;
printf("%c",*s);
s++;
printf("%c",*s);
getche();}
Операции отношения. Для указателей опр-ся след. операции отношения: = =, >=, <=, >,<, !=.
р1==р2 рез-т =1, если р1 и р2 указывают на один и тот же объект в опер. памяти
р1 >=р2 рез-т =1, если *р1 расположен в памяти правее (т.е. с большим адресом) чем р2
<=,
>
,<
, !=.
Унарная операция получения адреса & применима к величинам, имеющим имя и размещенным в оперативной памяти. Таким образом, нельзя получить адрес скалярного выражения, неименованной константы или регистровой переменной. Примеры операции приводились выше.
Указатель типа void *
Такой указатель исп-ся для доступа к любым типам данных. Указатель типа void указывает на место в операт. памяти и не содержит инф-ции о типе объекта, т.е. он указывает не на сам обьект, а на его возможное расположение. К указателю типа void не применяются арифм операции.
Массивы
При использовании простых переменных каждой области памяти для хранения данных соответствует свое имя. Если с группой величин одинакового типа требуется выполнять однообразные действия, им дают одно имя, а различают по порядковому номеру. Это позволяет компактно записывать множество операций с помощью циклов.
Массивом называется конечная упорядоченная именованная последовательность однотипных величин, к которым обращаются с помощи одного имени
Описание массива в программе отличается от описания простой переменной наличием после имени квадратных скобок, в которых задается количество элементов массива (размерность):
тип_элементов имя_массива[размерность]
float а [10]; // описание массива из 10 вещественных чисел
ВНИМАНИЕ
При описании массивов квадратные скобки являются элементом синтаксиса, а не указанием на необязательность конструкции.
Элементы массива нумеруются с нуля.
Можно инициализировать массив при описании
Правила инициализации
1-Инициализирующие значения для массивов записываются в фигурных скобках и разграничиваются запятыми.
2- Значения элементам присваиваются по порядку, начиная с нулевого.
3- Количество значений д.б. не более размерности
4. Если элементов в массиве больше, чем инициализаторов, элементы, для которых значения не указаны, обнуляются:
int b[5] = {3, 2, 1}; // b[0]=3. b[l]=2. b[2]=l, b[3]=0, b[4]=0
Размерность массива вместе с типом его элементов определяет объем памяти, необходимый для размещения массива, которое выполняется на этапе компиляции, поэтому размерность может быть задана только целой положительной константой или константным выражением.
Размерность массивов предпочтительнее задавать с помощью именованных констант, поскольку при таком подходе для ее изменения достаточно скорректировать значение константы всего лишь в одном месте программы.
Если при описании массива не указана размерность, должен присутствовать инициализатор, в этом случае компилятор выделит память по количеству инициализирующих значений.
Для доступа к элементу массива после его имени указывается номер элемента (индекс) в квадратных скобках.
имя_массива[индекс]
В следующем примере подсчитывается сумма элементов массива.
#i include <iostream.h>
int main()
{
const int n = 10;
int i, sum;
int marks[n] = {3, 4, 5, 4, 4};
for (i = 0, sum = 0; i<n; i++)
sum += marks[i];
cout <<"Сумма элементов: " <<sum;
return 0;
}
Обратите внимание, что последний элемент массива имеет номер, на единицу меньший заданной при его описании размерности.
ВНИМАНИЕ
При обращении к элементам массива автоматический контроль выхода индекса за границу массива не производится, что может привести к ошибкам
Процесс обмена элементов массива с номерами i и imin через буферную переменную а на 1-м проходе цикла проиллюстрирован на рис. Цифры около стрелок обозначают порядок действий.
Дата добавления: 2017-01-13; просмотров: 744;