Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Структуры как параметры функцийСодержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Структуры, так же, как и любые другие типы, могут быть параметрами функций. Существуют различные способы передачи структур в функции. В функцию в качестве аргументов можно передавать: а) элементы структуры; б) всю структуру; в) указатель или ссылку на структуру. Следует помнить, что структуры стандартно передаются в функцию по значению; поэтому в случае необходимости изменять фактический параметр в функцию следует передавать адрес структуры.
Задача 161. Рассмотрим механизм взаимодействия формальных и фактических параметров для этих случаев на примере функции summa(), вычисляющей зарплату (sum) каждого служащего по заданной тарифной ставке (tarif) и количеству отработанных часов (work).
// vozv_ank_2011.cpp #include "stdafx.h" #include <string.h> #include<conio.h> #include<stdio.h> #include <iostream> using namespace std;
// Массив анкет, Функции и структуры, возврат структур
#define LIM 30 // число служащих struct anketa // anketa - имя нового типа! { char fio[30]; int tabn; float tarif; int work; float sum; };
// Варианты функции summa (1-5)
// 1) параметры - элементы структуры //double summa1(double x, int y) //{ // return x*y; //}
// 2) арг - указатель на структуру //double summa2(const struct anketa *uk) //{ // return (uk->tarif*uk->work); //}
// 3) арг - сама структура //double summa3(anketa nachisleno) //{ // return (nachisleno.tarif*nachisleno.work); //}
// 3a) арг - ссылка на структуру. //Чаще всего параметры-структуры передаются в функции по //ссылке (при объявлении за именем типа структуры ставят знак &). //В этом случае фактически в функцию передается адрес структуры //и функция работает с тем же экземпляром, что и вызывающая //программа. void summa3a(anketa &nachisleno) { nachisleno.sum = (nachisleno.tarif*nachisleno.work); }
// 4)возврат результата через указатель // двусторонняя передача информации // прототип: void summa(struct anketa *) //void summa4(struct anketa *uk) //{ // uk->sum=(uk->tarif*uk->work); //}
// 5) возврат функцией результата через возврат структуры // здесь функция создает собственную копию структуры vedom[] //struct anketa summa5(struct anketa rab) //{ // rab.sum=(rab.tarif*rab.work); // return rab; //}
int main() { anketa vedom[LIM]; //массив структур типа anketa int k=0,i; system ("chcp 1251"); cout<<"Введи до "<<LIM<<" фамилий"<<'\n'; cout<<"Для прекращения - Enter в начале строки"<<'\n'; cout<<"Фамилия "<<k+1<<" -го служащего"; while((gets(vedom[k].fio)!=NULL)&& (vedom[k].fio[0])!='\0' &&k<LIM) { cout<<"табельн номер - "<<vedom[k].fio; cin>>vedom[k].tabn; cout<<"часовой тариф - "<<vedom[k].fio; cin>>vedom[k].tarif; cout<<"отраб часов - "<<vedom[k].fio; cin>>vedom[k].work; // непосредсвенное вычисление поля sum без функции // vedom[k].sum = vedom[k].tarif*vedom[k].work;
// 1) передача функции элементов структуры // vedom[k].sum = summa1(vedom[k].tarif,vedom[k].work);
// 2) передача функции указателя на структуру // vedom[k].sum = summa2(&vedom[k]);
// 3) передача функции всей структуры в качестве аргумента // vedom[k].sum = summa3(vedom[k]);
// 3а) передача функции ссылки на структуру как аргумент summa3a(vedom[k]);
// 4) возврат функцией результата через указатель // summa4(&vedom[k]);
// 5) возврат функцией результата через возврат структуры // vedom[k]=summa5(vedom[k]);
//ВНИМАНИЕ!!! fflush(stdin); //очистить входной поток! // Иначе 2-ю фамилию уже не введем, gets() определяет NULL
k++; if(k<LIM) cout<<"Фамилия "<<k+1<<" -го служащего "; } cout<<"\n\n\n\tВедомость на выплату зарплаты\n\n"; for(i=0;i<k;i++) printf("\n%-20s \t %10.2f\t %6d %10.2f\t ", vedom[i].fio,vedom[i].tarif,vedom[i].work, vedom[i].sum); getch();return 0;
}
В заключение приведем итоговую программу, иллюстрирующую некоторые типовые приемы работы со структурами, в частности, сортировку массива структур и поиск в текстовых полях массива структур.
Задача 162. Программа создает статический массив структур, содержащий фамилии служащих, их табельные номера, по запросу вводит часовую тарифную ставку и количество отработаных часов, а затем вычисляет зарплату служащего, сортирует записи в алфавитном поряде следования фамилий и выводит на экран ведомость на получение зарплаты. Реализован поиск по полю fio.
struct anketa //anketa - имя нового типа! { char fio[30]; int tabn; float tarif; int work; float sum; }; void strsort(anketa str[],int n); //прототип
// функция вычисления зарплаты //void summa (anketa *uk)//указатель на структуру //{ // uk->sum = uk->tarif*uk->work; //}
double summa(anketa rab) // параметр - сама структура { return rab.tarif*rab.work; }
int main() { //массив структур типа anketa anketa vedom[]={ { "Иванов И. И.", 1234}, { "Петров П. П.", 2345}, { "Бендер О. И.", 3456}, { "Ивановский П. А.", 4567}, { "Петров А. П.", 6789 }, { "", 0} //признак конца списка };
system("chcp 1251"); //переключаем в кодировку win1251 int k=0,i; //setlocale(NULL, ".1251");-без ввода строки //LIM - реальное (!) число записей int LIM = sizeof(vedom)/sizeof(anketa); for(i=0; i< LIM-1; i++) printf("\n%-20s %8d \n", vedom[i].fio,vedom[i].tabn); //getch(); cout<<"Введи до "<<LIM-1<<" записей"<<'\n'; while((vedom[k].fio[0])!='\0'&& k<LIM) { cout<<"часовой тариф - "<<vedom[k].fio<<" ";cin>>vedom[k].tarif; if(!vedom[k].tarif) break; cout<<"отраб часов - "<<vedom[k].fio<<" ";cin>>vedom[k].work; //vedom[k].sum = vedom[k].tarif*vedom[k].work; //без функции
//summa(&vedom[k]); //к функции с указателем на структуру vedom[k].sum=summa(vedom[k]);//к функции аргумент - сама структура k++; } //getch();
// обратиться к сортировке strsort(vedom,k);
cout<<"\n\n\n\t\tВедомость на выплату зарплаты\n\n"; for(i=0; i<k; i++) printf("\n%20s %10.2f %8d %10.2f", vedom[i].fio,vedom[i].tarif,vedom[i].work, vedom[i].sum);
//*************** ПОИСК ПО ФИО с 2010г.*********** char name[30]; int found=0; k=0; cout<<"\n\n\nВВЕДИ Фамилию "; cin >> name; while(vedom[k].fio[0]!='\0' && k<LIM) { if(strstr(vedom[k].fio, name)) if(vedom[k].fio[strlen(name)]==' ')//fio завершается пробелом? // если этот оператор не вставить, то по введенной name Макогон будут // обработаны и Макогоненко и Макогонский и... { printf("\n%-20s %8d %10.2f", vedom[k].fio, vedom[k].tabn, vedom[k].sum); found++; } k++; } if(found>0) cout<<"\nНАЙДЕНО "<<found << " фамилии "<<name<<'\n'; else cout << name<< "-Фамилия отсутствует в справочнике\n";
getch();return 0; }
// для массива структур - сортировка void strsort(anketa str[],int n) { anketa rab; int i,j; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) if(strcmp(str[i].fio,str[j].fio)>0) { rab=str[i]; str[i]=str[j]; str[j]=rab; } }
ФАЙЛЫ. ПОТОКОВЫЙ ВВОД-ВЫВОД Файл–физический объект, который содержит данные. Работа с файлами в С++ реализуется либо средствами методов ООП, либо с помощью функций, унаследованных от стандартной библиотеки С для работы с потоками. Каждый способ имеет свои преимущества. В программах, не использующих механизм классов и объектов, удобнее использовать потоковый ввод-вывод в стиле языка С. В С/С++ все файлы рассматриваются как неструктурированный поток (последовательность) байтов (т.е. никакой логической структуры не предполагается). Физически поток представляет файл или устройство (клавиатура, дисплей, принтер), снабженный средствами буферизации.
Буферизация. Потоковый ввод-вывод позволяет обрабатывать данные различных размеров и форматов, обеспечивая при этом буферизированный ввод и вывод. Таким образом, поток – это файл снабженный средствами буферизации. Буферы операционной системы реализуются в виде участков основной памяти фиксированного размера (чаще всего 512 и 1024 байта), который определен как константа стандартной библиотеки BUFSIZ. При чтении данных из файла в буфер поступает блок данных, равный размеру буфера (независимо от количества затребованной программой информации). Затем эти данные побайтно или определенными порциями передаются программе пользователя, а обращение к диску уже не происходит. Лишь когда буфер будет опустошен, произойдет чтение с диска нового блока данных. При выводе данных в файл они накапливаются в буфере, а при заполнении буфера записываются в виде единого блока на диск, за одно обращение к диску. Благодаря использованию системы буферизации уменьшается влияние механической составляющей на скорость обработки данных. Стандартная библиотека Для работы с файлами в языке С необходимо использовать заголовочный файл стандартной библиотеки, который содержит определения макросов, константы и переменные, объявления функций и типов. Называется он <stdio.h>. Функции, объявленные в <stdio.h>, являются весьма популярными благодаря тому, что являясь частью Стандартной библиотеки языка С, они гарантируют работу на любой платформе, поддерживающей С. В заголовочном файле <stdio.h> определен весьма важный тип данных – структура FILE.
/* Definition of the control structure for streams */ typedef struct { short level; /* fill/empty level of buffer */ unsigned flags; /* File status flags */ char fd; /* File descriptor */ unsigned char hold; /* Ungetc char if no buffer */ short bsize; /* Buffer size */ unsigned char _FAR *buffer; /* Data transfer buffer */ unsigned char _FAR *curp; /* Current active pointer */ unsigned istemp; /* Temporary file indicator */ short token; /* Used for validity checking */ } FILE; /* This is the FILE object */
Эта структура описывает сущность, с которой ассоциируется любой поток, используемый для ввода-вывода. Она содержит дескриптор файла, указатель текущей позиции в файле, индикатор конца файла, индикатор ошибок, указатель на буфер потока и его размер. Прежде чем начать работать с потоком, его следует открыть. Когда поток открывается для ввода-вывода, он связывается со структурой FILE. Замечание. Указатель текущей позиции в файле (текущий указатель файла) определяет то место в файле, откуда начинается чтение или запись потока.
Существует несколько предопределенных указателей на потоки, которые автоматически инициализируются при запуске программы. Это: · stdin – указатель на FILE, указывающий на стандартный поток ввода (обычно клавиатура) · stdout – указатель на FILE, указывающий на стандартный поток вывода (обычно дисплей терминала) · stderr – указатель на FILE, указывающий на стандартный поток ошибок (обычно дисплей терминала) Также определены еще два специализированных потока, это stdprn и stdaux, для работы с принтером и стандартным последовательным портом. Эти потоки употребляются реже.
Константы В заголовочном файле <stdio.h> определен ряд констант, некоторые из них представлены ниже.
#define NULL 0 макрос, расширяющий константу нулевого указателя; то есть, константу, представляющую значение указателя, гарантированно указывающего не существующий адрес объекта в памяти.
#define EOF (-1) /* End of file indicator */ отрицательное целое число типа int, используемое для обозначения конца файла.
#define BUFSIZ 512 /* Buffer size for stdio */ целое число, равное размеру буфера, используемое функцией setbuf()
#define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_SET 0 целые числа, которые могут быть переданы функции fseek() для запроса позиционирования относительно текущей позиции в файле либо конца или начала файла соответственно.
|
||||
Последнее изменение этой страницы: 2016-12-16; просмотров: 448; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.181.69 (0.012 с.) |