Вы на НеОфициальном сайте факультета ЭиП

На нашем портале ежедневно выкладываются материалы способные помочь студентам. Курсовые, шпаргалки, ответы и еще куча всего что может понадобиться в учебе!
Главная Контакты Карта сайта
 
Где мы?
» » » Работа с двумерными массивами Использование одно и двумерных массивов в решении содержательных задач

Реклама


Работа с двумерными массивами Использование одно и двумерных массивов в решении содержательных задач

Просмотров: 3000 Автор: admin

Варианты заданий

Задание 1. При записи данных о соревнованиях по шахматам формируется матрица турнира особого вида. Результат матча может быть 1 (выигранная партия), 0 (проигранная) или 0,5 (ничья). При вводе данных нужно получить симметричную матрицу турнира, где на главной диагонали нули, для обоих участников 0,5 в случае ничьей, а если участник выиграл, то его партнер проиграл, и ему записывается 0. Написать функцию для ввода данных турнира в диалоге с формированием матрицы турнира, которую сохранить в текстовом файле. Написать функцию обработки турнира, чтобы определить победителя. Написать функцию обработки турнира, чтобы распределить участников по убыванию набранных очков.

Задание 2. Фабрика производит валенки, тапочки и боты. Данные об объемах сбыта продукции каждого вида за прошлый год помесячно хранятся в файле. При подведении итогов года дирекция требует найти суммы накопительным итогом для каждого вида продукции, и сохранить эту информацию в файле, а также выяснить, в каком месяце имеет место наибольший сбыт каждого вида продукции. Использовать функции для накопления итогов и для поиска максимума.

Задание 3. Валяльная фабрика производит валенки. Данные об объемах сбыта продукции и о ценах продаж за прошлый год помесячно хранятся в файле в виде таблицы следующего вида:

Месяц

Объем продаж (пар)

Цена продажи (руб.)

Себестоимость (руб.)

Январь

4500

100

20

Февраль

3900

100

25

 

 

 

При подведении итогов года необходимо выяснить динамику сбыта, то есть найти и упорядочить по убыванию информацию о прибылях, приносимых производством. Использовать функцию для вычисления ежемесячной прибыли. Для сортировки матрицы по столбцу «прибыль» использовать функцию сортировки матрицы методом пузырька.

Задание 4. Кот Матроскин владеет стадом коров, а также организовал производство молока, сметаны, творога, масла, сыра. Ежедневно он записывает в текстовый файл дневной сбыт каждого вида продукции, причем цены товара у Матроскина могут изменяться, и цены ему приходится тоже ежедневно записывать. В конце месяца необходимо подвести итог по результатам торговли, чтобы выяснить, какая продукция пользуется наибольшим и наименьшим спросом, а также какая продукция приносит наибольшую и наименьшую прибыль.

Задание 5. В соревнованиях по фигурному катанию каждый спортсмен принимает участие в трех видах соревнований. Каждый вид судят десять судей. Для более точной оценки самый низкий и самый высокий баллы судей отбрасывают. Составить протокол судейства для n участников в виде матрицы, сохраненной в файле. Найти победителя соревнований. Использовать функции для обработки результатов соревнований.

Задание 6. Коротышки собирают урожай огурцов, помидор, гороха, моркови и прочих плодов земли. Работают n коротышек, а Знайка подводит итоги их трудовой деятельности. Он завел текстовый файл, и написал программу, которая ежедневно в диалоге позволяет ввести данные об итогах трудового дня. Эти данные суммируются с итогами предыдущих дней работы, и файл обновляется. По итогам работы в конце уборочной кампании производится оплата. Стоимость сбора одного вида овощей Знайка хранит в отдельном файле. Представьте, что Знайка, это Вы.

Задание 7. Разборчивая невеста занесла в файл данные о своих потенциальных женихах: внешность и богатство она оценила в баллах.

 

Возраст

Внешность

Богатство

Иван

25

15

10

Петр

30

15

10

Панкратий

40

12

50

Борис

45

8

50

Магомед

45

10

100

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

Задание 8. Сорок разбойников провели турнир, в котором каждый разбойник бился с каждым. Сведения о результатах соревнований записали в файл в виде турнирной таблицы, где номера строк и столбцов, – это номера разбойников. Найти самого сильного и самого слабого разбойника. Использовать функцию обработки турнира.

Задание 9. Учебное заведение производит приемные экзамены на новый учебный год. Информация об абитуриентах занесена в текстовый файл в виде матрицы. Каждый должен сдать три экзамена. Те, кто, получил двойку за первый экзамен, ко второму экзамену не допускаются, а кто получил двойку за второй экзамен, не допускаются к третьему. Обработать данные об абитуриентах, выполняя удаление после первого, второго и третьего экзаменов с использованием функции обработки матрицы.

Задание 10. В зале кинотеатра n рядов, в каждом из которых m мест. При бронировании и продаже билетов формируется карта занятости мест, которая сохраняется в текстовом файле после очередной операции. Нужно помочь кассиру и зрителю выполнить процедуру бронирования, для чего организовать диалог:

·       показать на экране карту занятости мест в зале;

·       показать зрителю выбранное им место;

·       зафиксировать выбор места по договоренности со зрителем;

·       сохранить измененную карту;

·       подсчитать стоимость билетов.

Задание 11. Царевна Несмеяна, принимая претендентов на ее руку и сердце, задает каждому М вопросов. Если ответ очень понравился, она присуждает 2 балла, если не очень понравился – 6 баллов, если очень не понравился – 8. Данные опроса она сама записывает в текстовый файл. В конце дня выбирается лучший претендент. Использовать функцию обработки матрицы, чтобы определить самого понравившегося претендента. Этот кандидат приписывается в файл, хранящий многолетнюю историю испытаний, по которому, возможно, когда-то будет принято окончательное решение.

Задание 12. n коротышек собирают урожай m видов различных овощей. Знайка подводит итоги их трудовой деятельности и выполняет расчет. Он завел текстовый файл, и написал программу, которая ежедневно в диалоге позволяет ввести данные об итогах трудового дня. По количеству собранных овощей в конце дня производится оплата. Сбор одного овоща каждого вида Знайка хранит в отдельном файле. Алгоритм оплаты труда сложный. Вычисляется среднее арифметическое собранных всеми за день овощей по каждому виду. Если коротышка собрал больше, чем среднее арифметическое этого вида, то сбор каждого овоща сверху оплачивается в 2 раза дороже. Тот, кто собрал больше всех, получает премию в размете стоимости сбора трех овощей этого вида. Ежедневно Знайка подсчитывает, сколько денег получает каждый коротышка за собранный урожай и суммарные затраты на оплату труда. Эти данные он приписывает в итоговый текстовый файл, чтобы впоследствии подвести общий итог уборочной кампании. Для обработки данных Знайка использует функции.

