Лекция: Общее знакомство

Вид материалаЛекция

Содержание


Данные перечислимого типа
Переменные структуры
Указатели и структуры
Массив структур
Определение элементов массива
Переименование типов
Стандартные библиотечные функции
Потоковая функция или макрокоманда
Подобный материал:
1   ...   25   26   27   28   29   30   31   32   33

Объединения


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

Определение объединенного типа данных аналогично определению структурного типа данных:

union имя_объединения {

Описания_элементов

};

Пример:

union bigword {

long bg_long;

char *bg_char [4];

};

Данные типа union bigword занимают память, необходимую для размещения наибольшего из своих элементов, и выравниваются в памяти к границе, удовлетворяющей ограничениям по адресации как для типа long, так и для типа char *[4].

Описание переменной объединенного типа:

Пример:

union bigword x;

union bigword *p;

union bigword a[100];

Перечисления


^ Данные перечислимого типа относятся к некоторому ограниченному множеству данных.

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

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

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

};

Каждое значение данного перечислимого типа задается идентификатором.

Пример:

enum color {

red, green, yellow

};

Описание переменной перечислимого типа:

enum color chair;

enum color suite [40];

Использование переменной перечислимого типа в выражении.

Пример:

char = red;

suite[5] != yellow;
^

Переменные структуры


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

struct {

общие компоненты;

метка активного компонента;

union {

описание компонента 1

описание компонента 2

...

описание компонента n

} идентификатор;

}

Ниже приведен пример определения переменной структуры health_record:

struct {

/* общая информация */

char name[25];

int age;

char sex;

/* метка активного компонента */

marital_status ms;

/* переменная часть */

union {

/* холост */

/* нет компонентов */

/* женат */

struct {

char marriage_date[8];

char spouse_name[25];

int no_children;

}

/* разведен */

char date_divorced[8];

} marital_info;

} health_record;

где тип marital_status, т.е. тип метки активного компонента ms, описан как

typedef enum {SINGL,MARRIED, DIVORCED}

marital_status;

Ниже приведены несколько примеров ссылки на компоненты переменной структуры:

health_record.name

healts_record.ms

health_record.marriage_info.marriage_date
^

Указатели и структуры


Рассмотрим метку структуры student, описание которой было дано выше как

struct student {

char name[25];

int id, age;

char sex;

}

Указатель new_student определен как

struct student *new_student;

Предположим, что память выделена таким образом, чтобы new_student указывал на объект student. Тогда на компоненты этого объекта можно ссылаться следующим образом:

(*new_student).name

(*new_student).id

(*new_student).age

(*new_student).sex

Поскольку указатели часто используются для указания на структуры, в языке Си специально для ссылок на компоненты таких структур введен оператор выбора стрелка вправо ->. Например, ссылки на вышеприведенные компоненты структуры можно записать с использованием оператора стрелки вправо -> как:

new_struct->name

new_struct->id

new_struct->age

new_struct->sex
^

Массив структур


Процесс описания массива структур совершенно аналогичен описанию любого другого типа массива:

struct book libry[MAXBKS];

Этот оператор объявляет libry массивом, состоящим из MAXBKS-элементов. Каждый элемент массива представляет собой структуру типа book. Таким образом, libry[0] является book-структурой, libry[1] - второй book-структурой и т.д.

^ Определение элементов массива структур. При определении элементов массива структур мы применяем те же самые правила, которые используются для отдельных структур: сопровождаем имя структуры операцией получения элемента и имени элемента:

libry[0].value value - первый элемент массива

libry[4].title title - пятый элемент массива
^

Переименование типов


Формат

typedef старый_тип новый_тип

Примеры:

typedef long large;

/* определяется тип large, эквивалентный типу long */

typedef char *string;

/* тип string, эквивалентен типу char* */

Переименование типов используется для введения осмысленных или сокращенных имен типов, что повышает понятность программ, и для улучшения переносимости программ (имена одного типа данных могут различаться на разных ЭВМ).

Пример:

/* Реализован алгоритм, который позволяет определить

строки матриц, состоящие из одинаковых целых,

расположенных в различных столбцах. Используются

двумерные массивы и структуры. Сначала выполняется

сортировка строк по возрастанию. Отсортированные

строки сравниваются и выводятся на экран номера

одинаковых строк */

#include

