Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб по С и С++ / Лаб_C_№10_№11

.doc
Скачиваний:
64
Добавлен:
17.03.2015
Размер:
109.06 Кб
Скачать

Лабораторная работа по структурам.

Изучить материал и продемонстрировать умение работать со структурами в том числе:

  1. описать шаблон структуры (в том числе вложенные структуры, структуры, содержащие объединение);

  2. уметь объявить структурную переменную, массив структур, указатель на структуру, массив указателей на структуру;

  3. уметь обращаться к полям структуры через имя структуры, указатель на структуру, элемент массива структур;

  4. максимально просто копировать поля одной структуры в другую (пример 1);

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

  6. уметь передать структуру в функцию через параметры функции и, возможно, передать структуру в качестве результата;

ПРИ НАПИСАНИИ ПРОГРАММЫ

  1. Взять за основу программу консольного приложения .

  2. Исходить из принципа модульного программирования:

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

  4. разбить весь текст на раздел описаний и раздел реализаций. Раздел описаний (файл с расширением *.h) содержит заголовочные файлы, макроопределения, описания внешних переменных, прототипы собственных функций. Раздел реализаций (один или несколько файлов с расширением *.с) содержит тексты самих функций.

  5. Сборку программы производить с помощью файла проекта

  6. Написать по тексту комментарии, особенно в файле описаний.

ПРИ ЗАЩИТЕ РАБОТЫ

1. Уметь выполнить программу.

2. Изложить узловые моменты и особенности алгоритма.

3. Дать объяснение любому оператору программы по требованию преподавателя.

1. Работа с файлами в C ( работает и в C++ )..

#include <iostream.h> #include <stdio.h> void main( void ) { FILE *file; char* file_name = "file.txt"; char load_string[50] = "none"; file = fopen( file_name, "w" ); fputs( "string", file ); fclose( file ); file = fopen( file_name, "r" ); if( file != 0 ) { fgets( load_string, 50 , file ); cout << "load_string = " << load_string << endl; } else { cout << "File not found !!!" << endl; } fclose(file); }

Описание функций работы с файлами находятся в библиотеке stdio.h Сначала надо создать указатель на переменную типа FILE ( FILE* file; ). Открытие файла производится вызовом функции fopen ( file = fopen( file_name, "w" ); )

Первый параметр этой функции - имя файла, второй - указывает в каком режиме должен быть открыт файл. "w" - открыть для записи, "r" - открыть для чтения, "a" - дополнение файла( это наиболее используемые режимы, хотя есть и другие ). Запись и считывание данных из файла осуществляется следующими функциями : fputc, fputs, fgetc, fgets, fprintf, fscanf( описание этих функций смотрите в stdio.h). Закрытие файла осуществляется вызовом функции fclose ( fclose( file ); ). (* см. ниже*)

СТРУКТУРЫ

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

Для использования структуры необходимо:

1. установить шаблон для структуры

2. объявить переменную, соответствующую этому шаблону

3. осуществить доступ к компонентам структуры.

Шаблон структуры

Шаблон - это схема, описывающая содержание структуры. Установка структурного шаблона телефонный справочник:

struct sprav

char fio[20];

long num;

;

Данный шаблон описывает структуру с именем типа структуры sprav, состоящую из двух компонентов: строки fio и целой пе-

ременной num типа long.

Имя типа структуры sprav необязательно и используется для ссылки на эту структуру.

Компоненты структуры - данные любого типа, включая и другие структуры. Имя внутри структуры может быть таким же, как имя объекта вне структуры.

Если шаблон описан внутри функции - он доступен только этой функции, если шаблон описан вне функции - он доступен любой функции программы.

Установка шаблона не вызывает никаких действий в программе.

Структурные переменные

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

откуда можно прочитать их.

Для объявления структурных переменных имеются несколько спо­собов.

1. Установить структурный шаблон: struct sprav

char fio[20];

long num;

;

Объявить простую переменную, массив структур, указатель на структуру:

struct sprav tel1, tel2[5], *tel3;

2. Установить структурный шаблон с помощью макроопределения: #define SPRAV struct sprav

SPRAV

char fio[20];

long num;

;

Объявить переменные:

SPRAV sp1, sp2[6], *sp3;

3. Объявить переменные одновременно с установкой шаблона (если на данную структуру вы больше не ссылаетесь):

struct

char fio[20];

long num;

tel1, tel2[3], *tel3;

4. Ввести новый тип данных (TEL)-структура определенного вида: typedef struct

char fio[20];

long num;

TEL;

Объявить переменные нового типа:

TEL tel1, tel2[6], *tel3;

Если программа достаточно объемна, представляется более удоб­ным четвертый способ.

Инициализация структуры

Инициализировать можно только внешние или статические структу­ры.