Задание 13. Кот Матроскин владеет стадом n коров. Ежедневно он записывает в текстовый файл дневной удой каждой коровы. Кот желает приобрести программу, которая позволит подвести итоги производительности его коров. В конце каждого месяца Матроскин желает найти общий удой каждой коровы, а также наибольший и наименьший. Эти данные должны быть программно приписаны в новый текстовый файл, по данным которого Матроскин подведет годовой итог. Использовать функцию (функции) обработки результатов.

Задание 14. Информация о развитии лабораторных животных хранится в файле в виде матрицы, где в строках записаны номера животных, а в столбцах даты (номер недели сначала эксперимента):

 

1

2

3

Крыса1

500

400

400

Крыса2

700

700

800

 

 

 

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

Задание 15. Отец Федор открыл небольшой свечной заводик под Самарой. На заводике льют свечи малые, средние, большие, очень большие и особые. Ежедневный итог по продажам каждого вида продукции в стоимостном выражении матушка дописывает в текстовый файл. По завершении месяца нужно подвести итог, какая суммарная прибыль получена от каждого вида продукции, какой вид приносит наибольшую и наименьшую прибыль.

Задание 16. Сорок разбойников провели соревнование по брейк дансингу. Судили пять судей. Запись о результатах записали в файл в виде матрицы 40*5. Чтобы результат был точнее, самый низкий и самый высокий баллы судей решили не учитывать. Составить оценочную таблицу в виде матрицы, найти победителя соревнований. Использовать функцию обработки результатов соревнований, возвращающую номер победителя.

Задание 17. Дана матрица размером 7*7. Это семеро козлят устроили турнир по копытрестлингу. Сведения о результатах соревнований записали в файл в виде турнирной таблицы, где номера строк и столбцов, – это номера козлят, принявших участие в турнире. Турнирная таблица представлена в виде симметричной матрицы. Найти распределение козлят по силе. Использовать функцию обработки турнира.

Задание 18. Семеро гномов копают золотой песок шесть дней в неделю, а в седьмой отдыхают. Сколько нарыл за день каждый гном, Белоснежка вечером записывает в файл. В воскресенье подводится итоги. Самый трудолюбивый гном награждается поцелуем красавицы, самый ленивый мытьем посуды. Найти самого старательного и самого ленивого гномов. Использовать функцию (функции) обработки результатов.

Задание 19. Информация о развитии лабораторных животных хранится в файле в виде матрицы, где в строках записаны даты (номер дня с начала эксперимента), а в столбцах номера животных:

 

Кролик1

Кролик 2

Кролик 3

1

1500

1400

1300

2

1800

1700

1800

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

Задание 20. Коротышки провели психологическое тестирование «Узнай себя». Запись о результатах записали в файл, в виде кто какие качества имеет, и их оценка в виде итогового балла:

 

Умный

Смелый

Добрый

Знайка

10

5

8

Незнайка

2

10

5

Пончик

5

3

10

Шурупчик

8

8

7

 

 

 

 

Составить оценочную таблицу в виде матрицы, найти самого умного, самого смелого, самого доброго из коротышек. Использовать функции.

Тема №11. Работа со строками символов

Строка представляет собой массив символов, однобайтовых данных целого типа, объявленных как char или unsigned char. Внутреннее представление символа, это его код (ASCII кодом является число в пределах от 0 до 256 согласно кодовой таблице), где первые 32 символа управляющие. Синтаксически признаком символьной константы являются кавычки, например '*' , '?' , 'f' , 'Я' , '#' , '1'.

Строковая константа, это последовательность символов, заключенная в двойные кавычки " ", например "строка символов".

При представления строки в памяти она рассматривается как массив символов, каждый символ хранится в отдельном байте, включая специальные символы. В конце строки должен быть нулевой байт '\0' как признак конца строки. Он добавляется автоматически при инициализации строки и при вводе строки с помощью специальной функции gets. При формировании строки вручную необходимо заботиться о том, чтобы этот символ был добавлен. Поэтому число символов в строке (длина строки) всегда больше на 1 (для нулевого символа).

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

Как массив: char        Str [80];

Это плохой стиль объявления, так как длина строки может изменяться ограниченно.

Как указатель:  char *Str;

Это хороший стиль, но в этом случае строка является динамической, и для указателя необходимо выделение памяти Str = newchar [80];

При инициализации строковых переменных происходит автоматическое выделение памяти под запись значения строки.

char*Str1 = "строка 1  ";     // Длина 11 байт, включая пробелы.

charStr2[9] = "строка 2";    // Длина 9 байт.

charStr1[]  = "строка 3";     // Специальный инициализатор.

charErr[4]  = "ошибка";      // Число символов больше, чем объявлено.

charErr[10] = "не ошибка";//

Пример №1. Символьные константы в строках.

Управляющие символы (Esc-последовательности) в тексте строки предваряются знаком слэш «\». Такой символ, встреченный в строке, приводит к выполнению управляющего воздействия, например, "\n" вызовет перевод строки. Чтобы особые символы были видны как символы, они удваиваются в записи строки.

#include <stdio.h>

void main(void)

