Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты 1-5.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
144 Кб
Скачать
☆

2) Массивы объектов

Можно создавать массивы объектов точно так же, как создаются массивы данных других типов. Например, следующая программа создает класс display, содержащий информацию о различных адаптерах дисплеев, которые могут быть подключены к PC. В частности, он содержит число цве­тов, которые могут быть получены, и тип видеоадаптера. В функции main() создается массив из трех объектов display. Доступ к элементам этого массива осуществляется с помощью обычной процедуры с использованием индексов. // пример массива объектов #include <iostream.h> enum disp_type {mono, cga, ega, vga}; class display { int colors; // число цветов enum disp_type dt; // тип дисплея public: void set_colors(int num) {colors = num; } int get_colors() {return colors;} void set_type (enum disp_type t) {dt = t; } enum disp_type get_type() {return dt; } }; char names [4 ] [5] = { "mono", "cga", "ega", "vga" }; int main() { display monitors [3]; register int i; monitors[0].set_type(mono); monitors[0].set_colors(1); monitors[1].set_type(cga); monitors [1] .set_colors(4); monitors[2].set_type(ega); monitors [2] .set_colors(16); for (1=0; i<3; i++) { cout << names[monitors[i].get_type()] << " "; cout << "has " << monitors[i].get_colors(); cout << " colors" << "\n"; } return 0; }

Эта программа выводит на экран следующий текст: mono has 1 colors cga has 4 colors ega has 16 colors

Хотя это и не относится специально к массивам объектов, обратим внимание, каким образом двумерный символьный массив names использован для преобразования перечисляемых значений к их строковым эквивалентам. Для всех переменных перечисляемого типа, не содержащих явной инициализации, первая константа имеет значение 0, вторая 1 и т. д. Поэтому возвращаемое фун­кцией get_type() значение может быть использовано для индексации массива names, что позволя­ет вывести подходящее имя.

Многомерные массивы объектов индексируются в точности так же, как и массивы любых дру­гих типов данных.

Билет 2

Вопрос 1:Типы данных c.Примеры

В языке различают понятия "тип данных" и "модификатор типа". Тип данных - это, например, целый, а модификатор - со знаком или без знака. Целое со знаком будет иметь как положительные, так и отрицательные значения, а целое без знака - только положительные значения. В языке Си можно выделить пять базовых типов, которые задаются следующими ключевыми словами:

  • char - символьный;

  • int - целый;

  • float - вещественный;

  • double - вещественный двойной точности;

  • void - не имеющий значения.

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

Процесс проверки и накладывания ограничений на типы используемых данных называется контролем типов или типизацией программных данных. Различают следующие виды типизации:

  • Статическая типизация — контроль типов осуществляется при компиляции.

  • Динамическая типизация — контроль типов осуществляется во время выполнения.

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

Различают простые, составные и прочие типы данных.

Простые данные

Простые данные можно разделить на

  • целочисленные,

  • вещественные,

  • символьные

  • логические.

Составные (сложные) данные

  • Массив - индексированный набор элементов одного типа.

  • Строковый тип - массив, хранящий строку символов.

  • Структура - набор различных элементов (полей записи), хранимый как единое целое и предусматривающий доступ к отдельным полям структуры.

Другие типы данных

  • Указатель - хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — указатель на переменную.

Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).

Идентификатор — это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a - z, A - Z, цифры 0 - 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.

Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.

Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.

Верно

Неверно

int a = 2, b; b = a+3;

Int a=2;  // правильно int INT a=2;

int a = 2, b; b = A + 3; // идентификатор А не объявлен

int a = 2; b = a + 3; // идентификатор b не объявлен

Целочисленные данные могут быть представлены в знаковой и беззнаковой форме.

Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2n-1, где n-количество занимаемых битов.

Знаковые целые числа представляются в диапазоне -2n-1...+2n-1-1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).

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

Количество бит

Беззнаковый тип

Знаковый тип

8

unsigned char 0...255

char -128...127

16

unsigned short 0...65535

short -32768...32767

32

unsigned int

int

64

unsigned long int

long int

Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме. Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как

12345,678 = 1,2345678·104

Число 0,009876 в нормированной форме можно представить как

0,009876 = 9,876·10-3

В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен  только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.

Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.

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

знак - бит, определяющий знак вещественного числа (0 для положительных чисел, 1 - для отрицательных).

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

