
- •Московский государственный институт пищевой промышленности
- •Type * имя указателя;
- •Int **p7; //неинициализированный указатель на объект типа int * // р7 – указатель на указатель
- •1.2. Типы указателей и операции над ними
- •Операция разыменования
- •Операция преобразования типов
- •Операция присваивания
- •Операция получения адреса указателя
- •Операция сложения и вычитания
- •Операции отношений (операции сравнений)
- •1.3. Массивы Массивы и переменные с индексами
- •Int z[100]; // одномерный массив из 100 элементов типа int char s[80]; // одномерный массив из 80 элементов типа char (строка) float y[3][4];// двумерный массив из 12 элементов типа float
- •Задача – 1
- •Математическая постановка задачи
- •Задача – 2
- •Математическая постановка задачи
- •Инициализация массивов
- •Массивы и указатели
- •Динамические массивы
- •2. Функции, передача параметров
- •2.1.Определение функции
- •Void Sum(float *s,float *X, int n); //прототип функции Sum
Операция преобразования типов
Операция приведения типа (type) применяется как к самим указателям, так и к объектам, на которые они указывают. Приведение типа для указателей используется как в явном, так и в неявном виде (по умолчанию). Рассмотрим применение операций приведения на примере программы, представленной ниже.
// program-1
# include<stdio.h>
# include<conio.h>
void main ()
{ unsigned long L = 0x12345678L;
char *cp = (char *)&L;
int *ip = (int *)&L;
long *lp = (long *)&L;
void *vp;
int x = 25;
float y = 1.2345;
clrscr();
printf ("&L = %x \n", &L);
printf ("cp = %x *cp = %x \n", cp, (int)*cp);
printf ("ip = %x *ip = %x \n", ip, (int)*ip);
printf ("lp = %x *lp = %lx \n", cp, (long)*lp);
vp = &x;
printf (" *vp = %d \n", * (int*)vp);
vp = &y;
printf (" *vp = %7.4f \n", * (float*)vp);
getch();
}
Результат выполнения этой программы (в каждой конкретной реализации транслятора вместо fff2 возможно другое значение адреса):
&L = fff2 cp = fff2 *cp = 78 ip = fff2 *ip = 5678 lp = fff2 lp = 12345678 *vp = 25 * vp = 1.2345
В программе используются четыре указателя cp, ip, lp, vp. Все они разных типов, а первые три настраиваются на участок памяти, занятый переменнойLтипаunsigned long. Спрашивается можно ли было инициироватьcр операторомchar *cp = &L;? Нет, этот оператор вызовет ошибку при трансляции. Дело в том, что cp – это указатель типаchar *,а операция&Lформирует адрес переменнойL, т. е. формирует указатель, значение которого равно адресу участка памяти, занимаемого переменнойL. Но какого типа это будет указатель? ПосколькуL– переменная типаunsigned long, то этот указатель будет типаunsigned long *,а это значит, что в оператореchar *cp = &L;делается попытка присвоить указателю типаchar *значение указателя типаunsigned long *.А это недопустимо! Поэтому в данном случае используется явное преобразование типов и оператор записывается в следующем виде :
char *cp = (char *)&L; В этом операторе операция (char *) приводит указатель &L к типу char *. Аналогично написаны операторы инициации переменных ip, lp. Итак, операторы
char *cp = (char *)&L;
int *ip = (int *)&L;
long *lp = (long *)&L;
настраивают три указателя разных типов на один и тот же участок памяти. Именно поэтому при печати мы видим, что все они имеют одно и то же значение fff2 – адрес размещения переменной L (см. рис. 2).
Печать же содержимого полей (*cp, *ip, *lp), на которые указывают cp, ip, lp, происходит в соответствии с типом указателей, который определяет количество байтов, рассматриваемых при выводе информации (еще раз см. рис.2).
Явное преобразование типов при работе с разными указателями в одном выражении необходимо для всех указателей кроме указателей типа void *. При использовании указателей типа void * операция приведения типа выполняется по умолчанию (указателю типа могу присваиваться значения любых указателей). Указатель типа void * отличается от других указателей отсутствием сведений о размере соответствующего ему участка памяти. Указатель типа void * создан “на все случаи жизни”, но для его применения всегда следует использовать приведение типов. Возможность “связывания” указателя void * с объектами разных типов демонстрируется в программе с помощью переменной vp. Сначала vp настраиваем на переменную х (оператор vp = &x;). Но при этом указатель vp “не знает”, на какого типа поле он указывает. Поэтому при выводе информации (оператор printf (" *vp = %d \n", * (int*)vp); ) выводимая информация указывается в виде * (int*)vp. Разберем более подробно это выражение. В нем vp – это указатель типа void *, (int*)vp – это уже указатель типа (int*), а * (int*)vp – это уже содержимое поля, на которое настроен указатель типа int*. Аналогично операторами
vp = &y;
printf (" *vp = %7.4f \n", * (float*)vp);
переменная vpнастраивается на область, выделенную дляу(операторvp = &y;), а далее операторомprintfвыводится на экран значение этой области в соответствии с форматом%7.4f.