{

// Выведем на экран несколько строк.

printf ("%s\n","Строка символов");                                     // Без особенностей.

printf ("%s\n","Слэш \ запишем как \\  \n ");              // Символ слэш удваивается.

printf ("%s\n","Символ ""апостроф"" удваивается");         // Апостроф удваивается.

// Здесь слэш не только не влияет на управление строкой, но и не виден при выводе.

printf ("%s\n","длинные строки могут\

           быть разбиты на части\

           произвольно, на самом\

           деле это одна строка");

// Здесь сочетание \n управляет выводом строки, разбивая ее на части.

printf ("%s\n","длинные строки могут\n быть разбиты на части\n произвольно, на самом\n деле это несколько строк.\n");

}

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

Пример №2. Инициализация строк.Ввод и вывод текстовых строк.

Для ввода и вывода строк можно использовать функции printf, scanf с управляющим признаком формата %s. При вводе строки ее текст будет введен только до первого пробела.

# include <stdio.h>

void main(void)

{

// Примеры объявления и инициализации строк.

           char    Str_1 [10] ;                                  // Выделено 10 байт,

// значения не присвоены.

           char    Str_2 [] = {'с','и','м','в','о','л','\0'};         // Выделено 7 байт,

// инициализация как массива символов.

           char    Str_3 [] = "primer & primer";      // Выделено 16 байт,

// инициализация как текстовой строки.

           char    * Str_4 = "primer string";            // Выделено 14 байт,

// инициализация как указателя.

           char    * Str_5;                                        // Указатель, память не выделена.

// Вывод строк может иметь варианты:

//1). Как строка по формату %s

           printf ("%s\n", Str_2);

//2). Как последовательность символов по формату %c

int       i = 0;

           while ( Str_2[i] )                                  // Пока не встречен последний символ '\0'.

                       printf("%c", Str_2 [i ++]);

           printf("\n");

//3). Как строка без формата

           puts (Str_3);

// Особенности ввода строк. Для Str_1 можно вводит не более 9-ти символов.

           scanf ("%s",Str_1);                                 // Текст будет введен до пробела.

           printf ("%s",Str_1);

           gets (Str_4);                                            // Текст будет введен до Enter.

           puts (Str_4);

}

Пример №3. Строки и указатели.

Строку нельзя считать обычным массивом как раз благодаря наличию нулевого байта '\0' в конце строки. Символьная строка, встреченная в выражении, это адрес массива символов. Может использоваться везде, где можно использовать указатель, но не в левой части операции присваивания. Удобно использовать косвенную адресацию, при этом текущий указатель будет адресовать один символ строки, но в отладчике будет видна оставшаяся часть строки до нулевого байта '\0'. Возможные ошибки связаны с механизмами выделения памяти для динамических строк. Если при объявлении указателя текстовая строка проинициализирована, то выделена память, равная длине этой строки. Нельзя даже пытаться записать в эту строку больше символов, чем выделено. Если же при объявлении указателя текстовая строка не проинициализирована, то память под запись строки не выделена, и этот указатель можно использовать только как рабочую переменную для косвенной адресации при работе с какой-либо строкой.

# include <stdio.h>

void main(void)

{

// Объявлена и проинициализирована строка длиной 57 байт.

char     * Str = "Пример строки текста. Память выделена при инициализации.";

char     * pts;                                            // Указатель на строку.

int       i = 0;

// gets, puts – функции ввода-вывода строк.

           gets (Str);                                       // Нельзя вводить больше, чем 57символов.

           puts (Str);

// Ошибкой будет запись gets (pts);         т.к. память для pts не выделена.

// Присваивание значения указателю:

           pts = Str ;                                      // pts показывает на начало строки.

           pts += 14;                                      // pts показывает на 14-й символ строки Str.

// Присваивание значения pts вносит изменения в строку.

           * pts = 0;                                       // Теперь здесь будет конец строки

// (15-й символ).

           pts = Str;                                       // pts снова показывает на начало строки.

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

           pts ++;                                                    // Возможная ошибка – выход за пределы

           pts ++;                                                    // строки.

// Для полного просмотра строки используется циклический алгоритм, в котором

// управляющей переменной является указатель на очередной элемент (символ)

// строки, который изменяется от адреса начала строки до достижения нулевого

// байта в конце строки.

pts = Str;                                                   // pts указывает на начало строки.

           while ( * pts )                                 // Пока его значение отлично от '\0'.

                       {

                       // Вывод очередного символа и смещение указателя.

                                  printf("%c",*pts++);                          

                       };

           printf ("\n");

// Такой же циклический алгоритм используется и для изменения содержимого

// строки. Управление циклом не изменяется, а изменение символов строки

// достигается изменением значения указателя на очередной элемент (символ)

// строки.

pts = Str;                                                   // pts указывает на начало строки.

           while ( * pts++ )

                       {

                                  *pts++ ='@';// Каждый второй символ будет заменен на '@'.

                       };

           puts (Str);

}

Пример №4. Внутренние коды символов.

Данные символьного типа при хранении имеют внутренние коды. ASCII кодом является число в пределах от 0 до 256. Внутри кодовой таблицы символы расположены в определенном порядке. Значения символов по их кодам можно увидеть, выполнив следующий пример. Здесь переменные i, j пробегают значения так, чтобы все значения выражения (16*i + j) , которые изменяются в пределах от 0 до 255, могли быть выведены в виде матрицы. Символы с кодами 7 – 14 при выводе пропущены.

#include <stdio.h>

#include <conio.h>

void main (void)

{

int       i, j;

clrscr();

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

           {

                       for (j= 0; j < 16; j++)

                       {

                                  if (16*i+j >7 && 16*i+j<14) continue;                  // Управляющие.

                                             // Символьное представление кода символа.

                                             printf("%c ", 16*i+j);     

                       }

                       printf("\n");

           }

}

Использовать внутренний порядок следования кодов символов можно при сравнении символов и при выполнении арифметических операций над символами. Эти операции на самом деле выполняются над значениями внутренних кодов символов.

char     c1, c2;

// Пусть эти символы имеют значения.

// Как сравнить два символа:

int       k;

           k = c1==c2;                                                      // Или c1 > c2 и прочие условия.

           if (c1 >= '0' && c1 <= '9')

                       printf ("Этот символ цифра\n",);                   // Cимвол с1 – цифра.

// Для перебора в алфавитном порядке управляющая переменная цикла

// может быть символьной.

char     c;

           for (c = 'a'; c <= 'z'; c ++)     

                       {.

...

                       }

Пример №5. Адресация в строках.

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

#include <stdio.h>

#include <conio.h>

void main(void)

{

char     *Str1 = "Первая строка.";   // Исходная строка. Длина 15 байт.

char     *pts;                                     // Рабочая переменная для косвенной адресации.

char     *Str2;                                   // Новая строка будет динамической.

puts (Str1);                                      // На экран выведена исходная строка.

// Определение длины строки len выполняется в цикле.

// Управляет циклом переменная pts. Ее начальное значение равно адресу строки.

// *pts, это значение очередного символа строки. *(pts++), – следующего за ним.

// Выход из цикла происходит, когда найден признак конца строки.

int       len = 0;

           pts = Str1;                            // Рабочая переменная указывает на начало.

           do

                       len ++;

           while (*(pts++) !='\0');                   // Поиск нулевого байта и смещение указателя.

           printf ("Длина строки %d\n", len);

// Выделение памяти для строки Str2 динамическое.

           Str2 = newchar [len];                    // Выделено столько же, сколько в Str1.

// Прямая адресация, это посимвольное копирование из Str1 в Str2.

int       i = 0;                                     // Начиная нулевого символа строки.

           while (Str1 != '\0')             // Пока не встречен нулевой байт в конце.

           {

                       Str2[i] = Str1[i];                  // Посимвольно присваивать.

                       i++;                           // И переходить к следующему символу.

           }

// Цикл while заканчивается до переноса нулевого байта в новую строку,

// поэтому по завершении цикла нужно его дописывать программно.

           Str2[i] = '\0';                         // Формируется конец строки.

           puts (Str2);

// В следующем примере прямой адресации тоже посимвольно копируется строка,

// но запись цикла короче. Использование оператора do удобнее тем, что

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

           *Str2 = '\0';                           // Так нужно очистить строку от содержимого.

           i = 0;

           do

                       Str2 = Str1;                  // Присваивание.

           while ( Str1[i++] !='\0');        // Проверка достижения конца строки.

                                                        // Нулевой символ переносится в новую строку.

           puts (Str2);

// Косвенная адресация при посимвольном копировании требует использования

// указателя на char в качестве рабочей переменной.

// В первом случае используем только один указатель на строку, которая будет

// копией. Меняя адрес первой строки, покажем, как легко можно изменить значение

// адреса, которое приведет к потере данных.

// Очистка строки.

           *Str2 = '\0';

// Управляет циклом переменная Str1, адресующая исходную строку.

           pts = Str2;                            // pts – указатель на новую строку.

           while (*Str1 != '\0')

                       *pts ++ = *Str1 ++;  // Str1 изменяется. Адрес, выделенный ранее

                                                        // для этой переменной, изменен операцией

                                                        // ++, строка потеряна.

// Признак конца строки должен быть перенесен в строку – копию.

           *pts = '\0';                            // Получена вторая строка.

           puts (Str2);

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

// новую переменную, чтобы показать в следующем цикле, что нужно сделать, чтобы

// косвенная адресация не изменяла бы адреса исходных строк.

// Для этого требуется две рабочие переменные, два указателя на обе

// строки, играющие роль синонимов строк.

char     * Str3 = "Новая строка";     // Ее длина не больше, чем у копии.

char     *pts_2;                                           // Для работы со второй строкой.

char     *pts_3;                                           // Для работы со третьей строкой.

           pts_2 = Str2;                        // Знает адрес строки.

           pts_3 = Str3;                        // Знает адрес строки.

           *Str2 = '\0';                           // Очистка строки.

// Управляет циклом переменная pts_3, адресующая исходную строку.

           do

                       *pts_2 ++ = *pts_3;  // Оба указателя смещаются одинаково.

           while (*pts_3 ++ != '\0');                         //

puts (Str2);

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

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

// не видны. Выполняются все те же действия, что и в предыдущем примере.

           *Str2 ='\0';

           pts_2 = Str2;

           pts_3 = Str3;

                       while (( *pts_2++ = *pts_3++) !='\0');

           puts(Str2);

}

Пример №6. Функции и строки.

При передаче строк в функции особенностей нет. Передача выполняется так же, как и для массивов. Строка должна быть параметром функции. Отдельно передавать длину строки нет необходимости, так как, во-первых, строка имеет признак конца, а во-вторых, ее длину всегда можно определить, используя функцию strlen библиотеки <string.h>, подробнее о которой далее по тексту. Рассмотрим пример функции преобразования строки, которая удалит из строки «лишние» пробелы, то есть те, что встречаются подряд друг за другом. Эта операция может быть названа сжатием строки. Приведем пример двух функций, первая из которых использует прямую адресацию, вторая косвенную.

#include <stdio.h>

#include <conio.h>

#include <string.h>

// Сжать строку, это означает удалить из нее лишние пробелы.

voidcompress_1( char []);     // Прототип функции с прямой адресацией.

voidcompress_2( char *);      // Прототип функции с косвенной адресацией.

void main(void)

{

char *str = newchar [80];      // Указатель на строку и выделение памяти.

           printf ("\nВведите строку символов с пробелами.\n");

           gets (Str);

           printf ("Наша строка: \n");

           puts (Str);

           compress_1 (Str);                 // Обращение к функции.

           printf ("Наша строка: \n");

           puts (Str);

           printf ("\nВведите строку символов с пробелами.\n");

           gets (Str);

           printf ("Наша строка: \n");

           puts (Str);

           compress_2 (Str);                 // Обращение к функции.

           printf ("Наша строка: \n");

           puts (Str);

getch();

}

// Описание функции, использующей прямую адресацию строки.

// Длину строки Str возвращает функция strlen (Str).

void compress_1 (char Str[])

{

int       i, mid;             // i – рабочая переменная для поиска рядом стоящих пробелов.

                                  // mid – рабочая переменная для сдвига.

           i = 0;              // Внешний цикл поиска рядом стоящих пробелов.

           while (i < strlen (Str) – 1)

                       if ((Str [i] == ' ') && (Str [i+1] == ' '))            // Два пробела рядом.

                                  {          // Внутренний цикл сдвига.

                                             for (mid = i; mid < strlen(Str); mid ++)

                                                        Str [mid] = Str [mid+1];         //символ '\0'тоже сдвигается.

                                  }

                                  else      // Движение по строке, только если не было сдвига.

                                  i++;

}

// Описание функции, использующей косвенную адресацию строки.

void compress_2 (char * Str)

{

char     *ip, *mid;                    // Рабочие указатели для поиска и для сдвига.

           ip = Str;                      // Внешний цикл поиска рядом стоящих пробелов.

           while ( *ip!='\0')

                       if ( *ip==' ' && *(ip+1)==' ')                          // Два пробела рядом.

                                  {          // Внутренний цикл сдвига.

                       mid = ip;                         // Запомнили адрес.

                                             while (*mid != '\0')

                                              {

                                                        *mid =*(mid+1);  // Копирование символа.

                                                        mid++;                 // Смещение указателя.

                                             }

                                  }

                                  else       // Движение по строке, только если не было сдвига

                                  ip ++;

}

Пример №7. Функция, возвращающая строку.

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

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

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <conio.h>

// Основная задача, это сохранить строку – образец. Новая строка будет содержать

// все символы исходной, но после каждого символа исходной строки будет добавлен

// новый символ.

// Функция Transform_1 получает и возвращает строки только через параметры,

// поэтому ее тип void. Память для строк должна быть выделена в main.

void Transform_1(char *Str, char *Ind, char Symbol)

{                                                                // Память для Ind выделена в main

char     *pts;                                               // Рабочая переменная

           pts = Str;                                       // Теперь pts, это исходная строка.

char     *pti;                                               // Рабочая переменная

           pti = Ind;                                        // Теперь pti, это новая срока Ind

           do

           {         // Циклом управляет pts

                       *pti = *pts;                         // Символ приписывается к Ind (*pti)

                                                                  // из Str (*pts)

                       pti++;

                       *pti = Symbol;                             // Symbol приписываетсяк Ind (*pti)

                      pti ++;

           }

           while ( *pts++ != '\0');                             // Выход при достижении конца строки

                                                                  // '\0' перенесен в строку назначения.

}

// Функция Transform_2 получает исходную строку через параметры, а новую

// возвращает через указатель, поэтому ее тип char *. Память для новой строки

// должна быть выделена в теле функции.

char * Transform_2 (char *Str, char Symbol)

{

int len;

           len=strlen (Str);                              // Длинастроки Str

char * Ind;

Ind = new char[len*2];                     // Выделена память для новой строки

char *pts;                                                  // Рабочая переменная

           pts = Str;                                       // Теперь pts, это исходная строка

char *pti;                                                   // Рабочая переменная

           pti = Ind;                                        // Теперь pti, это новая срока Ind

// Алгоритм тот же самый, но запись короче.

           do

                       {

                       *pti ++ = *pts;

                      *pti ++ = Symbol;

                       }

           while ( *pts++ !='\0');

           return Ind;                                      // Возвращается адрес новой строки.

}

// Обращение к этим функциям выполняется различным образом. Вызов

// Transform_1, это оператор-функция, вызов Transform_2, это оператор-выражение,

// его значение должно быть присвоено переменной такого же типа, как и тип

// возвращаемого функцией значения.

void main(void)

{

clrscr();

char *Str = new char[80];

char *Str_new_1 = new char[160];

Str = "Преобразование строки без изменения образца.";

           puts(Str);

           Transform_1 (Str, Str_new_1, '!');          // Для Str_new_1 памятьвыделена.

           puts(Str_new_1);

char     *Str_new_2;                                            // Просто адрес.

                                                                           // память выделит функция.

           Str_new_2 = Transform_2 (Str, '*');

           puts(Str_new_2);

}

Пример №8. Использование библиотек функций работы с символами и строками.

Библиотека функций <ctype.h> используется для работы с символами, имеет много полезных функций. Например, isalpha определит, является ли символ буквой латинского алфавита, isascii определит, имеет ли символ код ASCII (0 – 127), tolower и toupper позволят прообразовать символ латинского алфавита соответственно к нижнему и верхнему регистру, и так далее.

Библиотека <stdlib.h> имеет функции преобразования, которые используются  для преобразования строки в число (atof, atoi) или числа в строку (itoa) и так далее.

Библиотека <string.h> содержит функции преобразования строк. Например, strlen возвращает целочисленную длину строки, включая '\0', strcpy возвращает указатель на копию строки, strcat выполняет конкатенацию строк, strchr поиск первого вхождения символа, strcmp сравнение строк, strstr поиск подстроки в строке и так далее.

Рассмотрим несколько простых примеров использования библиотечных функций.

#include <stdio.h>

#include <ctype.h>

#include <string.h>

// Функция подсчитает, сколько символов в строке являются цифрами, используя

// функцию isdigit, которая получает как входное данное символ (char), и возвращает

// значение 0 или 1.

int cou_dig (char *str)

{

int       count = 0;

           while (*str != '\0')

           {

                       if (isdigit (*str) !=0 ) count++;

                      str ++;

  }

return count;

}

// Используемфункцию cou_dig, атакжебиблиотечныефункции strcpy, strcat, strstr.

void main(void)

{

char     * my_str = "1 2 3 4 5.";

           printf ("Цифр=%d",cou_dig (my_str));

char     * Old_str = "Cтрокатекста";

char     New_str [80];

// Для копирования строки Old_str по адресу New_str используем функцию strcpy.

           strcpy (New_str, Old_str);             // New_str = "Cтрокатекста"

           puts (New_str);

// Для слияния строк (конкатенации) используем функцию strcat.

           strcat (New_str, Old_str);              // New_str = "Cтрокатекста Cтрокатекста"

           puts (New_str);

// Для поиска вхождения подстроки в строку используем функцию strstr.

char     * found = "ока";                            // Строка поиска "ока"

char     * Yes;

           Yes = strstr (Old_str, found);                  // Yes = "окатекста"

           if (Yes==NULL)                            // Если бы вхождения не было.

                       printf ("Нет");

                       else printf("Есть '%s'\n", Yes);

}

Пример №9. Работа с текстом.

Текст может быть представлен двумерными массивами строк. В качестве примера покажем реализацию функция сортировки строк текста в алфавитном порядке (по возрастанию первых символов строки). Используем функции из библиотеки string.h.

#include <stdio.h>

#include <string.h>

#define                       LEN    80                // Наибольшая длина строки.

#define                       SIZE   20                // Наибольшее число строк.

// Функция в качестве параметра использует указатель на массив строк.

// Массив фактически двумерный. Разбивку на строки определяет константа LEN.

void SortStr (char *Srt [LEN], int num)             // Массивстрок, num – егодлина.

{

int       i;

int       flag;

char     buf [LEN];                                               // Для перестановки строк местами.

// Обычная пузырьковая сортировка

flag = 1;

while (flag != 0)

           for (i = 0, flag = 0; i < num – 1; i ++)

                       {

                       if ( strcmp (Str, Str[i+1]) > 0)   // Символ Str > символа Str[i+1]

                                  {  // Перестановка строк

                                             strcpy (buf, Str[i]);

                                             strcpy (Str, Str[i+1]);

                                             strcpy (Str[i+1], buf);

                                             flag = 1;                 // Запоминает факт перестановки.

                                  }

                       }

}

void main(void)

{

char     Text [SIZE][LEN];                // Массив вводимых строк

char     *ps [SIZE];                                    // Массив указателей на строки массива.

int       i, num;                                           // num – число вводимых строк

printf ("Введи строки до пустой строки. \n");

num = 0;

while(( gets (Text[num]) != NULL ) && num <= SIZE && strcmp (Text [num],"") != 0)

           // Условие завершения ввода сложное:

           // · пока gets выполняет удачный ввод (возвращает не пустое значение),

           // · пока число введенных строк меньше, чем наибольшее разрешенное SIZE,

           // · пока строка не пуста, при этом strcmp позволит сравнить значения

           // символов, а не указатели:

           {

                       ps [num]= Text [num];       // Указатель на очередную

                                                                  // прочитанную строку

                       num++;

           }

printf ("Вывод перед обращением к функции сортировки\n");

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

           puts (Text );                               // Введенный массив строк

printf ("\n");

           SortStr (ps, num);

printf ("Вывод после обращения к функции сортировки\n ");

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

           puts (Text );                               // Преобразованный массив строк

printf ("\n");

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

           puts (ps);                          // Указатель на сортированные строки

printf("\n");

}

Варианты заданий

Задание 1.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию преобразования строки, которая вносит изменения в строку текста, повторяя дважды каждую букву строки (знаки препинания и прочие символы не изменять). Преобразовать все строки текста, и новый текст записать в файл F2.

Задание 2.

1. Описать функцию работы со строкой символов, которая найдет, сколько раз в строке встречаются знаки препинания '.', '?', '!' и другие.

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга пробелами. Описать функцию, удаляющую из строки слово с номером М (номер слова М один из параметров функции). В вызывающей программе номер слова лучше всего вводить в диалоге. Преобразовать все строки текста, и новый текст записать в файл F2.

Задание 3.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию преобразования строки, которая после каждого десятого символа вставит в текст сочетание символов ":!:", в начало строки – "!:" , в конец – ":!". Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 4.

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

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга одним символом пробела. Описать функцию, определяющую, есть ли в тексте некоторое слово, заданное заранее (включить в список параметров функции, а в вызывающей программе вводить в диалоге). Описать функцию, удаляющую слово из текста. Преобразовать все строки текста, и новый текст записать в файл F2.

Задание 5.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию, преобразующую строку текста следующим образом: если в строке есть подстроки, заключенные в скобки, удалить их вместе со скобками. Если есть вложения скобок, удалить всю внешнюю скобку. Преобразовать все строки текста, и новый текст записать в файл F2.

Задание 6.

1. Описать функцию работы со строкой символов, которая найдет, есть ли в строке стоящие рядом одинаковые символы, и определит число таких вхождений.

2. Дан текст (2–3 строки) в файле F1. Описать функцию преобразования строки, которая заменяет все одинаковые идущие подряд символы одним вхождением этого символа. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 7.

1. Описать функцию работы со строкой символов, которая проверит, не является ли эта строка палиндромом. Для проверки придется удалить все пробелы, отделяющие слова, и перевести символы в один регистр. Пример палиндрома «А роза упала на лапу Азора».

2. Дан текст (2–3 строки) в файле F1. Описать функцию преобразования строки, которая заменяет все повторные вхождения символа пробел одним символом пробела, в начало строки добавляет слово "НАЧАЛО", в конец слово "КОНЕЦ". Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 8.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию обработки строки, которая удаляет из строки все знаки препинания. Преобразовать все строки исходного текста, и записать новый текст в файл F2.

Задание 9.

1. Описать функции работы со строкой символов, которые найдут самое длинное и самое короткое слово строки.

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая удалит из строки символы, находящиеся рядом (справа и слева) с символом '#'. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 10.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая удалит из исходной строки все слова, имеющие окончание "КАЯ" или "КОЕ". Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 11.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая после каждого пробела вставит в текст восклицательный знак. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 12.

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

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая формирует из исходной строки новую, записывая в нее только подстроки, заключенные в круглые скобки (вместе со скобками). Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 13.

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

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга одним пробелом. Описать функцию преобразования строки: из исходной строки в новую строку переписать только те слова, длина которых больше трех, отделяя их пробелами. Преобразовать все строки текста, и записать новый текст в файл F3.

Задание 14.

1. Описать функцию работы со строкой символов, которая найдет, сколько из слов строки начинаются и заканчиваются одной буквой, например, "абракадабра", "сервис", "кулак" и пр.

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая удаляет из строки все сочетания букв "АЯ" и "ОЕ". Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 15.

1. Описать функцию работы со строкой символов, которая получит массив длин слов этой строки.

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга произвольным числом пробелов. Описать функцию преобразования строки, которая каждое слово отделяет от другого слова сочетанием трех символов "***". Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 16.

1. Описать функцию работы со строкой символов, которая найдет, есть ли в строке символы, отличные от букв, пробела и точки.

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга одним символом пробела. Описать функцию, которая меняет местами первое слово с последним словом. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 17.

1. Для заданного натурального числа n получить его правильное символьное представление в виде строки, где триады цифр отделены друг от друга пробелами. Например, для n = 1753967 запись должна иметь вид: "1 753 976".

2. Дан текст (2–3 строки) в файле F1. Описать функцию преобразования строки, которая заменяет все последовательности цифр, стоящих подряд, одним символом решетки '#'. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 18.

1. Для заданного натурального числа n (n<20) получить его правильное текстовое представление в виде строки текста, например, "три", "девятнадцать", "одиннадцать" и пр.

2. Дан текст (2–3 строки) в файле F1. Описать функцию, которая формирует новую строку, занося в нее символы исходной строки по 10 через каждые десять. То есть, с 1-го по 10-тый, с 21-го по 30-й и т.д. Преобразовать все строки текста, и записать новый текст в файл F2.

Задание 19.

1. Описать функцию работы со строкой символов, которая проверит, начинается ли каждое слово с большой буквы.

2. Дан текст в файле F1 в виде:

ИМЯ ОТЧЕСТВО ФАМИЛИЯ_1

ИМЯ ОТЧЕСТВО ФАМИЛИЯ_2

Описать функцию, которая формирует текстовую строку в формате:

ФАМИЛИЯ И.О.

Сохранить преобразованный текст в файле F2.

Задание 20.

1. Дано натуральное число n (n<100), означающее возраст человека в годах, например, 1, 11, 51 и так далее. Получить текстовую строку, выражающую возраст человека. Например, "Один год", "Одиннадцать лет", "Пятьдесят один год".

2. Дан текст (2–3 строки) в файле F1. Текст состоит из слов, отделенных друг от друга пробелами. Описать функцию, которая находит самое длинное слово в строке, и удаляет его. Преобразовать все строки текста, и записать новый текст в файл F2.

Тема №12. Работа со структурами и объединениями

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

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

Объект называется среднестатистическим, если на нем достигается минимум модуля разности среднего арифметического значений его показателей со средним арифметическим всей группы объектов. Аналогично определяется уникальный объект (на нем достигается максимум).

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

Выясним, кто в группе объектов является:

а) среднестатистическим,

