Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
13_структуры_производные_типы_данных.pdf
Скачиваний:
9
Добавлен:
16.03.2016
Размер:
697.68 Кб
Скачать

Язык программирования Cи

Пример 3

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

Для решения примера воспользуемся структурой, рассмотренной в теоретической части данной темы:

struct employee {

 

char Name [20+1];

// имя

char Surname [20+1];

// фамилия

int age;

// возраст

double hourlysalary;

// почасовой оклад

} employee_new, *PTR;

// *PTR – указатель на структуру

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <string.h> #include <locale.h>

// Предполагаемое число символов в имени или фамилии

#define n 20

int main (void)

 

{

 

// Определение структуры

 

struct emloyee

 

{

 

char name[n+1];

// имя

char surname[n+1];

// фамилия

int age;

// возраст

double hourlysalary;

// почасовой оклад в у.е.

} emloyee_new, *PTR;

// *PTR - указатель на структуру

setlocale( LC_ALL, ".1251");// кодовая страница Windows – 1251 PTR = &emloyee_new; //В указатель помещается адрес employee_new

//Инициализация полей структуры strcpy_s(PTR -> name, n, "Владимир"); strcpy_s(PTR -> surname, n, "Викулов"); PTR -> age = 25;

PTR -> hourlysalary = 6.78;

//Вывод на консоль

puts("\n=============== Поля структуры ====================");

printf("\n Имя: %s\n Фамилия: %s\n возраст: %d лет\n

почасовой оклад: %1.2f y.e.\n", \PTR -> name, PTR -> surname, PTR -> age, PTR -> hourlysalary);

puts("\n==================================================\n"); printf("\n\n Нажмите любую клавишу (Press any key): "); _getch();

return 0;

}

В программе инициализация полей структуры выполнена с помощью оператора –>. С подключением заголовочного файла <locale.h> и определением прототипа функции setlocale(LC_ALL, ".1251") становится возможной поддержка русских шрифтов.

Результат выполнения программы представлен на рисунке.

7

Язык программирования Cи

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

Задание 3

1.В программу добавьте нумерацию полей структуры, например 1) имя: и т. д.

2.В программу введите свои имя и фамилию, возраст и размер получаемой стипендии (если нет, то нуль). Значения новых полей выведите на консоль и в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.

3.Инициализацию полей структуры выполните с помощью указателя.

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

Пример 4

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

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <string.h>

// Размер символьных массивов

#define N 20 int main (void)

{

struct stud // шаблон структуры

{

char name[N+1];

// имя студента

char surname[N+1];

// фамилия студента

int age;

// возраст - полных лет

double av_mark;

// средняя успеваемость

};

 

 

struct group

// шаблон структуры

{

 

 

int number;

// номер группы

int quantity;

// количество студентов в группе

struct stud student; // вложенная структура

} ACOUY;

// ACOUY - структурная переменная

//Инициализация полей структуры

ACOUY.number = 3; ACOUY.quantity = 21;

strcpy_s(ACOUY.student.name, N, "Peter"); strcpy_s(ACOUY.student.surname, N, "Bobrov"); ACOUY.student.age = 20; ACOUY.student.av_mark = 4.25;

//Вывод на консоль

puts("\n========= Varient field of structure ===============");

printf("\n Group Number: %d,\n The number of students in the group: %d,\n\ Name: %s,\n Surname: %s,\n Age: %d,\n Average mark: %1.2f", \ ACOUY.number, ACOUY.quantity, ACOUY.student.name, ACOUY.student.surname, \ ACOUY.student.age, ACOUY.student.av_mark);

8

Язык программирования Cи

puts("\n\n================================================\n"); printf("\n Press any key: ");

_getch(); return 0;

}

Результат выполнения программы показан на рисунке.

Пример информационной карточки студенческой группы

Задание 4

1.Инициализацию структуры выполните с клавиатуры.

2.Предусмотрите массив структур ACOUY[N], где N – количество групп (например, N = 3).

3.Введите данные своей студенческой группы и предусмотрите вывод на консоль данных о себе.

4.Примените оператор typedef и указатель на структуру.

Пример 5

Написать программу составления карточки на студента с динамическим распределением памяти для имени и фамилии на основе структурного типа данных [5].

Для динамического распределения памяти применим функцию malloc() и символьные указатели в качестве инициализаторов структуры.

Программный код решения примера

#include <stdio.h>

#include <conio.h> #include <string.h> #include <stdlib.h> #include <locale.h>

const int MAX = 80; // предполагаемое число символов

int main (void)

