Лекции.ИНФО


Int main() // Эта строка сейчас имеет номер 200.



{// Номер этой строки равен 201.

 cout << _ _LINE_ _;// Здесь выводится номер 202.

 return 0;

}

Директива #pragma

Директива #pragma зависит от конкретной реализации компилятора.

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

#pragma имя

Здесь элемент имя представляет имя желаемой #pragma-инструкции. Если указанное имя не распознается компилятором, директива #pragma попросту игнорируется без сообщения об ошибке.

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

Операторы препроцессора "#" и "##"

В C++ предусмотрена поддержка двух операторов препроцессора: "#" и "##". Эти операторы используются совместно с директивой #define. Оператор "#" преобразует следующий за ним аргумент в строку, заключенную в кавычки. Рассмотрим, например, следующую программу.

#include <iostream>

using namespace std;

#define mkstr(s) # s

Int main()

{

 cout << mkstr(Я в восторге от C++);

 return 0;

}

Препроцессор C++ преобразует строку

cout << mkstr(Я в восторге от C++);

В строку

cout << "Я в восторге от C++";

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

#include <iostream>

using namespace std;

#define concat(a, b) a ## b

Int main()

{

 int xy = 10;

 cout << concat(x, y);

 return 0;

}

Препроцессор преобразует строку

cout << concat (x, y);

В строку

cout << xy;

Если эти операторы вам кажутся странными, помните, что они не являются операторами "повседневного спроса" и редко используются в программах. Их основное назначение — позволить препроцессору обрабатывать некоторые специальные ситуации.

Зарезервированные макроимена

В языке C++ определено шесть встроенных макроимен.

_ _LINE_ _

_ _FILE_ _

_ _DATE_ _

_ _TIME_ _

_ _STDC_ _

_ _cplusplus

Рассмотрим каждое из них в отдельности.

Макросы _ _LINE_ _ и _ _FILE_ _ описаны при рассмотрении директивы #line выше в этой главе. Они содержат номер текущей строки и имя файла компилируемой программы.

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

Время трансляции исходного файла в объектный код содержится в виде строки в макросе _ _TIME_ _. Формат этой строки следующий: часы.минуты.секунды.

Точное назначение макроса _ _STDC_ _ зависит от конкретной реализации компилятора. Как правило, если макрос _ _STDC_ _ определен, то компилятор примет только стандартный С/С++-код, который не содержит никаких нестандартных расширений.

Компилятор, соответствующий ANSI/ISO-стандарту C++, определяет макрос _ _cplusplus как значение, содержащее по крайней мере шесть цифр. "Нестандартные" компиляторы должны использовать значение, содержащее пять (или даже меньше) цифр.

Мысли "под занавес"

Мы преодолели немалый путь: длиной в целую книгу. Если вы внимательно изучили все приведенные здесь примеры, то можете смело назвать себя программистом на C++. Подобно многим другим наукам, программирование лучше всего осваивать на практике, поэтому теперь вам нужно писать побольше программ. Полезно также разобраться в С++-программах, написанных другими (причем разными) профессиональными программистами. При этом важно обращать внимание на то, как программа оформлена и реализована. Постарайтесь найти в них как достоинства, так и недостатки. Это расширит диапазон ваших представлений о программировании. Подумайте также над тем, как можно улучшить существующий код, применив контейнеры и алгоритмы библиотеки STL. Эти средства, как правило, позволяют улучшить читабельность и поддержку больших программ. Наконец, просто больше экспериментируйте! Дайте волю своей фантазии и вскоре вы почувствуете себя настоящим С++-программистом!

Для продолжения теоретического освоения C++ предлагаю обратиться к моей книге Полный справочник по C++, М. : Издательский дом "Вильямс". Она содержит подробное описание элементов языка C++ и библиотек.


Приложение А: С-ориентированная система ввода-вывода

Это приложение содержит краткое описание С-системы ввода-вывода. Несмотря на то что вы предполагаете использовать С++-систему ввода-вывода, есть ряд причин, по которым вам все-таки следует понимать основы С-ориентированной системы ввода-вывода. Во-первых, если вам придется работать с С-кодом (особенно, если возникнет необходимость его перевода в С++-код), то вам нужно знать, как работает С-система ввода-вывода. Во-вторых, часто в одной и той же программе используются как С-, так и С++-операции ввода-вывода. Это особенно характерно для очень больших программ, отдельные части которых писались разными программистами в течение довольно длительного периода времени. В-третьих, большое количество существующих С-программ продолжают находиться в эксплуатации и нуждаются в поддержке. Наконец, многие книги и периодические издания содержат программы, написанные на С. Чтобы понимать эти С-программы, необходимо понимать основы функционирования С-системы ввода-вывода.

Узелок на память. Для С++-программ необходимо использовать объектно-ориентированную С++-систему ввода-вывода.

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

Система ввода-вывода языка С требует включать в программы заголовочный файл stdio.h (ему соответствует заголовок <cstdio>, отвечающий новому стилю). Каждая С-программа должна использовать заголовочный файл stdio.h, поскольку язык С не поддерживает С++-стиль включения заголовков. С++-программа может работать с использованием любого из этих двух вариантов. Заголовок <cstdio> помещает свое содержимое в пространство имен std, а заголовочный файл stdio.h— в глобальное пространство имен, что соответствует С-ориентации. В этом приложении в качестве примеров приведены С-программы, поэтому они используют С-стиль включения заголовочного файла stdio.h и не требуют установки пространства имен.