б) среднестатистическим по отдельным показателям,

в) просто поставим задачу найти объект в группе по ключевому значению.

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

Поскольку в группе объектов несколько данных, следует объединить их в массив, где один элемент массива описывает один объект.

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

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

2. Для работы с одним объектом пригодятся функции ввода данных об одном объекте и вывода данных об одном объекте. Имя формального параметра пусть будет Man, это полные данные об одном объекте.

3. Чтобы иметь возможность визуально сравнить данные, требуется вывод общей информации, наверное, в виде таблицы.

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

Функция поиска может вернуть номер элемента в массиве структур или указатель на объект. Покажем это на примере функций поиска. Функция поиска среднестатистического объекта вернет его номер в массиве структур. Имея функцию вывода, мы легко выведем его данные на экран с использованием операции разыменования []. Функция поиска среднего по k-тому показателю вернет указатель на структуру. Имея функцию вывода, мы легко выведем его данные на экран с использованием операции разыменования *.

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

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

#include <stdio.h>

#include <conio.h>

#include <io.h>

#include <math.h>

#include <string.h>

// Описание абстрактного типа «Объект» с именем Person использует инструкцию

// typedef, потому что объявлений объектов указанного типа будет несколько.

typedefstruct

{

           char    Name [10];       // Поле «Имя», статический символьный массив.

                                               // Символов в имени не более 10-ти.

           char    *Surname;        // Поле «Фамилия»,

                                               // динамический символьный массив.

                                               // Для нее должна быть выделена динамическая

                                               // память перед присваиванием значения этой

                                               // переменной.

           int       Data [5];          // Поле «Показатели», статический массив данных.

           int       Sum;                // Поле «Сумма» накапливает и сохраняет

                                               // сумму баллов.

           float    Var;                 // Поле «Среднее» вычисляет и сохраняет

                                               // средний показатель.

} Person;        // Имя типа данного "Person"

