Объединения
Объединение - поименованная совокупность данных разных типов, размещаемых в одной и той же области памяти, размер которой достаточен для хранения наибольшего элемента.
Объединенный тип данных декларируется подобно структурному типу:
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
В языке Си есть возможность генерации т.н. псевдослучайных чисел, т.е. чисел, выглядящих для человека как случайные, хотя в действительности вычисляемых по некоторому алгоритму.
К числу функций, обеспечивающих генерацию псевдослучайных чисел, относятся 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;
16. Файлы в языке С
Файл – это набор данных, размещенный на внешнем носителе и рассматриваемый в процессе обработки и пересылки как единое целое. В файлах размещаются данные, предназначенные для длительного хранения.
В языке Си имеется большой набор функций для работы с файлами, большинство которых находятся в библиотеках stdio.h и io.h. Все они рассматривают файл как последовательность байт, из которой можно читать или в которую можно записывать данные различными способами. При работе с файлом (при открытии файла) создается указатель позиции в файле (аналогичный по назначению курсору на экране) - он указывает, в каком месте файла будет производиться чтение/запись. По мере выполнения операций чтения/записи этот указатель автоматически продвигается вперед, так что каждая последующая операция чтения/записи будет читать/записывать уже следующую информацию. Указатель можно также непосредственно устанавливать в нужную позицию.