static struct

char fio[20];

long num;

tel[2]=

"Иванов Ф.А.", 456756,

"Петров В.П.", 632345

;

Доступ к компонентам структуры

Доступ к компонентам структуры продемонстрируем с помощью примеров.

Пример 1.

/* Обращение к элементам структуры через имя переменной */

#include <stdio.h>

#include <conio.h>

void main(void)

struct

char fio[20]; /* фамилия */

long num; /* телефон */

tel1, tel2;

clrscr();

puts("введите фио абонента-");

gets(tel1.fio);

puts("введите его номер-");

scanf("%ld",&tel1.num);

tel2=tel1; /* нельзя так же сравнивать структуры */

puts("Введено:");

printf("Фамилия :%s номер: %ld\n",tel2.fio,tel2.num);

Пример 2.

/* Динамическое выделение памяти для структуры */

/* Обращение к элементам структуры через указатель */

#include <stdio.h>

#include <conio.h>

#include <alloc.h>

struct sprav

char fio[20];

long num;

;

void main(void)

struct sprav *tel1, *tel2;

clrscr();

/* Выделение памяти для структуры */

tel1=(struct sprav *)malloc(sizeof(struct sprav));

tel2=(struct sprav *)malloc(sizeof(struct sprav));

puts("введите фио абонента-");

gets(tel1->fio);

puts("введите его номер-");

scanf("%ld",&tel1->num);

*tel2= *tel1;

puts("Введено:");

printf("Фамилия :%s номер: %ld\n",(*tel2).fio,(*tel2).num);

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

Пример 3.

/* Массив структур. Обращение к элементам структуры через */

/* имя элемента массива */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#define SPRAV struct sprav

void main(void)

SPRAV

char fio[20];

long num;

;

SPRAV tel[5]; /* массив структур - 5 элементов */

char fio_tek[20];

int i;

clrscr();

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

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

puts("введите фио абонента-");

gets(tel[i].fio);

puts("введите его номер-");

scanf("%ld",&tel[i].num);

getchar();

puts("Выбор телефона по фамилии");

gets(fio_tek);

/* поиск структуры по фамилии абонента */

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

if(!strcmp(fio_tek,tel[i].fio)) break;

if(i!=5) /* цикл закончен по break */

printf("номер абонента %s равен %ld\n",fio_tek, \

tel[i].num);

else /* цикл выполнился полностью */

puts("Абонент не найден");

Пример 4.

/* Массив структур. Память выделяется динамически. */

/* Обращение к элементам структуры через указатель */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <alloc.h>

typedef struct

char fio[20];

long num;

TEL;

void main(void)

TEL *tel;

char fio_tek[20];

int i;

clrscr();

/* Выделение памяти для массива - 3 элемента */

tel=(TEL *)malloc(sizeof(TEL)*3);

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

puts("введите фио абонента-");

gets((tel+i)->fio);

puts("введите его номер-");

scanf("%ld",&(tel+i)->num);

getchar();

puts("Выбор телефона по фамилии");

gets(fio_tek);

for(i=0; i<5; i++,tel++)

if(!strcmp(fio_tek,tel->fio)) break;

if(i!=5)

printf("номер абонента %s равен %ld\n",fio_tek, \

tel->num);

else

puts("Абонент не найден");

Передача структуры в функцию

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

Не все компиляторы языка Си позволяют передавать структуры в функцию по значению, поэтому в примерах передача структуры идет через указатель.

Пример 5.

/* Передача структуры в функцию через указатель на структуру */ /* Определение комплексного числа через структуру и действия */ /* над комплексными числами ( ввод, вывод, вычисление суммы) */ #include <stdio.h>

typedef struct float a; /* действительная часть */

float b; /* мнимая часть */

COMPLEX;

void vvod(COMPLEX *,float,float);

void sum(COMPLEX *,COMPLEX *,COMPLEX *);

void out(COMPLEX *);

void main(void)

COMPLEX x,y,z;

vvod(&x,2.5,6.7);

vvod(&y,6.89,8.45);

puts("Введены числа:");

out(&x);

out(&y);

sum(&x,&y,&z);

puts("Сумма комплексных чисел равна:");

out(&z);

/* Вывод комплексного числа */

void out( COMPLEX *p)

printf("(%.2f,%.2f)\n", (*p).a,(*p).b);

return;

/* Вычисление суммы двух комплексных чисел */

void sum(COMPLEX *p1,COMPLEX *p2,COMPLEX *p3)

(*p3).a=(*p1).a+(*p2).a;

(*p3).b=(*p1).b+(*p2).b;

return;

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

void vvod(COMPLEX *p,float a, float b)

p->a=a;

p->b=b;

return;

Вложенные структуры

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

Пример 6.