// Функция ввода данных об одном объекте возвращает объект.

voidIn (Person & Man)         // Одно данное типа Person возвращается по ссылке

{                                             // через параметр.

           puts ("Введите имя: ");

           scanf ("%s", &Man.Name);

           puts ("Введите фамилию: ");

           Man.Surname = newchar [10];     // Обязательно выделить память.

                                                                  // Число символов в фамилии не более 10-ти.

           scanf ("%s", Man.Surname);          // & при вводе значения указателя не пишем.

           puts ("Введите данные: ");

           Man.Sum = 0;                                // Будет накоплена сумма показателей при вводе.

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

                       {

                       scanf ("%4d", &Man.Data );

                       Man.Sum += Man.Data;

                       }

           Man.Var = (float) Man.Sum / 5.;   // Вычислен средний показатель.

}

// Функция вывода полных данных об одном объекте.

void Out (Person Man)                             // Передаетсяданноетипа Person

{

           printf ("%s ", Man.Name);

           printf ("%s ", Man.Surname);

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

                       printf ("%4d",Man.Data);                  // Показатели выводятся одной строкой.

           printf ("\nСумма баллов: %d  ", Man.Sum);

           printf ("Среднее: %6.2f\n", Man.Var);

}

// Функция вывода данных обо всех объектах в форме таблицы.