И еще. Как отмечалось в главе 1, стандарт языка С был обновлен в 1999 году и получил название стандарта С99. В то время в С-систему ввода-вывода было внесено несколько усовершенствований. Но поскольку C++ опирается на стандарт С89, то он не поддерживает средств, которые были добавлены в стандарт С99. (Более того, на момент написания этой книги ни один из широко доступных компиляторов C++ не поддерживал стандарт С99. Да и ни одна из широко распространяемых программ не использовала средства стандарта С99.) Поэтому здесь не описываются средства, внесенные в С-систему ввода-вывода стандартом С99. Если же вас интересует язык С, включая полное описание его системы ввода-вывода и средств, добавленных стандартом С99, я рекомендую обратиться к моей книге Полный справочник по С, М.: Издательский дом "Вильямс".

Использование потоков в С-системе ввода-вывода

Подобно С++-системе ввода-вывода, С-ориентированная система ввода-вывода опирается на понятие потока. В начале работы программы автоматически открываются три заранее определенных текстовых потока: stdin, stdout и stderr. Их называют стандартными потоками ввода данных (входной поток), вывода данных (выходной поток) и ошибок соответственно. (Некоторые компиляторы открывают также и другие потоки, которые зависят от конкретной реализации системы.) Эти потоки представляют собой С-версии потоков cin, cout и cerr соответственно. По умолчанию они связаны с соответствующим системным устройством.

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

Каждый поток, связанный с файлом, имеет структуру управления файлом типа FILE. Эта структура определена в заголовочном файле stdio.h. Вы не должны модифицировать содержимое этого блока управления файлом.

Функции printf() и scanf()

Двумя самыми популярными С-функциями ввода-вывода являются printf() и scanf(). Функция printf() записывает данные в стандартное устройство вывода (консоль), а функция scanf(), ее дополнение, считывает данные с клавиатуры. Поскольку язык С не поддерживает перегрузку операторов и не использует операторы "<<" и ">>" в качестве операторов ввода-вывода, то для консольного ввода-вывода используются именно функции printf() и scanf(). Обе они могут обрабатывать данные любых встроенных типов, включая символы, строки и числа. Но поскольку эти функции не являются объектно-ориентированными, их нельзя использовать непосредственно для ввода-вывода объектов классов, создаваемых программистом.

Функция printf()

Функция printf() имеет такой прототип:

int printf(const char *fmt_string, ...);

Первый аргумент, fmt_string, определяет способ отображения всех последующих аргументов. Этот аргумент часто называют строкой форматирования. Она состоит из элементов двух типов: текста и спецификаторов формата. К элементам первого типа относятся символы (текст), которые выводятся на экран. Элементы второго типа (спецификаторы формата) содержат команды форматирования, которые определяют способ отображения аргументов. Команда форматирования начинается с символа процента, за которым следует код формата. Спецификаторы формата перечислены в табл. А.1. Количество аргументов должно в точности совпадать с количеством команд форматирования, причем совпадение обязательно и в порядке их следования. Например, при вызове следующей функции printf().

printf ("Привет %с %d %s", 'с', 10, "всем!");

На экране будет отображено: "Привет с 10 всем! ".

Функция printf() возвращает число реально выведенных символов. Отрицательное значение возврата свидетельствует об ошибке.

Команды формата могут иметь модификаторы, которые задают ширину поля, точность (количество десятичных разрядов) и признак выравнивания по левому краю. Целое значение, расположенное между знаком % и командой форматирования, выполняет роль спецификатора минимальной ширины поля. Наличие этого спецификатора приведет к тому, что результат будет заполнен пробелами или нулями, чтобы гарантированно обеспечить для выводимого значения заданную минимальную длину. Если выводимое значение (строка или число) больше этого минимума, оно будет выведено полностью, несмотря на превышение минимума. По умолчанию в качестве заполнителя используется пробел. Для заполнения нулями нужно поместить 0 перед спецификатором ширины поля. Например, строка форматирования %05d дополнит выводимое число нулями (их будет меньше пяти), чтобы общая длина была равной пяти символам.

Точное значение модификатора точности зависит от кода формата, к которому он применяется. Чтобы добавить модификатор точности, поставьте за спецификатором ширины поля десятичную точку, а после нее — значение спецификации точности. Для форматов а, А, е, Е, f и F модификатор точности определяет число выводимых десятичных знаков. Например, строка форматирования %10.4f обеспечит вывод числа, ширина которого составит не меньше десяти символов, с четырьмя десятичными знаками. Применительно к целым или строкам, число, следующее за точкой, задает максимальную длину поля. Например, строка форматирования %5.7s отобразит строку длиной не менее пяти, но не более семи символов. Если выводимая строка окажется длиннее максимальной длины поля, конечные символы будут отсечены.

По умолчанию все выводимые значения выравниваются по правому краю: если ширина поля больше выводимого значения, оно будет выровнено по правому краю поля. Чтобы установить выравнивание по левому краю, поставьте знак "минус" сразу после знака %. Например, строка форматирования %-10.2f обеспечит выравнивание вещественного числа (с двумя десятичными знаками в 10-символьном поле) по левому краю. Рассмотрим программу, в которой демонстрируется использование спецификаторов ширины поля и выравнивания по левому краю.

#include <stdio.h>

Int main()

{

 printf("|%11.6f|", 123.23);

 printf ("|%-11.6f|", 123.23);

 printf("|%11.6s |", "Привет всем");

 printf("|%-11.6s |", "Привет всем");

 return 0;

}









Читайте также:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 93;


lektsia.info 2017 год. Все права принадлежат их авторам! Главная