#include

#include

#include

const n=4, m=4; // n - кол-во строк, m - столбцов

int m1[n][m]; /*исходный массив*/

struct mas{int i,i1;};

/*i-индекс сравниваемой строки с i1 строкой*/

mas a[n*2];

/*массив типа mas, где будут лежать одинаковые

строки, a[1].i и a[1].i1 - одинаковые строки*/

void main()

{

clrscr();

int i,j;

randomize();

for(i=0;i
for(j=0;j
m1[i][j]=random(2);

/*случайным образом в массив заносим целые*/

for(i=0;i
printf("\n %d) ",i);

for(int j=0;j
printf(" %d",m1[i][j]);

}

int min, p;

/* индекс минимального элемента после s-го элемента

i-ой строки сортировка строк массива по возрастанию */

for(i=0;i
for(int s=0;s
min=m1[i][s+1];

for(int j=s;j
if(m1[i][j]<=min) {

min=m1[i][j];p=j;

}

/* запоминаем минимальный элемент в ряду после

s-го элемента */

if(m1[i][s]>=min) {

m1[i][p]=m1[i][s];m1[i][s]=min;

}

/* меняем местами s-й и p-й элемент,если

s-й > p-го(минимального) */

}

}

printf("\n");

for(i=0;i
printf("\n %d) ",i);

for(int j=0;j
printf(" %d",m1[i][j]);

/* выводим отсортированный массив */

}

int s,k=0;

/*сколько элементов в i-й строке совпадают с элементами i1 строки*/

/*сколько строк совпали*/

int i1;

for(i=0;i
for(i1=i+1;i1
s=0;

for(int j=0;j
/* сравнение идет по j-му столбцу */

if(m1[i][j]==m1[i1][j]) s++;

/* если соответствующие элементы в i-й и i1-й строки совпадают то кол-во совпавших увеличивается на 1 */

if(s==m) {a[k].i=i;a[k].i1=i1;k++;}

/* если все элементы i-й и i1-й строки совпали, то они одинаковые */

}

printf("\n Совпадающие строки :");

for(i=0;i
printf("\n %d и %d",a[i].i,a[i].i1);

/* распечатываем a[i].i-ю и a[i].i1-ю совпадающую

строку */

getch();

}

15. Лекция: Библиотека языка Си и файлы ввода-вывода
^

Стандартные библиотечные функции


Библиотека языка Си содержит множество функций и макроопределений. Библиотеки меняются от системы к системе, но есть ядро функций (стандартная библиотека).

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

Главными преимуществами стандартных библиотечных функций Си являются мобильность и низкие затраты на сопровождение пользовательских приложений. Библиотечные функции не подвержены частым изменениям, поэтому программы, в которых они используются, легки в сопровождении. Некоторые из этих библиотечных функций соответствуют стандарту ANSI С - стандарту Си Американского национального института, благодаря чему они приемлемы для всех систем, соответствующих этому стандарту. Чтобы сократить затраты и время на разработку приложений, рекомендуется использовать библиотечные функции Си всякий раз, когда это оказывается возможным.

Стандартные библиотечные функции Си объявляются в наборе файлов-заголовков, которые в UNIX-системах обычно расположены в каталоге /user/include. Опишем библиотечные функции ANSI C, определенные в файлах-заголовков, перечисленные ниже:





















Кроме указанных, в большинстве UNIX-систем есть файлы заголовков, которые не определены в ANSI C:




.

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

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

^ Потоковая функция или макрокоманда

Назначение

fopen

Открывает поток для чтения и (или) записи

fclose

Закрывает поток

fread

Читает блок данных из потока

fgets

Читает строку текста из потока

fscanf

Читает форматированные данные из потока

fwrite

Записывает блок данных в поток

fputs

Записывает строку текста в поток

fprintf

Записывает форматированное данное в поток

fseek

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

ftell

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

freopen

Повторно использует указатель потока для ссылки на новый файл

fdopen

Открывает потоковый файл с указанным дескриптором

feof

Макрокоманда, которая возвращает ненулевое значение, если в данном потоке обнаружен символ конца файла, в противном случае - нулевое значение

ferror

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

clearer

Макрокоманда, которая сбрасывает флаг наличия ошибок в данном потоке

fileno

Макрокоманда, которая возвращает дескриптор данного потокового файла