void Out_All (Person Man [], int n)          // Передается n данныхтипа Person

{

printf ("====================================================\n");

printf ("ИМЯ \t ФАМИЛИЯ \t  ДАННЫЕ  \t  CУММА  СРЕДНЕЕ\n");

printf ("====================================================\n");

for (int k = 0;k < n; k++)

           {

           printf ("% –10s ", Man[k].Name);

           printf ("% –10s ", Man[k].Surname);

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

                       printf ("%4d", Man[k].Data);

           printf("%4d ",Man[k].Sum);

           printf("%6.2f \n",Man[k].Var);

           }

printf ("====================================================\n");

}

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

// полей Var по всему массиву Man.

float Sred (Person Man [], int n)      // Передается n данныхтипа Person

{

float Var = 0;                                   // Переменная Var не имеет отношения к полю

                                                        // структуры с именем Var.

           for (int i = 0; i < n; i++)

                       Var += Man.Var;

  return Var / (float) n;            // Среднее по всем средним.

}

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

// Номер показателя (от 0 до 5), это один из параметров функции.

float Sred_k (Person Man [], int n, int k) // Передается n данныхтипа Person

{                                                                // и номер показателя k.

float    Var_k = 0;                                     // Var_k – средний по одному показателю.

for (int i = 0; i < n; i++)

                       Var_k += (float) Man.Data[k];// Складывает один k-тый показатель по

                                                                           // всем объектам.

           return Var_k / (float) n;                          // Среднее по k-тому показателю.

}

