Директивы препроцессора #include и #define 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Директивы препроцессора #include и #define



Конспект лекций

 

Часть 1

 

 

Омск 2007 г.


ПРЕДИСЛОВИЕ

 

Язык программирования С++ был разработан на основе языка С Бьярном Страуструпом (Bjarne Stroustrup) и вышел за пределы его исследовательской группы в начале 80-х годов. Язык С++ является надмножеством языка Си, поэтому программы, написанные на языке Си могут обрабатываться компилятором языка С++. В программах на языке С++ можно использовать тексты на языке С и обращаться к библиотечным функциям языка Си. Язык С++ был создан с учетом следующих целей: улучшить язык Си, поддержать абстракцию данных и обеспечить объектно-ориентированное программирование.

Через несколько лет практического использования языка С++ стандартом языка де-факто стала спецификация языка АТ&Т С++ release 2.0, разработанная под руководством автора языка Б. Страуструпом в Bell Laboratories фирмы AT&T. Затем там же появилась усовершенствованная версия 3.0 языка С++. В настоящее время в Американском Национальном Институте Стандартов (ANSI) существует комитет по языку С++ (X3J16). Изданное в 1990 году описание языка с комментариями принято комитетом ANSI в качестве исходного материала для стандартизации С++. Последняя версия стандарта (но не окончательная) датирована 26 мая 1994г.

Весьма полная реализация соглашений по языку С++ выполнена в широко распространённых компиляторах Turbo C и Borland C++ фирмы Borland International. Turbo C и Borland C++ поддерживают стандарты языков соответственно Си и С++, разработанные ANSI, но содержат и ряд дополнительных языковых средств и библиотечных функций.

Большинство пользователей осваивают Borland C++ для того, чтобы пользоваться преимуществами объектно-ориентированных средств языка С++.

В настоящее время широкое распространение получила интегрированная среда программирования Borland C++, поддерживающая объектно-ориентированный язык программирования С++. Мы будем использовать версию 3.1.

 

 

1. ВВЕДЕНИЕ В С++

 

1.1. Интегрированная среда программирования Borland C++

 

Системы программирования на языке С++ – Borland C++ включают в себя:

интегрированную среду программирования (Integrated Development Environment - IDE), называемую далее просто IDE или интегрированной средой;

компилятор исходного текста программы;

редактор связей (компоновщик);

библиотеки заголовочных файлов;

библиотеки функций;

программы-утилиты.

Интегрированная среда (IDE) – это программа, имеющая встроенный редактор текстов, подсистему работы с файлами, систему помощи (далее Help-система или просто Help), встроенный отладчик, подсистему управления компиляцией и редактированием связей, а также компилятор и редактор связей. Другими словами, IDE даёт возможность получить.EXE-файл, не используя другие программы. Borland C++ имеет два варианта IDE: BC.EXE для работы в реальном режиме; BCX.EXE для работы в защищённом режиме.

Кроме встроенного в интегрированную среду компилятора, Borland C++ имеет ещё один компилятор, называемый компилятором командной строки (файл BCC.EXE). Компилятор командной строки – это полный компилятор, поддерживающий все возможности системы программирования. Компилятор командной строки по умолчанию после завершения компиляции автоматически вызывает редактор связей. Редактор связей имеет имя файла TLINK.EXE. В настоящий момент редактор связей TLINK.EXE практически полностью совместим с редактором связей LINK.EXE фирмы Microsoft.

Среди характерных особенностей интегрированной среды Borland C++ можно выделить мощную оконную систему с возможностью передвижения и изменения размера окон, поддержку манипулятора “мышь”, многооконный текстовый редактор, окна диалогов, различные меню.

Прежде чем начать работу в IDE, следует проверить и при необходимости выставить нужные опции.

Меню Options включает команды Compiler, Transfer…, Make…, Linker…, Application…, Debugger…, Directories… Все опции имеют значение по умолчанию, ”впечатанные” в программу интегрированной среды и изменяемые с помощью программы настройки IDE.

