Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции за I семестр конспект Гуревича для C++ B....doc
Скачиваний:
11
Добавлен:
21.11.2018
Размер:
1.3 Mб
Скачать

14.10. Объединения

Объединение - поименованная совокупность данных разных типов, размещаемых в одной и той же области памяти, размер которой достаточен для хранения наибольшего элемента.

Объединенный тип данных декларируется подобно структурному типу:

union ID_объединения {

описание полей

};

Пример описания объединенного типа:

union word {

int nom;

char str[20];

};

Пример объявления объектов объединенного типа:

union word p_w, mas_w[100];

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

Например, поток сообщений по каналу связи пусть содержит сообще­ния трех видов:

struct m1 {

char code;

float data[100]; };

struct m2 {

char code;

int mode; };

struct m3 {

char code, note[80]; };

Элемент code - признак вида сообщения. Удобно описать буфер (место для хранения) сообщений в виде

struct m123 {

char code;

union {

float data[100];

int mode;

char note[80]; };

};

Практически все вышесказанное для структур имеет место и для объединений.

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

Пример использования переменных типа union:

. . .

union W {

int a;

float b;

char s[5];

};

void main(void) {

W s;

s.a = 4;

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

s.b = 1.5;

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

strcpy(s.s, “Minsk”);

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

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

getch();

}

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

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

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

Char[] a = Minsk, Sizeof(s.s) = 5

Sizeof(s) = 5

15. Генерация псевдослучайных чисел.

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

К числу функций, обеспечивающих генерацию псевдослучайных чисел, относятся random() и randomize(). Для их работы необходимо подключить заголовочный файл stdlib.h (годятся также и некоторые другие).

Собственно генерацию выполняет функция random. При обращении к ней в скобках надо указать число, задающее диапазон генерируемых чисел (обозначим его N). Результат функции - "случайное" целое число, равновероятно выбранное в диапазоне от 0 до N-1 (таким образом, получается N различных вариантов этого числа).

Если нам нужно случайное целое число в другом диапазоне, то достаточно прибавить к значению random() начало требуемого диапазона, "сдвинув" тем самым результат:

int a,b,x;

...

x=random(b-a+1)+a; // x - случайное число в диапазоне [a..b]

Аналогично можно получать и дробные числа.

Работа функции random() основана на использовании специальной статической ячейки памяти. При запуске программы эта ячейка получат некоторое значение (обычно 0), а затем при каждом обращении к функции random() новое очередное значение в этой ячейке вычисляется из предыдущего по достаточно сложному алгоритму. Исходя из текущего значения этой ячейки, вычисляется сам результат функции random(). Поэтому он не имеет никакой видимой связи с предыдущим ее результатом, что и создает "псевдослучайность" полученных чисел. Однако, при повторном запуске программы начальное значение этой ячейки вновь будет восстановлено, поэтому вся последовательность полученных псевдослучайных чисел повторится.

Если же мы хотим, чтобы последовательность генерируемых чисел различалась при каждом запуске программы, можно воспользоваться функцией randomize(). Она записывает в упомянутую ячейку значение текущего системного времени (с учетом сотых долей секунд, а также даты). Поскольку дата и время запуска программы не могут повториться (тем более - с точностью до сотых долей секунды), после вызова randomize() функция random() будет выдавать уже совершенно новую, практически непредсказуемую последовательность.

Поэтому обращение к randomize() достаточно сделать один раз в начале программы. Не стоит делать это в цикле, т.к. значение системного времени обновляется не более 100 раз в секунду, а цикл может выполниться быстрее, и тогда каждый вызов randomize() запишет в ячейку одно и то же значение, а следующие за ними вызовы random() дадут одинаковые результаты.

Пример программы, заполняющей массив случайными числами от 1 до 100:

int a[40], n, i;

...

randomize();

for (i=0; i<n; i++)

a[i]=random(100)+1;