{

char *NAME, *SURNAME;

struct stud // шаблон структуры

{

char *name; // указатель вместо массива символов имени студента

char *surname;

// указатель вместо

массива символов фамилии

int age;

// возраст - полных лет

float av_mark;

// средняя успеваемость

int letters;

// число символов в имени и фамилии

} TABLE, *PTR;

PTR = &TABLE; // инициализация указателя на структуру

NAME = (char *)malloc(MAX);

printf("\n Enter a name of the student: "); gets_s( NAME, MAX – 1 );

SURNAME = (char *)malloc(MAX);

printf(" Enter a surname of the student: "); gets_s( SURNAME, MAX – 1 );

// Распределение памяти для хранения "структурного" имени

9

Язык программирования Cи

PTR->name = (char *)malloc(strlen(NAME)+1);

//Копирование имени в распределенную память strcpy_s(PTR->name, strlen(NAME)+1, NAME);

//Распределение памяти для хранения "структурной" фамилии

PTR->surname = (char *)malloc(strlen(SURNAME)+1);

//Копирование фамилии в распределенную память

strcpy_s(PTR->surname, strlen(SURNAME)+1, SURNAME); printf(" Enter the age of the student: "); scanf_s("%d", &TABLE.age);

printf(" Enter an average mark of the student: "); scanf_s("%f", &TABLE.av_mark);

TABLE.letters = strlen(PTR->name) + strlen(PTR->surname);

//Для вывода чисел с десятичной запятой setlocale(LC_NUMERIC, ".1251");

puts("\n======== Varient field of structure ===============");

printf("\n Name: %s\n Surname: %s\n Age: %d\n Average mark: %1.2f\n\ The name and surname of student have: %d letters", \ PTR->name, PTR->surname, PTR->age, PTR->av_mark, PTR->letters);

puts("\n\n================================================\n");

//Освобождение памяти

free(NAME);

free(SURNAME); free(PTR->name); free(PTR->surname); printf("\n Press any key: "); _getch(); return 0;

}

В программе сначала выделяется память под имя и фамилию, для которых использованы указатели *NAME, *SURNAME. После того как эти данные введены с клавиатуры, рассчитывается количество символов плюс символ окончания строки '\0', которые используются при резервировании памяти для структурных переменных.

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

Пример динамического создания карточки студента

Задание 5

1.С клавиатуры введите данные о себе (буквами русского алфавита), выведите информацию на консоль и в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.

2.Поменяйте операторы «стрелка» на операторы «точка» и наоборот.

3.Вместо указателей *NAME, *SURNAME примените массивы символов.

4.Предусмотрите нумерацию полей структуры, например 1) Name: Peter и т. д.

Пример 6

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

10

Язык программирования Cи

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

Для динамического распределения памяти применим функцию malloc() и символьные указатели в качестве инициализаторов структуры.

Программный код решения примера

#include <stdio.h> #include <conio.h> #include <string.h>

#define MAX 80 // предполагаемое число символов struct stud // шаблон структуры

{

char name[MAX+1];

// массив символов имени студента

char surname[MAX+1];

// массив символов фамилии студента

char ACOUY[MAX+1];

// специальность

int age;

// возраст - полных лет

float av_mark;

// средняя успеваемость

};

 

int main (void)

 

{

 

char NAME[MAX+1], SURNAME[MAX+1], SPEC[MAX+1]; FILE *fid;

//условная инициализация переменной структуры и

//определение указателя на структуру

struct stud TABLE = {"--", "--", "--", 0, 0.0}, *PTR;

PTR = &TABLE; // инициализация указателя на структуру printf("\n Enter a name of student: ");

gets_s(NAME, MAX);

printf(" Enter a surname of student: "); gets_s(SURNAME, MAX);

printf(" Enter a speciality: "); gets_s(SPEC, MAX);

// Занесение имени в структуру strcpy_s(PTR->name, strlen(NAME)+1, NAME); // Занесение фамилии в структуру

strcpy_s(PTR->surname, strlen(SURNAME)+1, SURNAME);

// Занесение названия специальности в структуру strcpy_s(PTR->ACOUY, strlen(SPEC)+1, SPEC); printf("Enter the age of the student: "); scanf_s("%d", &TABLE.age);

printf(" Enter the average mark student: "); scanf_s("%f", &TABLE.av_mark);

puts("\n======= Varient field of structure ============");

printf("\n Name: %s\n Surname: %s\n \

Specialisation: %s\n Age: %d\n Average mark: %0.2f\n ", \ PTR->name, PTR->surname, PTR->ACOUY, PTR->age, PTR->av_mark );

puts("\n================================================\n"); if ( fopen_s(&fid, "D:\\data12.dat", "wb") )

{

printf("\n File could not be opened\n"); printf("\n Press any key: ");

_getch(); return -1;

}

//Пакетная запись в двоичный файл fwrite(PTR, sizeof(struct stud), 1, fid); fclose(fid);

//if ( fopen_s(&fid, "D:\\data12.dat", "rb") ) //{printf("\n File could not be opened\n"); //printf("\n Press any key: ");

11

Язык программирования Cи

//_getch(); return -1; }

// Чтение из двоичного файла

//fread(PTR, sizeof(struct stud), 1, fid); //puts("\n===== Variants of fields of structure =====");

//printf("\n Name: %s\n Surname: %s\n \

//Specialisation: %s\n Age: %d\n Average mark: %1.2f\n ", \

//PTR->name, PTR->surname, PTR->ACOUY, PTR->age, PTR->av_mark ); //puts("\n===============================================\n"); //fclose(fid);

printf("\n\n Press any key: "); _getch();

return 0;

}

Форматы записи в двоичный файл и чтения из него выглядят так: fwrite(PTR, sizeof(struct stud), 1, fid); fread(PTR, sizeof(struct stud), 1, fid);

Вфункции fwrite() первый параметр PTR определяет содержимое структуры (данных в других случаях), которое по указателю на файл *fid записывается в файл. Второй параметр sizeof(struct stud) определяет размер структуры в байтах. Третий параметр 1

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

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

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

Вариант записи информации в двоичный файл Результат выполнения программы после комментирования программного кода с за-

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

Результат чтения из двоичного файла

12