// Функция определяет номер среднестатистического объекта в массиве.

int Sred_Stat (Person Man [], int n)          // Передается n данных типа Person

{

floatVar_All = Sred (Man,n);                            // Средний показатель по всем объектам.

float Var_min = fabs(Var_All-Man[0].Var);     

intNom = 0;                                    // Наименьший имеет номер 0.

           for (int i = 0; i < n; i++)

                       if ( fabs (Var_All – Man.Var) < Var_min)

                                  Nom = i;        // Запоминаем номер самого среднего.

           returnNom;

}

// Функция определяет объект, среднестатистический по k-тому показателю,

// и возвращает указатель на найденный объект.

Person * Sred_Stat_k (Person Man [], int n, int k)      // Передается n данныхтипа Person

{                                                                         // и номер показателя.

float Var_k = Sred_k (Man, n, k);   // Находим среднее значение k-того

                                                        // показателя по всем объектам.

float Var_min = fabs (Var_k – Man[0].Data[k]);

           Person * Nom = Man;                    // Указатель Nom запоминает адрес

                                                        // объекта.

           for (int i = 0; i < n; i++)

                       if ( fabs (Var_k – Man.Data[k]) < Var_min)

                                  Nom = Man + i;      // Запоминаем адрес самого среднего.

           return Nom;

}

// Функция поиска объекта по фамилии. Передается n данных типа Person, и

// Who – строка, содержащая фамилию искомого объекта. Выполняется прямой

// поиск по всей группе объектов путем последовательного сравнения искомой

