Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры теория 113019.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
380 Кб
Скачать
☆

Void main(void)

{

W s, *p = &s;

s.a = 4;

printf(“\n Integer a = %d, Sizeof(s.a) = %d”, s.a, sizeof(s.a));

p –> b = 1.5;

printf(“\n Double b = %lf, Sizeof(s.b) = %d”, s.b, sizeof(s.b));

strcpy(p–>s, “Minsk”);

printf(“\n String a = %s, Sizeof(s.s) = %d”, s.s, sizeof(s.s));

printf(“\n Sizeof(s) = %d”, sizeof(s));

}

Результат работы программы:

Integer a = 4, Sizeof(s.a) = 2

Double b = 1.500000, Sizeof(s.b) = 4

String a = Minsk, Sizeof(s.s) = 5

Sizeof(s) = 5

Перечисления – средство создания типа данных посредством задания ограниченного множества значений.

Определение перечисляемого типа данных имеет вид

enum ID_перечисляемого_типа {

список_значений };

Значения данных перечисляемого типа указываются идентификаторами, например:

enum marks {

zero, one, two, three, four, five };

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

Основные операции с данными перечисляемого типа:

– присваивание переменных и констант одного типа;

– сравнение для выявления равенства либо неравенства.

Практическое назначение перечисления – определение множества различающихся символических констант целого типа.

48. Указатели. Указатели и адреса объектов. Указатели и массивы.

При обработке декларации любой переменной, например double x=1.5; компилятор выделяет для переменной участок памяти, размер которого определяется ее типом (double – 8 байт), и инициализирует его указанным значением (если таковое имеется). Далее все обращения в программе к переменной по име­ни заменяются компилятором на адрес участка памяти, в котором будет храниться значение этой переменной. Разработчик программы на языке Си имеет возможность определить собственные переменные для хранения адресов участков оперативной памяти. Такие переменные называются указателями.

Итак, указатель – это переменная, которая может содержать адрес некоторого объекта. Простейшая декларация указателя имеет формат

тип * ID_указателя;

Например: int *a; double *f; char *w;

Здесь тип может быть любым, кроме ссылки или битового поля.

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

Например, в декларации:

int *a, *b, с;

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

Значение указателя равно первому байту участка памяти, на который он ссылается.

Указатели предназначены для хранения адресов областей памяти. В языке Cи имеются три вида указателей – указатели на объект известного типа, указатель типа void и указатель на функцию. Эти три вида различаются как своими свойствами, так и набором допустимых операций. Указатель не является самостоятельным типом данных, так как всегда связан с каким-либо конкретным типом, т.е. указатель на объект содержит адрес области памяти, в которой хранятся данные определенного типа.

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

Указателю типа void можно присвоить значение указателя любого типа, а также сравнивать его с любыми другими указателями, но перед выполнением каких-либо действий с участком памяти, на которую он ссылается, требуется явно преобразовать его к конкретному типу.

Указатель может быть константой или переменной, а также указывать на константу или переменную.

С указателями-переменными связаны две унарные операции & и *.

Операция & означает «взять адрес» операнда. Операция * имеет смысл – «значение, расположенное по указанному адресу» (операция разадресации).

Таким образом, обращение к объектам любого типа как операндам операций в языке Cи может производиться:

– по имени (идентификатору);

– по указателю (операция косвенной адресации):

ID_указателя=&ID_объекта; – операция разыменования;

*ID_указателя – операция косвенной адресации.

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

Унарная операция получения адреса & применима к переменным, имеющим имя (ID), для которых выделены участки оперативной памяти. Таким образом, нельзя получить адрес скалярного выражения, неименованной константы или регистровой переменной (типа register).

Отказ от именования объектов при наличии возможности доступа по указателю приближает язык Си по гибкости отображения «объект – память» к языку ассемблера.

Указатели, как и переменные любого другого типа, могут объединяться в массивы.

Объявление массива указателей на целые числа имеет вид:

int *a[10], y;

Теперь каждому из элементов массива указателей a можно присвоить адрес целочисленной переменной y, например: a[1]=&y;

Чтобы теперь найти значение переменной y через данный элемент массива а, необходимо записать *a[1].

В языке Си можно описать переменную типа «указатель на указатель». Это ячейка оперативной памяти (переменная), в которой будет храниться адрес указателя на некоторую переменную. Признак такого типа данных – повторение символа «*» перед идентификатором переменной. Количество символов «*» определяет уровень вложенности указателей друг в друга. При объявлении указателей на указатели возможна их одновременная инициализация. Например:

int a=5;

int *p1=&a;

int **pp1=&p1;

int ***ppp1=&pp1;

Если присвоить переменной а новое значение, например 10, то одинаковые результаты будут получены в следующих операциях:

a=10; *p1=10; **pp1=10; ***ppp1=10;

Для доступа к области ОП, отведенной под переменную а, можно использовать и индексы. Эквивалентны следующие выражения:

*p1 ~ p1[0] ;

**pp1 ~ pp1[0][0] ;

***ppp1 ~ ppp1[0][0][0] .

Используя указатели на указатели, мы имеем дело с многомерными мас-ми