Для того, чтобы работать в IDE, прежде всего, требуется задать директории, используемые текстовым редактором, компилятором и компоновщиком. Для этого используется команда Directories.

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

Работа IDE Borland C++ с файлами проектов удобна и проста. Все необходимые для этого команды (Open project…, Close project.., Add item…, Delete item, Local option…, Include files…) включены в меню Project.

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

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

Встроенный отладчик IDE позволяет:

1)выполнить программу по шагам;

2)выполнить программу до заданной строки, называемой точкой останова;

3)проследить изменения заданных переменных программы и при необходимости установить для них новые значения.

В ходе отладки программы можно сразу вносить изменения в ее текст. После каждого изменения отладчик запрашивает подтверждение на продолжение сеанса отладки или предлагает повторную компиляцию программы.

Возможностей встроенного отладчика IDE, в большинстве случаев достаточно для поиска и устранения практически всех типов смысловых ошибок. Но существует несколько случаев, когда необходимо использовать внешний турбо – отладчик TD.EXE.

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

Borland C++ включает богатейшие библиотеки функций для управления файлами, выполнения ввода-вывода и многих других действий. Подавляющее большинство этих функций следует ANSI-стандарту языка Си, т.е. полностью совместимыми по типу параметров и возвращаемым значениям с другими системами программирования на Си, в частности Microsoft C. Прототипы, символические константы и другие макро, связанные с библиотечными функциями, объединяют в заголовочные файлы, которые по традиции имеют расширение имени файла.h.

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

К программам-утилитам относят ассемблер (TASM.EXE), совместимый в настоящий момент с макроассемблером фирмы Microsoft, препроцессор (CPP.EXE), отладчик (TD.EXE) и связанные с ним файлы (драйверы, программы удаленной отладки и т.п.), программу профилирования (TPROF.EXE) и связанные с ней файлы, программу формирования объектных библиотек (TLIB.EXE) и многие другие полезные программы.

 

1.2. Структура программы на языке С++

 

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

Пример:

extern double sqrt (double);

extern istream cin;

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

Пример:

Если описание sqrt хранится в заголовочном файле для стандартных математических функций math.h, и нужно извлечь квадратный корень из числа 4, можно написать:

#include <math.h>

//…….

x=sqrt (4);

Рассмотрим структуру программы в С++ на примере:

//Prim1_1.cpp

// HELLO. CPP -имя файла с программой.

# include < iostream. h >

void main ()

{

cout << "\nHELLO, WORLD!\n";

}

В первой строке программы – однострочный комментарий, начинающийся парой символ ‘//‘, заканчивающийся неизображаемым символом “конец строки”. Между этими разделителями может быть помещен произвольный текст. Комментарии объясняют, что происходит в программе. Комментарии используются для того, чтобы описать назначение раздела кода, объяснить предложение или разъяснить тот или иной специфический ход. Они облегчают чтение программы. Строки комментариев игнорируются компилятором; он просто пропускает их, преобразуя программу на С++ в машинный код.

Во второй строке помещена команда (директива) препроцессора, обеспечивающая включение в программу средств связи со стандартными потоками ввода и вывода данных. Указанные средства находятся в файле с именем iostream.h (мнемоника:”i”(input) –ввод; “o”(output) –вывод; stream –поток; “h”(head) – заголовок). Стандартным потоком вывода по умолчанию считается вывод на экран дисплея.

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

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

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

Третья строка является заголовком функции с именем main. Любая программа на языке С++ должна включать одну и только одну функцию с этим именем. Именно с нее начинается выполнение программы. Перед именем main помещено служебное слово void - спецификатор типа, указывающий, что функция main в данной программе не возвращает никакого значения. Круглые скобки после main требуются в соответствии с форматом (синтаксисом) заголовка любой функции. В них помещается список параметров. В данной программе параметры не нужны и список пуст.

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

cout << "\ n HELLO, WORLD!\n";

Все программы на С++ должны начинаться с функции, называемой main().

Структура программы:

 

main() Функция, означающая начало

{ программы - точку входа

...; здесь начинается функция

...;

...;

}

Пример:

//Prim1_2.cpp

#include <stdio.h>

main()

{

puts(“У меня все в порядке”);

puts(“А у тебя”);

return(0);

}

В примере использована функция вывода строки puts.

 

Алфавит языка

 

В алфавит языка С++ входят:

прописные и строчные буквы латинского алфавита;

цифры 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;

специальные знаки:

“ { }, | [ ] () + - / % \; ‘: < == > _! & # ~. * ^? =

Из символов алфавита формируются лексемы языка:

идентификаторы;

ключевые (служебные, иначе зарезервированные) слова;

константы;

знаки операций;

разделители (знаки пунктуации).

Лексема – это одна из смысловых единиц (имен, констант, зарезервированных слов и т.д.) во входном тексте для компилятора. Лексический анализатор разделяет входной текст, представляемый в виде потока знаков, на группы лексем.

 


Имена

 

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

Примеры имен:

Hello this_is_a_most_unusually_long_name

DEFINED foO bAr u_name

var0 var1 CLASS

Примеры последовательностей символов, которые не могут использоваться как идентификаторы:

012 $sys class 3var

pay.due foo~bar.name if

Буквы в верхнем и нижнем регистрах считаются различными, поэтому Count и count – различные имена, но вводить имена, лишь незначительно отличающихся друг от друга, нежелательно.

 

Переменные и константы

 

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

Понятие «тип» - одно из фундаментальных для любого языка программирования. В С++ все типы разбиваются на 4 категории: «пустой» тип (void); скалярный тип; тип «функция»; агрегированный тип (агрегат).

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

Кроме того, типы могут быть разделены на основные (фундаментальные) и производные (derived). К основным типам относят void, char, int, float, и double вместе с вариантами short, long, signed и unsigned, применимыми к некоторым из них.

В С++ есть набор основных типов, которые соответствуют наиболее общим основным единицам памяти компьютера и наиболее общим основным способам их использования:

char, short int, int, long int для представления целых различных размеров;

float, double для представления чисел с плавающей точкой;

unsigned char, unsigned short int, unsigned int, unsigned long int для представления беззнаковых целых, логических значений, битовых массивов и т.п.

Производные типы - это указатели и ссылки на другие типы, массивы, функции, классы, структуры и объединения.

 

Данные типа int

 

Тип «целое» (integer) включает данные типа char, short, int И long вместе с их вариантами signed и unsigned. Данные типа int (переменные и константы) могут быть в одной из следующих возможных форм, указанных в табл.1.

 

Таблица 1

Данные типа int для компилятора Borland C++ 3.1

 

Тип Размер, Бит Диапазон представления чисел
    Минимум Максимум
Unsigned int Short int Int Long Unsigned long   -32 768 -32 768 -2 147 483 648 65 535 32 767 32 767 2 147 483 647 4 294 967 295  

 

Как следует из таблицы, short int и int являются синонимами. Синонимами являются типы unsigned int и unsigned.

Язык С++ поддерживает IEEE – стандарт внутреннего представления данных типа int (рис.1).

 

Int S Значение числа
    14 0

 

unsigned int Значение числа
  15 0

 

long int S Значение числа
    30 0

 

long unsigned Значение числа
  31 0

 

S - знаковый разряд числа

 

Рис.1. IEEE - стандарт внутреннего представления данных типа int

 

В компьютере с 16-ти разрядным процессором данные типа int занимают 2-а байта памяти (машинное слово), данные типа long занимают 4-ре байта. Старший бит знаковых типов int, short int, long int хранит знак числа. Если он равен нулю, число положительное, если он равен единице – число отрицательное. Положительные числа хранятся в памяти и вступают в операции в прямом коде, т.е. в обычном двоичном представлении числа. Отрицательные числа хранятся в памяти компьютера в дополнительном коде. Приведем правило получения дополнительного кода:

модуль отрицательного числа записывается в прямом коде в битах 14-0 или 30-0 «прижатым» вправо. В неиспользуемые старшие биты записываются нули;

в знаковый разряд бит 15 или 31 записывается 1;