2n-1

где n - количество разрядов, отводимых для представления степени числа.

целое - бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1.

мантисса - значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.

Различают три основных типа представления вещественных чисел в языке Си:

Тип

Обозна- чение в Си

Кол-во бит

Биты степени

Мантисса

Сдвиг

простое

float

32

30...23

22...0

127

двойной точности

double

64

62...52

51...0

1023

двойной расширен- ной точности

long double

80

78...64

62...0

16383

Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде: Пример: представить число -178,125 в 32-разрядной сетке (тип float). Для представления числа в двоичной системе счисления преобразуем отдельно целую и дробную части: 17810 = 101100102. 0,12510 = 0,0012.Тогда 178,12510 = 10110010,0012=1,0110010001·2111 (для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево). Для определения степени числа применяем сдвиг:

0111111+00000111 = 10000110.

Таким образом, число -178,125 представится в разрядной сетке как

Символьный тип хранит код символа и используется для отображения символов в различных кодировках. Символьные данные задаются в кодах и по сути представляют собой целочисленные значения. Для хранения кодов символов в языке Си используется тип char. Подробнее о кодировке символов

Логический тип имеет два значения: истина и ложь - применяется в логических операциях, используется при алгоритмических проверках условий и в циклах.

В программе должно быть дано объявление всех используемых данных с указанием их имени и типа. Описание данных должно предшествовать их использованию в программе.

Пример объявления объектов

int n;    // Переменная n целого типа double a; // Переменная a вещественного типа двойной точности

Вопрос 2:Ссылки в C++.Ограничение на ссылки.

В С++ введен новый тип данных – ссылка. Ссылка позволяет определять альтернативное имя переменной.

Формат объявления ссылки:

тип &идентификатор = идентификатор2;

Такое объявление назначает переменной с именем идентификатор2 второе имя идентификатор.

Ссылка при объявлении всегда должна быть проинициализирована!

int a,b; int &alt=a;   // alt — другое имя переменной а (ссылка на a) alt = b;  // a=b; alt++;  // a++;

Если объявлен указатель

int *ptr = &a;

то истины следующие выражения:

*ptr == alt;   // истина, сравниваются значения ptr == &alt;  // истина, сравниваются адреса

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

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

Возможно инициализировать ссылка на константу:

const char &new_line='\n';

В этом случае компилятор создает некоторую временную переменную temp и ссылку на нее:

char temp = '\n'; const char &new_line = temp;

Основной причиной введения в С++ нового типа данных – ссылки явилась необходимость передачи параметров в функцию через ссылку и получение возвращаемого значения в виде ссылки. Это используется в двух случаях:

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

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

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

  • во-первых, в функции для данного параметра надо выполнять операцию разыменования,

  • во-вторых, при вызове функции надо передавать не саму переменную, а ее адрес.

Пример. Функция, меняющая местами два целых числа:

Без использования ссылок

С использованием ссылок

void swap (int *a, int *b) { int temp = *a; *a = *b; *b = temp; }

void swap (int &a, int &b) { int temp = a; a = b; b = temp; }

Вызов:

int x = 10; int y = 5; swap(&x, &y);

Вызов:

int x = 10; int y = 5; swap(x, y);

При использовании ссылок в качестве параметров, наряду с указанными преимуществами есть два существенных недостатка:

  • Фактический аргумент, переданный в функцию по ссылке, может быть изменен функцией без ведома вызывающей программы. Чтобы этого избежать, параметры, которые не должны изменяться, должны определяться с ключевым словом const. При попытке изменить параметр, объявленный как const будет сообщение об ошибке.

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

void swap (int &, int &); int main() { int x=10; unsigned int y; y=5; swap(x, y); ... }

Компилятор будет выполнять следующие преобразования:

int temp = (int)y; int &t = temp; swap(x, t);

В результате swap() поменяет местами значения x и temp. После выхода из функции переменная temp удалится, а y останется неизменной.

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

  • если возвращаемое значение — указатель, то нельзя оператором return; возвращать адрес локальной переменной.

  • если возвращаемое значение — ссылка, то нельзя оператором  return возвращать локальную переменную. (Так как после выхода из функции переменная не существует, и мы получим повисшую ссылку).

Чаще всего потребность в ссылках возникает при перегрузке операций.

Билет 3: