Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


ВЫПОЛНЕНИЕ ОПЕРАЦИЙ ЧТЕНИЯ И ЗАПИСИ



Все программы, представленные в данном уроке, выполняли файловые операции над символьными строками. По мере усложнения ваших программ, возможно, вам понадобится читать и писать массивы и структуры. Для этого ваши программы могут использовать функции readи write. При использовании функций read и write вы должны указать буфер данных, в который данные будут читаться или из которого они будут записываться, а также длину буфера в байтах, как показано ниже:

input_file.read(buffer, sizeof(buffer));
output_file.write(buffer, sizeof(buffer));

Например, следующая программа STRU_OUT.CPP использует функциюwrite для вывода содержимого структуры в файл EMPLOYEE.DAT:

#include < iostream.h>

#include < fstream.h>

void main(void)

{
struct employee

{
char name[64];
int age;
float salary;
} worker = { «Джон Дой», 33, 25000.0 };

ofstream emp_file(«EMPLOYEE.DAT»);
emp_file.write((char *) & worker, sizeof(employee));
}

Функция write обычно получает указатель на символьную строку. Символы (char *) представляют собой оператор приведения типов, который информирует компилятор, что вы передаете указатель на другой тип. Подобным образом следующая программа STRU_IN.CPP использует метод read для чтения из файла информации о служащем:

#include < iostream.h>

#include < fstream.h>

void main(void)

{
struct employee

{
char name [6 4];
int age;
float salary;
} worker = { «Джон Дой», 33, 25000.0 };

ifstream emp_file(«EMPLOYEE.DAT»);
emp_file.read((char *) & worker, sizeof(employee));
cout < < worker.name < < endl;
cout < < worker.age < < endl;
cout < < worker.salary < < endl;
}

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

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

1. Заголовочный файл fstream.h определяет классы ifstream иofstream, с помощью которых ваша программа может выполнять операции файлового ввода и вывода.

2. Для открытия файла на ввод или вывод вы должны объявить объект типа ifstream или ofstream, передавая конструктору этого объекта имя требуемого файла.

3. После того как ваша программа открыла файл для ввода или вывода, она может читать или писать данные, используя операторы извлечения (> > ) и вставки (< < ).

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

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

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

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

8. Если вашим программам необходимо вводить или выводить такие данные, как структуры или массивы, они могут использовать методы read и write.

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

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

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

ВСТРОЕННЫЕ ФУНКЦИИ

Когда вы определяете в своей программе функцию, компилятор C++ переводит код функции в машинный язык, сохраняя только одну копию инструкций функции внутри вашей программы. Каждый раз, когда ваша программа вызывает функцию, компилятор C++ помещает в программу специальные инструкции, которые заносят параметры функции в стек и затем выполняют переход к инструкциям этой функции. Когда операторы функции завершаются, выполнение программы продолжается с первого оператора, который следует за вызовом функции. Помещение аргументов в стек и переход в функцию и из нее вносит издержки, из-за которых ваша программа выполняется немного медленнее, чем если бы она размещала те же операторы прямо внутри программы при каждой ссылке на функцию. Например, предположим, что следующая программа CALLBEEP.CPP вызывает функцию show_message, которая указанное число раз выдает сигнал на динамик компьютера и затем выводит сообщение на дисплей:

#include < iostream.b>

void show_message(int count, char *message)

{
int i;
for (i = 0; i < count; i++) cout < < ‘\a’;
cout < < message < < endl;
}

void main(void)

{
show_message(3, «Учимся программировать на языке C++»);
show_mes sage(2, «Урок 35″ );
}

Следующая программа NO_CALL.CPP не вызывает функциюshow_message.Вместо этого она помещает внутри себя те же операторы функции при каждой ссылке на функцию:

#include < iostream.h>

void main (void)

{
int i;
for (i = 0; i < 3; i++) cout < < ‘\a’;
cout < < » Учимся программировать на языке C++» < < endl;
for (i = 0; i < 2; i++) cout < < ‘\a’;
cout < < «Урок 35″ < < endl;
}

Обе программы выполняют одно и то же. Поскольку программа NO_CALL не вызывает функцию show_message, она выполняется немного быстрее, чем программа CALLBEEP. В данном случае разницу во времени выполнения определить невозможно, но, если в обычной ситуации функция будет вызываться 1000 раз, вы, вероятно, заметите небольшое увеличение производительности. Однако программа NO_CALL более запутана, чем ее двойник CALL_BEEP, следовательно, более тяжела для восприятия.

При создании программ вы всегда должны попытаться определить, когда лучше использовать обычные функции, а когда лучше воспользоваться встроенными функциями. Для более простых программ предпочтительно использовать обычные функции. Однако, если вы создаете программу, для которой производительность имеет первостепенное значение, вам следовало бы уменьшить количество вызовов функций. Один из способов уменьшения количества вызовов функций состоит в том, чтобы поместить соответствующие операторы прямо в программу, как только что было сделано в программе NO_CALL. Однако, как вы могли убедиться, замена только одной функции внесла значительную путаницу в программу. К счастью, C++ предоставляет ключевое слово inline, которое обеспечивает лучший способ.

Использование ключевого слова inline

При объявлении функции внутри программы C++ позволяет вам предварить имя функции ключевым словомinline.Если компилятор C++ встречает ключевое слово inline, он помещает в выполнимый файл (машинный язык) операторы этой функции в месте каждого ее вызова. Таким образом, можно улучшить читаемость ваших программ на C++, используя функции, и в то же время увеличить производительность, избегая издержек на вызов функций. Следующая программа INLINE.CPP определяет функции тахи minкак inline:

#include < iostream.h>

inline int max(int a, int b)

{
if (a > b) return(a);
else return(b);
}

inline int min(int a, int b)

{
if (a < b) return(a);
else return(b);
}

void main(void)

{
cout < < «Минимум из 1001 и 2002 равен » < < min(1001, 2002) < < endl;
cout < < «Максимум из 1001 и 2002 равен » < < max(1001, 2002) < < endl;
}

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

О встроенных функциях

Если компилятор C++ перед определением функции встречает ключевое слово inline, он будет заменять обращения к этой функции (вызовы) на последовательность операторов, эквивалентную выполнению функции. Таким образом ваши программы улучшают производительность, избавляясь от издержек на вызов функции и в то же время выигрывая в стиле программы, благодаря использованию функций.

ВСТРОЕННЫЕ ФУНКЦИИ И КЛАССЫ

Как вы уже знаете, при определении класса вы определяете функции этого класса внутри или вне класса. Например, класс employeeопределяет свои функции внутри самого класса:

class employee

{
public:
employee(char *name, char *position, float salary)

{
strcpy(employee:: name, name);
strcpy(employee:: position, position);
employee:: salary = salary;
}

void show_employee(void)

{
cout < < «Имя: » < < name < < endl;
cout < < «Должность: » < < position < < endl;
cout < < «Оклад: $» < < salary < < endl;
}

private:
char name [64];
char position[64];
float salary;
};

Размещая подобным образом функции внутри класса, вы тем самым объявляете их встроенными {inline).Если вы создаете встроенные функции класса этим способом, C++ дублирует функцию для каждого создаваемого объекта этого класса, помещая встроенный код при каждой ссылке на метод (функцию) класса. Преимущество такого встроенного кода состоит в увеличении производительности. Недостатком является очень быстрое увеличение объема самого определения класса. Кроме того, включение кода функции в определение класса может существенно запугать класс, делая его элементы трудными для восприятия.

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

inline void employee:: show_employee(void)

{
cout < < «Имя: » < < name < < endl;
cout < < «Должность: » < < position < < endl;
cout < < «Оклад: $» < < salary < < endl;
}


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-05-30; Просмотров: 619; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.02 с.)
Главная | Случайная страница | Обратная связь