формируется обратный код битов 14-0 или 30-0; для этого нуль заменяется единицей, а единица нулем;

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

Например, обратный код числа –33 в формате int:

 

  14 0  
  000.0000.0010.0001 Прямой код
  111.1111.1101.1110 Обратный код
+    
  111.1111.1101.1111 Дополнительный код FFDEh

 

Константы типа int могут задаваться в десятичной, восьмеричной и шестнадцатеричной системой счисления. Признаком константы в шестнадцатеричной системе счисления являются 0х (0Х) в качестве первых ее символов. Запись такой константы может содержать цифры от 0 до 9, а также символы шестнадцатеричных цифр A-F. Любая константа, начинающаяся с нуля, рассматривается компилятором как заданная в восьмеричной системе счисления.

Если в записи константы встречается суффикс L (l), компилятор интерпретирует константу как long. Суффикс U(u) явно указывает на константу типа unsigned. Разрешается комбинировать оба суффикса в любом порядке, например 976LU.

При отсутствии суффиксов L(l) или U(u) точный тип константы определяется по ее записи (табл.2). Отрицательные константы получаются применением операции «унарный минус» к соответствующей положительной константе.

Переменная типа int объявляется с использованием ключевых слов unsigned, int, short, long. Синонимами будут сочетания ключевых слов: signed int и int; unsigned int и unsigned; short, sort int и signed short int; unsigned short и unsigned short int; long, long int и signed long int; unsigned long и unsigned long int.

При описании переменной ей может быть задано начальное значение. Например:

int i=0xabcd, j=04567, k=1;

Таблица 2

Целые константы и их тип при отсутствии суффиксов для компилятора

Borland C++ 3.1

 

Записанное значение константы Тип, принимаемый компилятором
Десятичные константы: От 0 до 32 767 От 32 768 до 2 147 483 647 От 2 147 483 648 до 4 294 967 295 > 4 294 967 295     Int Long Unsigned long Генерируется ошибка
Восьмеричные константы: От 00 до 077777 От 0100000 до 0177777 От 02000000 до 017777777777 От 020000000000 до 037777777777 > 037777777777   Int Unsigned int Long Unsigned long Генерируется ошибка
Шестнадцатиричные константы: От 0x0000 до 0x7FFF От 0x8000 до 0xFFFF От 0x10000 до 0x7FFFFFFF От 0x80000000 до 0xFFFFFFFF > 0xFFFFFFFF   Int Unsigned int Long Unsigned long Генерируется ошибка

 

Если в описании опущен тип, он предполагается int. Например:

const a = 1;

static x;

все определяют объект типа int.

 

Данные типа char

 

Данные типа char занимают в памяти 1 байт. Код от 0 до 255 в этом байте задает один из 256 возможных символов. Закрепление конкретных символов за кодами задается так называемыми кодовыми таблицами. Для персональных компьютеров наиболее распространена ASCII-таблица.

Тип char является типом «целое». Данные типа char могут рассматриваться компилятором и как данные со знаком (signed char), и как данные без знака (unsigned char).

Если тип char рассматривается как signed, то старший бит его кода определяет знак. В случае unsigned char все восемь бит рассматриваются как код, а диапазон возможных значений от 0 до 255.

Константа типа char представляет собой символ заключенный в одиночные кавычки, например ‘A’, ‘$’. Внутренний код байта, соответствующего константе, определяется по кодовой таблице.

Представление группы символьных констант описаны ниже в параграфе 2.5.3.

Переменная типа char занимает 1 байт памяти и описывается с использованием ключевого слова char. При описании переменной ей можно задать начальное значение. Например:

char symbol=’\0100’; /* прописная латинская P */

char name=’0’, first=’\n’;

 

Данные с плавающей точкой

 

Язык Borland C++ поддерживает операции с плавающей точкой. Особенностью персональных компьютеров IBM PC является отсутствие в системе команд микропроцессора Intel, на базе которых они построены, операций над числами с плавающей точкой. Такие арифметические операции выполняет либо специальный сопроцессор математики с плавающей точкой (сопроцессоры 8087/80287/80387), либо при его отсутствии специальные стандартные подпрограммы (программная эмуляция сопроцессора).