// строки с полем Surname каждого элемента массива Man.

// Функция возвращает указатель на найденный объект или NULL.

Person * Found_Fam (char *Who, Person Man [], int n)

{

           for (int i = 0; i < n; i++)

                       if ( strcmp (Who ,Man.Surname) == 0)                // ==0, значит, найдено.

                                  return Man+i;                                      // Возвращаетадрес.

           returnNULL;                                 // Возвращает NULL, если поиск неудачен.

}

// Продемонстрируем текст программы, которая объявляет данные и

// осуществляет управление ими путем вызова функций обработки данных.

void main (void)

{

int       n;

// Объявлен массив структур, то есть данных типа Person.

PersonAll_Person [20];

printf ("Введите количество\n");              // Реальное количество данных n.

scanf ("%d", &n);

// Ввод данных выполняется в цикле вызова функции In ввода одного объекта.

for (int i = 0; i < n; i++)

           {

           In (All_Person);

           // Out (All_Person);

           }

// Вывод на экран полной таблицы.

           Out_All(All_Person,n);

// Для поиска номера среднестатистического объекта вызывается функция Sred_Stat.

// Ей передается весь массив структур.

           int Found = Sred_Stat (All_Person, n);

           printf ("Самый средний имеет номер: %d\n", Found);

           printf ("Его данные: \n");

           Out (All_Person [Found]);

// Снова выведем таблицу на экран.

           Out_All(All_Person,n);

// Для поиска значения объекта, среднестатистического по k-му показателю

// вызывается функция Sred_Stat_k. Ей передается весь массив структур.

// Она возвращает указатель на объект.

Person *Found_k;

           for (int k = 0;k < 5;k ++)

           {

                       printf ("Средний по %d -му показателю\n", k);

                       Found_k = Sred_Stat_k (All_Person, n, k);

                       Out (*Found_k);

  }

// Поиск объекта по фамилии.

char Surname [10];                 // Тоже фамилия, но не та, что в Person.

puts ("Введите строку для поиска\n");

scanf ("%s", Surname);                    //

Person * Who;                                 // Функция возвращает указатель.

           Who = Found_Fam (Surname, All_Person, n);

           if (Who != NULL)                // Проверяем, найден объект или нет.

                                  Out (*Who);

                       else

                                  puts("Такого нет.\n");

}

Варианты заданий

Задание 1. Определить структуры, описывающие шар и точку в трехмерном пространстве.

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

Задание 2. Определить структуру для описания понятия алгебраический полином.

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

Задание 3. Определить структуру для регистрации автомашин. Она должна иметь следующие поля: фамилия владельца, дата регистрации, марка машины, год выпуска, цвет, регистрационный номер.

Написать и протестировать функции для регистрации новой машины, удаления машины из регистрационного списка, поиска машины по марке и по цвету, а также по сочетанию признаков «марка и цвет».

Задание 4. Определить структуру для регистрации автомашин. Она должна иметь следующие поля: фамилия владельца, дата регистрации, марка машины, год выпуска, цвет, регистрационный номер.

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

Задание 5. Определить две структуры, описывающие точку в полярной системе координат и декартовой системе координат.

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

Задание 6. Определить структуру, описывающую прямоугольник со сторонами, параллельными осям координат (прямоугольник задаётся двумя точками – левой нижней и правой верхней).

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

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

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

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

Написать и протестировать функции для ввода и вывода общей информации о багаже. Определить, имеются ли два пассажира, багажи которых совпадают по числу вещей и различаются по весу не более чем на 0,5 кг. Выяснить, имеется ли пассажир, багаж которого превышает багаж каждого из остальных пассажиров и по числу вещей и по весу.

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

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

Задание 10. Определить структуру, описывающую сведения об ученике, с полями: имя, фамилия, название класса, в котором он учится (год обучения и буква).

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

Задание 11. Определить структуру, описывающую сведения об ученике, с полями: имя, фамилия, название класса, в котором он учится (год обучения и буква).

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

Задание 12. Определить структуру, описывающую сведения об ученике, с полями: имя, фамилия, название класса, в котором он учится (год обучения и буква), а также отметки, полученные учениками в последней четверти.

Написать и протестировать функции для добавления нового ученика, для вывода информации об одном ученике и вывода общей информации. Выяснить, сколько учеников имеют отметки не ниже 4. Выяснить, сколько учеников имеют тройки в четверти.

Задание 13. Определить структуру, описывающую дату, с полями число, название месяца, год. Написать и протестировать функции для ввода даты, вывода в формате «ЧЧ.ММ.ГГ» и «ЧЧ Месяц ГГ». Пусть есть некоторое количество дат, связанных с некоторым событием, например, исторической датой. Написать и протестировать функции для сортировки этих данных по дате и по названию события.

Задание 14. Определить структуру, описывающую сведения о книге, с полями: фамилия автора, название и год издания.

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

Задание 15. Определить структуру, описывающую сведения о книге, с полями: фамилия автора, название, год издания.

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

Задание 16. Определить структуру, описывающую сведения о сотрудниках учреждения, с полями: фамилия, имя, отчество, занимаемая должность, номер телефона.

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

Задание 17. Определить структуру, описывающую кубики: размер (длина ребра в сантиметрах), цвет (красный, желтый, зеленый или синий) и материал (деревянный, металлический, картонный).

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

Задание 18. Определить структуру, описывающую кубики: размер кубика (длина ребра в сантиметрах), его цвет (красный, желтый, зеленый или синий) и материал (деревянный, металлический, картонный).

Написать и протестировать функции для ввода и вывода данных, а также функции поиска количества кубиков с указанными значениями «материал» и «длина ребра». Например, найти количество деревянных кубиков с ребром 3 см и количество металлических кубиков с ребром 5 см.

Задание 19. Определить структуру, описывающую сведения о веществах: название вещества, его удельный вес и проводимость (проводник, полупроводник, изолятор).

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

Задание 20. Определить структуру, описывающую сведения о веществах: название вещества, его удельный вес и проводимость (проводник, полупроводник, изолятор).

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

Задание 22. Определить структуру, описывающую сведения об игрушках: название игрушки, ее стоимость и возрастные границы детей для которых она предназначена (например, для детей от двух до пяти лет).

 


Информация

Комментировать статьи на нашем сайте возможно только в течении 60 дней со дня публикации.

Популярные новости

Статистика сайта



Rambler's Top100



 
Copyright © НеОфициальный сайт факультета ЭиП