/* Даны четыре точки - центры четырех окружностей.

Заполнить структуру окружность, если все окружности проходят через начало координат.

*/

#include<conio.h>

#include<stdio.h>

#include<math.h>

#include<stdlib.h>

struct POINT

float x;

float y;

;

struct CIRCLE

struct POINT point; /* вложенная структура */ double r;

circle[2], *p;

void main (void)

int i,j;

float a,b,c,d;

clrscr();

gotoxy(17,1);

cputs("ВВЕДИТЕ КООРДИНАТЫ ТОЧЕК :\r\n");

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

cprintf ("\n\n ВВЕДИТЕ X: ");

cprintf ("X[%d]= ",i+1); cscanf("%f",&circle[i].point.x);

cprintf ("\n ВВЕДИТЕ Y: ");

cprintf ("Y[%d]= ",i+1);

cscanf ("%f",&circle[i].point.y);

p=circle;

gotoxy(17,12);

cputs("РЕЗУЛЬТАТ:\r\n\n");

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

a=p->point.x;

b=p->point.y;

c=sqrt(a*a+b*b);

p->r=c;

cprintf("\nРАДИУС : %lf ЦЕНТР (%f,%f)\r\n",p->r,a,b); p++;

ФУНКЦИИ ВВОДА И ВЫВОДА ВЕРХНЕГО УРОВНЯ

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

Функции ввода/вывода делятся на группы:

1. ввод/вывод верхнего уровня

2. ввод/вывод системного уровня

3. ввод/вывод для консольного терминала

4. ввод/вывод через порт.

Для пользователя файл, открытый на верхнем уровне, представляется как последовательность считываемых или записываемых байтов. Чтобы отразить эту особенность, используется понятие "поток" (stream).

Функции ввода/вывода работают с буферизацией. Обмен информацией происходит не между программой и файлом, а между программой и буфером, расположенным в оперативной памяти.

Буферизация ускоряет работу программы из-за уменьшения количества обращений к внешним устройствам.

Чтобы получить доступ к файлу, необходимо связать его с соответствующей структурой типа FILE, объявленной в stdio.h и содержащей разнообразную информацию о файле. Эта операция называется открытием файла и осуществляется с помощью функции fopen, которая в качестве результата возвращает указатель на структуру FILE - указатель файла. Указатель файла в дальнейшем используется функциями для ввода/вывода информации в файл.

Указатель файла позиционируется в соответствии с открытием потока: если поток открыт для чтения - на начало файла, если для дозаписи - на конец файла. Указатель файла изменяется в соответствии с операцией записи или чтения.

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

Потоки бывают текстовые или двоичные (по умолчанию - текстовые). При вводе текстового потока система Турбо Си преобразует символы возврат коретки и перевод строки в символ перевода строки, а при выводе текстового потока в среду операционной системы происходит обратное преобразование.

При вводе/выводе двоичного потока никаких преобразований не происходит.

При выполнении любой программы автоматически открываются пять стандартных потоков, имеющих следующие указатели файлов: stdin - поток ввода, stdout - поток вывода, stderr - поток вывода для сообщений об ошибках ( для вывода в поток stderr используется функция perror ), stdaux - последовательный порт и stdprn - устройство печати. Первые три потока по умолчанию связываются с консольным терминалом. Имена указателей стандартных потоков ввода/вывода могут указываться в функциях ввода/вывода.

Для переопределения стандартных потоков используется функция freopen.

Прототипы функций ввода/вывода описаны в stdio.h, и там же объявлен ряд макроопределений, в том числе NULL - нулевой байт, EOF - символ конца файла, BUFSIZ - размер буфера.

Далее приводятся описания прототипов функций с кратким пояснением.

Доступ к файлу

FILE * fopen(char *pathname, char *type);

функция открывает файл (имя задает первый аргумент) для

(второй аргумент):

"r" - чтения существующего файла

"w" - записи (перезаписи) файла

"a" - записи (дозаписи) файла

"r+" - чтения и записи существующего файла

"w+" - чтения и записи (перезаписи) файла

"a+" - чтения и записи (дозаписи) файла.

В конец строки записывается t - текстовый режим или b - двоичный режим. Например: "rt" , "w+b".

Возврат при ошибке: NULL.

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

int fclose(FILE *stream);

int fcloseall(void);

Возврат при ошибке: EOF.

Конец файла

int feof(FILE *stream);

Возврат: 0 - не конец файла, иначе - конец файла.

Данные в файле могут быть организованы как:

1. непрерывный поток символов

2. последовательность строк переменной длины

3. форматированные поля, разделенные определенным символом

4. последовательность записей фиксированной длины.

В соответствии с этим разделим функции ввода/вывода верхнего уровня на группы.

Ввод/вывод символа

int getchar(void); - ввод из stdin