Компилятор использует три формы внутреннего представления данных с плавающей точкой (табл.3).

 

Таблица 3

Данные с плавающей точкой для компилятора Borland C++ 3.1

 

  Тип Размер, бит Диапазон представления чисел(abs) Точность (десятичных цифр)
    Максимум минимум  
Float Double Long double   3.4*10-38 1.7*10-308 3.4*10-4932 3.4*1038 1.7*10308 3.4*104932 19

Borland C++ поддерживает IEEE-стандарт, в соответствии с которым такие данные представляются в виде двух частей – мантиссы М и порядка Р числа в двоичной системе счисления:

С = М * 2Р

Число бит для хранения мантиссы и порядка зависит от типа данных с плавающей точкой (рис. 2).

 

 

float: S P M  
    30 23 22 0  
double: S P M  
    62 52 51 0  
long double: S P M
    78 64 63 0
               

 

 

S – знак числа (0 – для положительных, 1 – для отрицательных);

Р – сдвинутый порядок числа;

М – мантисса числа.

 

Рис. 2. IЕЕЕ-стандарт внутреннего представления данных с плавающей точкой.

 

Вещественное число в памяти хранится с нормализованной мантиссой. При нарушении нормализации мантиссу сдвигают влево до тех пор, пока старшей цифрой мантиссы не станет 1. Каждая операция сдвига сопровождается уменьшением порядка на 1. Но если мантисса всегда нормализована, то старшую едини­цу можно и не хранить в памяти. Это экономит один бит и, следовательно, увеличивает точность представления веществен­ных чисел. Эта единица присутствует неявно и называется неяв­ной единицей (implicit one). Отбрасывание старшей цифры мантиссы выполняется для форматов float и double, но не выполня­ется для long double.

Порядок числа хранится "сдвинутым", т. е. к нему при­бавляется число так, чтобы порядок был всегда неотрицатель­ным. Для чисел формата float прибавляется 127, для чисел формата double - 1023, для чисел формата long double -16383. Всегда неотрицательный порядок избавляет от необходимости выделять один бит для хранения знака порядка и упрощает выполнение операций сравнения порядков и арифметических операций над ними.

Например, число 15.375 (1111.011 в двоичной системе счисления) в формате float IEEE-стандарта записывается так:

1.111011*211.

Учитывая отбрасывание неявной единицы и сдвиг порядка, получаем внутреннее представление числа:

S = 0;

Р = 3+127 = 130(1000.0010 в двоичной системе счисления);

М = 1110110...0.

Переменные с плавающей точкой описываются с использованием спецификаторов типа float, double, long double.

Причина того, что представляется более чем один целый тип, более чем один беззнаковый тип и более чем один тип с плавающей точкой в том, чтобы дать возможность программисту воспользоваться характерными особенностями аппаратного обеспечения. На многих машинах между различными разновидностями основных типов существуют значительные различия в потребностях в памяти, временах доступа к памяти и временах вычислений. Размеры типов не указаны в стандарте языка а зависят от операционной системы, компилятора и разрядности процессора. В компьютерах с 16-ти разрядными процессорами int – 2 байта, в компьютерах с 32-х разрядными процессорами – 4 байта и т.д. В стандарте языка С++ указаны следующие соотношения относительно размеров основных типов:

I = = sizeof (char) < = sizeof(short) < = sizeof(int) < = sizeof(long)

sizeof (float) < = sizeof(double)

Однако обычно разумно предполагать, что в char могут храниться целые числа в диапазоне 0…127, что short и int имеют не менее 16 битов, что int имеет, по меньшей мере, 24 бита.

Беззнаковые (unsigned) целые типы идеально подходят для применений, в которых память рассматривается как массив битов.

 

Константы

 

