- •Предисловие
- •Библиографический список
- •Контрольные вопросы
- •Библиографический список
- •Тема 2 Переменные и базовые типы данных языка с
- •Контрольные вопросы
- •Библиографический список
- •Тема3 Организация циклов в языке с
- •Контрольные вопросы
- •Библиографический список
- •Тема 4 Принятие решений. Условные операторы в языке с
- •Контрольные вопросы
- •Библиографический список
- •Тема 5 Числовые массивы в языке программирования с
- •Тип имя_массива[размер];
- •Тип имя_массива[размер1] [размер2];
- •Тип имя_массива[размер1] [размер2] [размерN];
- •Контрольные вопросы
- •Библиографический список
- •Тема 6 Символьные массивы в языке с. Работа со строками
- •Тип имя_массива[размер];
- •Тип имя_массива[размер1] [размер2];
- •Тип имя_массива[размер1] [размер2] [размерN];
- •Контрольные вопросы
- •Библиографический список
- •Тема 7 Указатели в языке программирования с
- •Int *ptr; // объявили указатель на целую переменную
- •Контрольные вопросы
- •Библиографический список
- •Тема 8 Указатели и массивы в языке с
- •Int data[7]; // обычный массив
- •Int *pd[7]; // массив указателей
- •Контрольные вопросы
- •Библиографический список
- •Тема 9 Динамическое распределение памяти в языке с
- •If (!ptr) // условие логического отрицания
- •If (!ptr) // условие логического отрицания
- •Контрольные вопросы
- •Библиографический список
- •Тема 10 Функции Общие сведения о функциях языка с
- •Fun(тип имя_перем1, тип имя_перем2, , тип имя_перем n)
- •Контрольные вопросы
- •Библиографический список
- •Тема 11 Указатели и функции в языке программирования с
- •Тип_возвращаемый_функцией(*имя_указателя_на_функцию)(аргументы);
- •Контрольные вопросы
- •Библиографический список
- •Тема 12 Файловый ввод/вывод в языке с
- •Контрольные вопросы
- •Библиографический список
- •Тема 13 Структуры – производные типы данных языка с
- •Int age; // возраст
- •Int age; // возраст
- •Int age; // возраст
- •Int age; // возраст
- •Int age; // возраст
- •Int age; // возраст
- •Контрольные вопросы
- •Библиографический список
- •Тема 14 Объединения и перечислимые типы в языке с
- •Контрольные вопросы
- •Библиографический список
- •Тема 15 Структуры и функции языка с
- •Контрольные вопросы
- •Библиографический список
- •Тема 16 Операции с разрядами (битами) в языке с
- •Контрольные вопросы
- •Библиографический список
- •Тема 17 Программы, состоящие из нескольких файлов, на языке с
- •Спецификатор extern
- •Спецификатор static
- •Спецификатор register
- •Спецификатор auto
- •Контрольные вопросы
- •Библиографический список
- •Тема 18 Рекурсивные алгоритмы и функции
- •Переместить (a, b);
- •Контрольные вопросы
- •Библиографический список
- •Тема 19 Препроцессор языка с
- •Директива #define
- •Директива #error
- •Директива #include
- •Директивы условной компиляции
- •2_ Я_последовательность операторов программного кода
- •3_ Я_последовательность операторов программного кода
- •Директива #line
- •Директива#pragma
- •Предопределенные символические константы
- •Макрос подтвержденияassert
- •Контрольные вопросы
- •Библиографический список
- •Тема 20 Программы на языке с при использовании статически подключаемой библиотеки
- •Контрольные вопросы
- •Библиографический список
- •Тема 21 Использование аргументов командной строки в с
- •Контрольные вопросы
- •Контрольная работа № 2 Покупки в супермаркете
- •Приложение Управление конфигурациями проекта в Visual Studio 2010
Int age; // возраст
double hourlysalary; // почасовой оклад
};
Как видно, шаблон структуры struct employeeсостоит из символьных массивов типаchar, целого числа типаintи числа с плавающей точкой и двойной точности типаdouble. Описание элементов производится в фигурных скобках, после закрывающей скобки обязательна точка с запятой.
Определение структуры начинается с ключевого слова struct. Идентификаторemployeeявляетсяименем-этикеткой(tag name),дескриптором, именует структуру и используется совместно с ключевым словомstructдля объявления переменных структурного типа [4].
Переменные структуры объявляются так же, как и переменные других типов. На основе приведенного шаблона сделаем несколько объявлений новых структурных переменных:
struct employee new_ employee, * employeePtr, stack[120];
Здесь new_employee – переменная типа struct employee, *employeePtr – указатель на struct employee, stack[120] – массив из 120 элементов типа struct employee.
Переменные new_employee, *employeePtr, stack[102] могут быть объединены с определением структуры, а именно:
struct employee {
char Name [20+1]; // имя
char Surname [20+1]; // фамилия
Int age; // возраст
double hourlysalary; // почасовой оклад
} new_employee, *employeePtr, stack[120];
Имя-этикеткане является для структуры обязательным. Если определение структуры не содержит его, то переменные для этой структуры могут быть объявлены только в ее определении, но не отдельно [1].
При создании структур часто используется ключевое слово typedef(оператор). Оно предоставляет программисту средство создания синонимов (или псевдонимов) для ранее определенных типов данных. К нему часто обращаются для того, чтобы дать укороченное имя структурному типу [4]. Например, оператор вида
typedef struct card Card;
определяет новый тип с именем Cardкак синоним типаstruct card.
Ключевое слово typedefможет быть использовано в определении типа структуры без имени-этикетки. Например,
typedef struct {
char**Name; // имя
char**Surname; // фамилия
Int age; // возраст
double hourlysalary; // почасовой оклад
} Man;
создает тип Manбез использования отдельного оператораtypedef. В данном примере необходимо предусмотреть выделение памяти под символьные указатели.
Созданный тип Manможно использовать для объявления структурных переменных типаstruct employee, например
Man stack[120];
Примечание. Использованиеtypedefпомогает сделать программу более переносимой.
Синтаксис инициализации структур аналогичен инициализации массивов. Например, выполним инициализацию структуры:
struct employee {
char Name [20+1]; // имя
char Surname [20+1]; // фамилия
Int age; // возраст
double hourlysalary; // почасовой оклад
} new_employee;
Возможный вариант инициализации:
struct employee {
char Name [20]; // имя
char Surname [20]; // фамилия
Int age; // возраст
double hourlysalary; // почасовой оклад
} new_employee = { "Peter", "Smith", 25, 6.78 };
При инициализации структуры ее элементы (инициализаторы) должны соответствовать заданному типу и отделяться друг от друга запятыми.
Доступ к элементам (компонентам, полям) структуры осуществляется двумя способами:
с помощью оператора связывающей точки (оператора точки) «.» при непосредственной работе со структурой;
с помощью стрелки «–>»при использовании указателей на структуры.
Общий формат доступа к элементам структуры имеет вид
имя_переменной_структуры.имя_поля;
имя_указателя_на_структуру–>имя_поля;
(*имя_указателя_на_структуру).имя_поля;
Например, для рассмотренной инициализации можно изменить почасовой оклад с помощью оператора точки и указателя на структуру:
new_employee.hourlysalary = 21.0;
employeePtr –> hourlysalary = 21.0;
Следует обратить внимание на то, что new_employee– это имя всего объекта-структуры, аhourlysalary– имя элемента этой структуры. Аналогично и в случае использования указателя*employeePtrна структуру.
При изменении полей структуры следует обратить внимание на случай со строками, например:
strcpy(new_employee . name, "Stephen");
При этом должен быть предусмотрен заголовочный файл <string.h>. для функцииstrcpy().
Когда объявлен массив структур, например stack[120], то это означает, что создано 120 наборов переменных, каждый из которых организован так, как определено в структуре с дескрипторомemployee. Чтобы получить доступ к определенной структуреstack[120], следует указать имя массива с индексом, который изменяется от 0 до 119. Например, для пятой структуры можно сделать изменения в почасовом окладе:
stack[4].hourlysalary = 121.5;
Как и в других массивах переменных языка С, в массивах структур индексирование начинается с нуля. Членами структуры могут быть также массивы или структуры. Когда одна структура является членом другой, она называетсявложенной [2].
Рассмотрим пример:
struct X = {
int A[7][8];
float b;
char ch;
struct employee Emp2;
} Y;
Инициализация элементов двухмерного массива Аможет быть такой:
Y.A[2][5] = 99;
Инициализация вложенной структуры может быть следующей:
Y.Emp2.hourlysalary = 12.75;
В соответствии со стандартом С89 структуры могут быть вложенными вплоть до 15-го уровня, стандарт С99 допускает уровень вложенности до 63-го включительно [2].
ПРАКТИЧЕСКАЯ ЧАСТЬ
Пример1.Написать программу структурного описания каталога одной книги.
Программный код решения примера
#include <stdio.h> #include <conio.h> #include <string.h> #define N 40 struct book { // определение структуры char title[N+1]; // название книги char author[N+1]; // автор int year; // год издания int page; // количество страниц float price; // цена в у.е. } Library;
int main (void) { // Инициализация полей структуры Library.year = 2007; Library.page = 496; Library.price = 12.78F;
strcpy_s(Library.title, N, "Programming in C"); strcpy_s(Library.author, N, "Stephen G. Kochan");
// Вывод на консоль printf("\n\t Title: %c\n", Library.title); printf("\t Author: %c\n", Library.author); printf("\t Year: %d\n", Library.year ); printf("\t Number of pages: %d p.\n", Library.page ); printf("\t Price: %1.2f y.e.\n", Library.price);
printf("\n\n Press any key: "); getch(); return 0; } |
В программе использованы функции strcpy_s()вместо стандартных функцийstrcpy(), что позволило избавиться от предупреждений в системеVisualStudio2010.
Результат выполнения программы показан на рис.13.1.
Рис.13.1. Пример инициализированных полей структуры
Задание1
Совместите объявление и инициализацию структуры. После инициализации структуры выполните изменение ее полей с последующим выводом на консоль.
Примените оператор typedef.
Поля структуры titleиauthorопределите с помощью указателей.
Произведите инициализацию структуры после ввода значений полей с клавиатуры.
Выполните вывод полей структуры в текстовый файл compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
Пример2.Написать программу анализа средней успеваемости четырех студентов по четырем предметам за сессию на основе структурного типа данных.
Программный код решения примера
#include <stdio.h> #include <conio.h> #include <stdlib.h>
#define N 4 // число студентов #define CH 30 // число символов для фамилии или имени
// Определение структуры Struct { char**name; // имя студента char**surname; // фамилия студента int M; // отметка по математическому анализу int A; // отметка по алгебре int H; // отметка по истории int In; // отметка по информатике
} student[N];
int main (void) { float mark; int i;
// Выделение памяти для символьных указателей for (i = 0; i < N; ++i) { student[i].name = (char**) malloc(CH*sizeof(char)); student[i].surname = (char**) malloc(CH*sizeof(char)); } printf("\n"); for (i = 0; i < N; ++i) { printf("\t Enter a name of %d student \n\t: ", i+1); gets_s( student[i].name, CH - 1);
printf("\t Enter a surname of %d student \n\t: ", i+1); gets_s( student[i].surname, CH – 1 );
printf("\t Enter marks in 4 subjects for %d student (through a blank) \n\t: ", i+1);
scanf_s("%i%i%i%i", &(student[i].M),&(student[i].A), &(student[i].H),&(student[i].In)); _flushall(); } puts("\n=====================================================================================");
printf("\t Statement of Achievement students:\n"); puts("======================================================================================\n"); for (i = 0; i < N; ++i) { printf("\t %c \t %c:\n\t Mathematical analyses, Algebra, History, Informatics\n \ \n\t\t %d\t\t %3d\t \ %3d\t %5d\n----------------------------------------------\n", \ student[i].name, student[i].surname, \ student[i].M,student[i].A,student[i].H,student[i].In); }
mark = 0.0F; // F – спецификатор для типа float
for (i = 0; i < N; ++i) {
mark += (student[i].M + student[i].A + student[i].H + student[i].In);
}
// Средняя оценка группы из 4 (N)студентов printf("\n\t The average mark groups of %d students: %1.4f", N, mark/(4*N)); // 4*N - общее количество оценок
// Освобождение памяти for (i = 0; i < N; ++i) { free(student[i].name); free(student[i].surname); }
printf("\n\n Press any key: "); getch(); return 0; }
|
В программе использован массив структур – переменная student[N]. С целью определения имени и фамилии предварительно выделяется память под символьные указатели с помощью функцийmalloc(), для которых включен заголовок#include <stdlib.h>.
Определение структуры выполнено за пределами главной функции main(), что позволяет использовать ее в других функциях, если бы они были определены в программе.
Шаблон структуры задан без имени-этикетки.
Возможный результат выполнения программы приведен на рис.13.2.
Рис.13.2. Пример сводной ведомости успеваемости студентов
Задание2
Выполните усреднение оценок для каждого студента.
Предусмотрите ввод названий предметов (математический анализ, алгебра и т.д.) и определите их в виде инициализаторов структуры.
Увеличьте число студентов до семи и произведите запись результатов в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
В шаблоне структуры задайте теговое имя. Проанализируйте работу программы.
Примените оператор typedef для определения структурного типа данных.
Расположите фамилии (с именем) студентов в порядке возрастания их среднего балла за сессию.
Пример3.Написать программу создания карточки служащего с помощью структурного типа данных и указателя на структуру. Предусмотреть инициализацию полей структуры и изменение этих полей.
Для решения примера воспользуемся структурой, рассмотренной в теоретической части данной темы:
struct employee {
char Name [20+1]; // имя
char Surname [20+1]; // фамилия