int putchar(int); - вывод в stdout

int fgetc(FILE *stream); - ввод из потока

int fputc(int c, FILE *stream); - вывод в поток

int getc(FILE *stream); - ввод из потока

int putc(int c,FILE *stream); - вывод в поток

int ungetc(char c, FILE *stream); - возврат введенного символа в поток.

Возврат при ошибке: EOF.

Построчный ввод/вывод

char * fgets(char *s,int n, FILE *stream); - cтрока из входного потока помещается в s (не более n-1 символа).

char * gets(char *s); - строка из stdin помещается в s.Возврат при ошибке: NULL.

int fputs(char *s, FILE *stream); - cтрока помещается в вы ходной поток.

int puts(char *s); - cтрока помещается в stdout.

Возврат при ошибке: EOF.

Форматный ввод/вывод

int fprintf(FILE *stream,<строка формата>,<список имен>); форматный вывод в поток.

int fscanf(FILE *stream,<строка формата>,<список адресов>); форматный ввод из потока.

int printf(<строка формата>,<список имен>); форматный вывод в stdout.

int scanf(<строка формата>,<список адресов>); форматный ввод из stdin. Ввод/вывод записей

int fread(void *bufer, int size, int count, FILE *stream); функция читает count элементов длины size из входного потока и помещает в bufer.

int fwrite(char *bufer, int size, int count, FILE *stream); функция дописывает count элементов длины size из области bufer в поток. Как правило, эти функции используются для ввода/вывода массивов и структур.

Внутреннее преобразование данных

int sprintf(char *s,<строка формата>,<список имен> ); вывод данных в строку.

int sscanf(char *s,<строка формата>,<список адресов>); ввод из строки по адресам.

Возврат при ошибке: EOF.

Прямой доступ к файлу

int fseek(FILE *stream, long offset, int origin); - функция перемещает указатель файла на offset позиций относительно начала файла, если origin равно 0, текущей позиции, если origin равно 1, конца файла, если origin равно 2. Если значение offset положительно - движение вперед, иначедвижение назад. Возврат при ошибке: не нуль.

Текущая позиция в файле

long ftell(FILE *stream); - возвращает номер текущей позиции от начала файла.

Пример 1.

/* создание копии autoexec.bat в autoexec.bak */

#include<stdio.h>

void main (void)

{

/* указатели входного и выходного потоков */

FILE *in, *out;

/* открытие входного потока */

if((in=fopen("\\autoexec.bat","rt"))==NULL)

{

fprintf(stderr, "cannot open input file\n");

exit(1);

}

/* открытие выходного потока */

if((out=fopen("autoexec.bak","wt"))==NULL)

{

fprintf(stderr, "cannot open output file\n");

exit(1);

}

/* символ из входного потока записать в выходной */

while(!feof(in))

fputc(fgetc(in), out);

/* закрытие потоков */

fclose(in);

fclose(out);

}

Пример 2.

/* внутреннее преобразование данных - из строки в float */

#include<stdio.h>

void main (void)

{

char s[20];

float chislo;

puts("\nввод числа");

gets(s);

sscanf(s,"%f",&chislo);

printf("полученное число %f\n", chislo);

}

Пример 3.

/* прямой доступ к файлу - печать 21-го символа из ес.bat */

/* в результате печатается n */

#include<stdio.h>

void main (void)

{

FILE *in, *out;

if((in=fopen("ec.bat","rt"))==NULL)

{

fprintf(stderr, "cannot open input file\n");

exit(1);

}

/* сместить указатель файла на 20 позиций от начала файла */

fseek(in,20L,0);

fprintf(stdout,"21-ый символ равен %c\n", fgetc(in));

}

/* содержимое ec.bat */

rrrrrrrrrrrrrrrrrrrdnyyyy

ЗАДАНИЕ

Условия выбора варианта

подгруппа

1

2

3

4

машины

варианта

варианта

варианта

варианта

1

1

11

6

10

2

2

12

7

9

3

3

13

8

8

4

4

14

9

7

5

5

15

10

6

6

6

1

11

5

7

7

2

12

4

8

8

3

13

3

9

9

4

14

2

10**

10

5

15

1

  1. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - книги.

  2. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - ценная бумага

  3. . Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - товар.

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

  5. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - игрушка.

  6. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - ученик

  7. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - автомобиль.

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

  9. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - банк

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

  11. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - дневная температура

  12. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - сессия

  13. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - ценная бумага

  14. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - телефонный справочник

  15. Определить шаблон структуры на заданную тему, состоящий из полей различного типа.. Количество структур, если не оговорено особо, в пределе 10 необходимо создать массив типа структура, заполнение данных в массив, поиск, удаление и редактирование. Структура - квартира

Соседние файлы в папке Лаб по С и С++