С++ дает возможность записи значений основных типов: символьных констант, целых констант и констант с плавающей точкой. Кроме того, нуль (0) может использоваться как константа любого указательного типа, и символьные строки являются константами типа char[]. Можно также задавать символические константы. Символическая константа - это имя, значение которого не может быть изменено в области его видимости. В С++ имеется три механизма определения символических констант: 1) любому значению любого типа можно дать имя и использовать его как константу, добавив к его описанию ключевое слово const; 2) множество целых констант может быть определено как перечисление; 3) любое имя массива или функции является константой.

 

Целые константы

 

Целые константы предстают в четырех "обличиях": десятичные, восьмеричные, шестнадцатиричные и символьные константы. Десятичные используются чаще всего и выглядят так:

0 1234 5768595974474736

Десятичная константа имеет тип int, при условии, что она "влезает" в int, в противном случае ее тип – long суффикс L или l явно указывает компилятору, что тип константы – long, например 314564L или 3254354l. Компилятор должен предупреждать о константах, которые слишком длинны для представления в машине.

Константа, начинающаяся нулем, за которым идет x (0x), является шестнадцатеричным числом, а константа, начинающаяся нулем, за которым идет цифра, является восьмеричным числом. Например:

0 02 045 09786 07564 / / восьмеричные константы

0x0 0x6 0x3f 0x56 / / шестнадцатеричные константы

 

Символьные константы

 

Хотя в С++ и нет отдельного символьного типа данных, в нем для символов имеется специальная и удобная запись. Символьная константа - это символ, заключенный в одинарные кавычки; например, 'a' или '0'. Такие символьные константы в действительности являются символическими константами для целого значения символов в наборе символов машины. Употребление символьных констант вместо десятичной записи делает программу более переносимой. Несколько символов также имеют стандартные имена, в которых обратная косая \ используется как escape - символ. Некоторые из них:

'\b' возврат назад

'\f' перевод формата

'\n'' новая строка

'\r' возврат каретки

‘\t’ табуляция

Для явного указания кода символа используется выражение ‘\nnn’, где nnn - восьмеричный код или ‘\0xhh’, где hh – шестнадцатеричный код.

 

Строки

 

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

"это строка"

Каждая строковая константа содержит на один символ больше, чем кажется; все они заканчиваются пустым символом '\0' со значением 0. Например:

sizeof ("wer") = = 5;

Строка имеет тип "вектор из соответствующего числа символов", поэтому "wer" имеет тип char[5]. Пустая строка записывается " " (и имеет тип char[1]).

В строке может стоять обратная косая, сразу после которой идет новая строка; и то, и другое будет проигнорировано:

cout << "здесь все \

ok"

напечатает:

здесь все ok

Новая строка, перед которой идет символ \ не приводит к появлению в строке новой строки, это просто договоренность записи.

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

 

Const

 

Ключевое слово const может добавляться к описанию объекта, чтобы сделать этот объект константой, а не переменной:

const int model = 232;

const int w[] = {1,2,3,4};

Поскольку константе ничего нельзя присвоить, она должна быть инициализирована. Описание чего-нибудь как const гарантирует, что его значение не изменится в области видимости:

model = 145; / / ошибка

model++; / / ошибка

Const изменяет тип, т.е. ограничивает способ использования объекта, вместо того, чтобы задавать способ размещения константы.

 

2.5.6. Стандартные преобразования типов.

 

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

операнды разных типов приводятся к "старшему", т.е. более длинному типу; ниже перечислены типы, начиная от самого старшего, в порядке убывания старшинства: самый старший - long double, double, float, unsigned long, long int, unsigned, int, char - самый младший;

при выполнении операции присваивания результат приводится к типу переменной слева от знака операции; в этом случае может возникнуть ситуация преобразования "старшего" типа к "младшему".

При преобразовании типов нужно различать преобразования, изменяющие внутреннее представление данных, и преобразования, изменяющие только интерпретацию внутреннего представления. Например, когда данные типа unsigned unt переводятся в тип int, менять их внутреннее представление не требуется - изменяется только интерпретация. При преобразовании типа float в тип int недостаточно изменить только интерпретацию, необходимо изменить длину участка памяти для внутреннего представления и кодировку. При таком преобразовании из float в int возможен выход за диапазон допустимых значений типа int, и реакция на эту ситуацию существенно от конкретной реализации. Именно поэтому для сохранения мобильности программ в них рекомендуется с осторожностью применять преобразование типов.

Рассмотрим этапы (последовательность выполнения) преобразования операндов в арифметических выражениях.

Все короткие целые типы преобразуются в типы неменьшей длины в соответствии с табл. 1. Затем оба значения, участвующие в операции, принимают тип float или int либо double в соответствии со следующими правилами.

Если один из операндов имеет тип long double, то второй тоже будет преобразован в long double.

Если п.2 не выполняется и один из операндов есть double, другой приводится к типу double.

Если п.2 - 3 не выполняются и один из операндов имеет тип float, то второй приводится к типу float.

Если п.2 - 4 не выполняются (оба операнда целые) и один операнд long int, а другой unsigned int, то, если long int может представить все значения unsigned int, последний преобразуется к long int; иначе оба операнда преобразуются к unsigned long int.

Если п.2 - 5 не выполняются и один операнд есть long, другой преобразуется к long.

Если п.2 - 6 не выполнены и один операнд unsigned, то другой преобразуется к unsigned.

Если п.2 - 7 не выполнены, то оба операнда принадлежат типу int.

 

Таблица 4

Правила стандартных арифметических преобразований

 

Исходный тип Преобразуется в Правила преобразования
char int, unsigned int, long int, unsigned long Расширение нулем или знаком в зависимости от умолчания для char (см. пример 1)
unsigned char int Старший байт заполняется нулем
signed char int Расширение знаком
short int Сохраняется то же значение
unsigned short unsigned int Сохраняется то же значение
int unsigned int Сохраняется то же значение
int long, unsigned long Расширение знаком
unsigned int long unsigned Добавление двух нулевых старших байтов
long int unsigned long Сохраняется то же значение
enum int Сохраняется то же значение
битовое поле int Сохраняется то же значение

 

Пример:

char ff = '\xff ', gg = '\x7f '; int i, j;

i = ff; //0xffff для signed char (размножение знака);

//0x00ff для unsigned char (размножение нуля)

j = gg; //0x007f для signed char (размножение знака);

//0x007f для unsigned char (размножение нуля)

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

 

 


ЭЛЕМЕНТАРНЫЙ ВВОД-ВЫВОД

Форматированный ввод-вывод

 

 

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

Консольный ввод-вывод может быть двух видов: форматиро­ванный и неформатированный. Форматированный ввод-вывод даст возможность обрабатывать за одно обращение к библиотеч­ной функции несколько элементов, выполняя, если необходи­мо, преобразование данных. Две функции-компаньона – scanf() и printf() выполняют соответственно консольный ввод и вывод. Этим функциям передастся переменное число аргументов, но первым аргументом всегда является текстовая (так называемая форматная) строка. Она задает способ преобразования данных. Функция printf() выдаст на экран всю форматную строку, в ко­торой знак %ххх заменяется символами выводимой информа­ции. Символы после % до первого разделителя рассматриваются как спецификация преобразования значения выводимой пере­менной. Имя переменной - это второй, третий и т.д. аргументы списка аргументов. Правила использования функции printf() представлены на рис. 3.

Функция scanf() принимает с консоли все символы до на­жатия клавиши ENTER и помещает их в буфер. Затем по форматной строке определяется способ преобразования вве­денных символов в соответствии с заданными спецификациями. Полученное в результате преобразования число помещает­ся по адресу переменной, который является вторым, третьим и т.д. аргументом в списке аргументов функции. Спецификация преобразования задается в виде последовательности

 

% [флаги ] [ширина ] [.точность J [F S N i h! 1 ]<тип>

 

В табл. 5 перечисляются некоторые из знаков, задающих спецификацию преобразования.

 

 

Рис. 3. Правила использования функции printf().

 

Таблица 5.

Символы управления форматированием

 



Поделиться:


Последнее изменение этой страницы: 2017-02-05; просмотров: 385; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.139.82.23 (0.554 с.)