ЛК_2_2 Основы С++. Книга для начинающих, представляющая пошаговое руководство по становлению программистом на C
Скачать 354.5 Kb.
|
Основные понятия языка программирования C++"Язык программирования C++". Это была первая книга, описывающая язык программирования C++, написанная создателем языка Бьярне Страуструпом. Страуструп начал разрабатывать C++ в 1979 году и считается самым важным авторитетом в этой области. "A Tour of C++" "Экскурсия по C++" того же автора. Это скорее справочник, чем учебник, не используйте его для изучения C++ - используйте его для улучшения памяти, когда вы начнете серьезно использовать C++. Алекс Аллейн "Переход на C++". Это отличная книга для начинающих, представляющая пошаговое руководство по становлению программистом на C++. Скотт Мейерс "Эффективный C++" - кто стремится улучшить свои программы и узнать больше о лучших практиках в C++ - книгаПростейшая программа на C++ #include using namespace std; int main() { cout << "It's me, your first program."; return 0; } Символ # (hash, хэш) означает, что содержимое этой строки является так называемой директивой препроцессора, preprocessor directive. Это отдельная часть компилятора, задача которой состоит в том, чтобы предварительно прочитать текст программы и внести в него некоторые изменения. Префикс "pre" предполагает, что эти операции выполняются до того, как произойдет полная обработка (компиляция). Изменения, которые внесет препроцессор, полностью контролируются его директивами. В этой программе - директива include. Когда препроцессор встречает (выполняет) эту директиву, он заменяет директиву содержимым файла, имя которого указано в директиве (файл с именем iostream). Изменения, внесенные препроцессором, не изменяют содержимое исходного файла. Любые изменения вносятся в изменяемую копию программы, которая исчезает сразу же после завершения компилятором своей работы. Зачем препроцессору включать содержимое файла с названием iostream? Написание программы похоже на построение конструкции из готовых блоков. В программе мы собираемся использовать один такой блок - cout, но компилятор пока ничего об этом не знает, не знает, что cout является допустимым именем для этого блока, в то время как cuot cute - нет. Компилятор должен знать об этом факте. Набор предварительной информации, необходимой компилятору, включен в header files (файлы заголовков). Эти файлы содержат набор предварительной информации о готовых блоках, которые могут быть использованы программой для написания текста на экране или для чтения букв с клавиатуры. Поэтому, когда программа собирается что-то написать (вывести на экран), она будет использовать блок под названием cout, который способен это выполнить. Нам нужно предупредить компилятор об этом. Разработчики компилятора поместили набор этой предварительной информации в файл iostream. Все, что нужно сделать, это использовать файл. Это то, что мы ожидаем от директивы include. Препроцессор знает, где находится файл iostream. В языке C++ все элементы стандартной инфраструктуры C++ объявляются в namespace пространстве имен, называемом std. Пространство имен - это абстрактный контейнер или среда, созданная для хранения логической группировки уникальных сущностей (блоков). Сущность, определенная в namespace пространстве имен, связана только с этим пространством имен. Если вы хотите использовать многие стандартные сущности C++, вы должны вставить инструкцию using namespace в начало каждого файла, вне какой-либо функции. В инструкции должно быть указано имя желаемого пространства имен namespace (в нашем случае std). Это сделает стандартные удобства доступными на протяжении всей программы. Можно опустить использование using namespace пространства имен в коде, но тогда нужно сообщить компилятору, откуда взялся блок cout, и вы должны делать это каждый раз, когда используете любую из сущностей, производных от пространства имен std. Нужно написать: std::cout вместо: cout Компилятору все равно, что вы выберете. Предпочтительно использовать пространство имен using namespace , это делает код более понятным и последовательным. Имя главной функции программы: main. С нее начинается выполнение программы Каждая функция в C++ начинается со следующего набора информации: каков результат выполнения функции? как называется функция? сколько аргументов принимает функция и каковы их имена? В программе: • результатом функции является целочисленное значение (int, является сокращением от integer) • название функции - main • функция не требует никаких аргументов (между скобками ничего нет). Этот набор информации называют prototype прототипом. Прототип ничего не говорит о том, для чего предназначена функция (это написано внутри функции). Внутренняя часть функции называется телом функции. Тело функции начинается с первой открывающей скобки { и заканчивается соответствующей закрывающей скобкой }. Тело функции может быть пустым, что означает, что функция ровно ничего не делает. Можно создать lazy (ленивую) функцию: void lazy() { } Слово void, помещенное перед именем функции (main), указывает компилятору, что функция не дает результата.. В более старых версиях C++ для объявления факта, что определенная функция (включая main) не принимает никаких аргументов: int main(void) { } Точка с запятой в конце строки. << указывает направление, в котором отправляется текст Строки в программе на C++ заключены в кавычки (так компилятор распознает текст, который отправляется пользователю программы). Приведенная форма исходного кода является наиболее естественной и наиболее легко читаемой людьми, но можно написать ее по-другому: cout << "It's me, your first program." ; В языке C++ нет необходимости писать только один оператор в строке. Вы можете разместить два (или более) утверждения в одной строке или разделить одно утверждение на несколько строк, но читаемость (для людей) является очень важным фактором. Но компиляторы, в отличие от людей, никогда не будут жаловаться на ваш стиль. Последняя строчка: return 0;Последняя строчка: return 0; Это оператор языка C++. Его имя - return - возвращение. Используемый в функции, он вызывает завершение выполнения функции. Если вы выполняете возврат где-то внутри функции, эта функция немедленно прерывает ее выполнение. Ноль 0 после слова return является результатом функции main. Это важно - вот как ваша программа сообщает ОС следующее: я сделал то, что должен был сделать, все в порядке. Если бы вы написали: return 1; это означало бы, что что-то пошло не так, это не позволило успешно выполнить вашу программу, и ОС могла бы использовать эту информацию для соответствующей реакции. Обычно, если функция возвращает целочисленное значение (main), она обязана содержать оператор return , он обязан возвращать целочисленное значение. Иначе - ошибка компиляции. Но основная функция main является исключительной. Объявлен как int, но не должен возвращать его. Более того, если внутри основной функции нет оператора return, компилятор предполагает, что неявно использовалось значение return 0. Но рекомендуется использовать return в main . ЧислаЧисла Числа, обрабатываемые компьютерами, бывают двух типов: • целые числа int; • числа с плавающей запятой float, которые содержат (могут содержать) дробную часть. Это определение упрощенное. Оба этих вида чисел различаются тем, как они хранятся в памяти компьютера, и диапазоном допустимых значений. Характеристика числа, которая определяет его вид, диапазон и применение, называется типом. Как язык C++ распознает целые числа? Использование одинарных кавычек в качестве разделителей, улучшающих читаемость целых чисел, было введено в C++17 - более старый компилятор отвергнет такую запись Например, число одиннадцать миллионов сто одиннадцать тысяч сто одиннадцать. В C++ это: 11111111 или можно записать его как: 11'111'11 Отрицательные числа в C++: -11111111 Положительным числам не обязательно знак плюс: +123 123 Существуют три дополнительных соглашения: 1 - позволяет использовать числа в (octal representation) восьмеричном представлении. Если целому числу предшествует цифра 0, оно будет рассматриваться как восьмеричное значение (что число должно содержать цифры, взятые только из диапазона от 0 до 7). 0123 восьмеричное число с (десятичным) значением = 83. 2 - шестнадцатеричные числа, предшествует префикс 0x или 0X. 0x123 - шестнадцатиричное число = десятичному значению 291. 3 - двоичные числа, которым предшествует префикс 0b или 0B. 0B1111 - двоичное число = десятичному значению 15. КомментарииКомментарии Язык C++ поддерживает два способа вставки комментариев: // comment - однострочные комментарии and /* comment */ - блок комментариев (также известные как комментарии в стиле C из-за того, что они используются с самого начала ЯП C, предшественника C++). Однострочный комментарий отбрасывает все, начиная с того места, где находится пара знаков косой черты (//), и заканчивая концом той же строки. На языке C++ комментарий к блоку - это текст, начинающийся с пары следующих символов: /* и заканчивается парой следующих символов: */ Комментарий может занимать несколько строк или занимать только одну строку или часть строки. Может ли другой комментарий быть помещен в один комментарий. Рассмотрим: /* int i; /* int j; */ int k; */ Вопрос: разрешено ли вам размещать один комментарий блока (например, /* int j; */)) внутри другого комментария блока? Ответ - нет. Такая нотация может быть не принята конкретным компилятором и, по сути, делает наш код подверженным капризам компилятора - мы не хотим полагаться на неопределенные предположения. Рекомендуется вам не использовать такую конструкцию в своем коде, даже если ваш компилятор допускает это. Числа с плавающей запятой Десятичная точка необходима для распознавания чисел с плавающей запятой в C++: 4 и 4.0 Компилятор C++ видит их совершенно по-другому: 4 - это int 4.0 - это float. 300000000 3 • 10^8 3E8 6.62607E-34 код: int i = 10 / 4; i =2 float x = 10.0 / 4.0; x = 2,5 Пример. Вычислить значение q.
int j = 25; int k = 13; int q = (5 * ((j % k) + i) / (2 * k)) / 2; q=10. Операторы Pre и postОператоры Pre и post
int j = i++; В результате j получит значение 1, а i - значение 2. int i = 1; int j = ++i; i, и j будут равны 2. int i = 4; int j = 2 * i++; i = 2 * --j; Результат = 14. Операторы префиксной версии- справа налево, постфиксные операторы - слева направо. Операторы быстрого доступа i = i * 2; i *= 2; Общее описание: если op является оператором с двумя аргументами (это важное условие) и используется в контексте: variable = variable op expression; то это выражение можно упростить: variable op= expression; Ряд слов в языке Си++ не может использоваться в качестве идентификаторов. Такие зарезервированные слова называются ключевыми. Примеры: asm auto bad_cast bad_typeid bool break case catch char clas cons continue default delete do double else enum extern float for friend goto if inline int long mutable namespace new operator private protected public register return short signed sizeofstatic static_cast struct switch template thenthis throw try type_info typedef typeidunion unsigned using virtual void volatile while xalloc Пример: int max(int x, int y) { if (x > y) return x; else return y;} max, x и y – имена или идентификаторы. Слова int, if, return и else – ключевые слова, они не могут быть именами переменных или функций и используются для других целей. ПеременнаяПеременная Для символического обозначения величин, имен функций и т.п. используются имена или идентификаторы. Идентификаторы в языке Си++ – это последовательность знаков, начинающаяся с буквы или знака подчеркивания. Что есть у каждой переменной? имя; тип; значение; Правила: имя переменной должно состоять из прописных или строчных латинских букв, цифр и символа _ (подчеркивание); имя переменной должно начинаться с буквы; • символ подчеркивания - это буква; • прописные и строчные буквы обрабатываются как разные; Стандарт языка C++ не накладывает ограничений на длину имен переменных, но у конкретного компилятора оно может быть. Корректные, но не всегда удобные имена переменных: variable i t10 Exchange_Rate counter DaysToTheEndOfTheWorld TheNameOfAVariableWhichIsSoLongThatYouWillNotBeAbleToWriteItWithoutMistakes _ abc A12 NameOfPerson BYTES_PER_WORD abc и Abc – два разных идентификатора, т.е. заглавные и строчные буквы различаются. Пример неправильного идентификатора: 12X a-b Некорректные имена: 12X a-b 10t Adiós_Señora Exchange Rate Дополнительная информация о стиле именования и соглашениях C++ в Основных руководствах по C++. C++ Core Guidelines Тип - это атрибут (attribute) , который однозначно определяет, какие значения могут храниться внутри переменной. Например, типы целых чисел (int) и с плавающей запятой (float). Значение переменной. Можно ввести только значение, совместимое с типом переменной. Переменной типа int может быть присвоено только целочисленное значение Примеры создания и присваивания значений переменным: counter = 1; Фрагмент кода int variable; variable = 1; может быть скомпонован в следующую форму: int variable = 1; Такое решение демонстрирует некоторые важные преимущества. Объявление переменной с немедленным присвоением ей начального значения менее подвержено ошибкам, чем выполнение этих двух действий в двух разных местах. Код более разборчив, намерения программиста лучше узнаваемы, и если вы привыкли объявлять и инициализировать переменную за один шаг, вы минимизируете риск использования неинициализированной переменной. Можно:
result = 100 + 200; x = x + 1; Константы – это неизменяемая величина Явная запись значения в программе – это константа. Не всегда удобно записывать константы в тексте программы явно. Чаще используются символические константы. Например, если запишем : const int BITS_IN_WORD = 32; то затем имя BITS_IN_WORD можно будет использовать вместо целого числа 32. Преимущества такого подхода. имя BITS_IN_WORD (битов в машинном слове) дает хорошую подсказку, для чего используется данное число. Без комментариев понятно, что выражение b / BITS_IN_WORD (значение b разделить на число 32) вычисляет количество машинных слов, необходимых для хранения b битов информации. 2) Если по каким-либо причинам надо изменить эту константу, потребуется изменить только одно место в программе – определение константы, оставив все случаи ее использования как есть. ВыраженияВыражения Программа оперирует с данными. Числа можно +, -, /, *. Из разных величин можно составлять выражения, результат вычисления которых – новая величина. Примеры выражений: X * 12 + Y // значение X *на 12 и к результату + значение Y val < 3 // сравнить значение val с 3 -9 // константное выражение -9 Выражение, после которого стоит точка с запятой – это оператор-выражение. Его смысл состоит в том, что компьютер должен вычислить выражение. x + y – 12; // сложить значения x и y и затем вычесть 12a = b + 1; // прибавить единицу к значению b и запомнить результат в переменной a Выражения – это переменные, функции и константы, называемые операндами, объединенные знаками операций. Операции могут быть унарными – с одним операндом, например, минус; могут быть бинарные – с двумя операндами, например сложение или деление. В Си++ есть операция с тремя операндами – условное выражение. В типизированном языке ся Си++, у переменных и констант есть определенный тип. Есть он и у результата выражения. Например, операции сложения (+), умножения (*), вычитания (-) и деления (/), примененные к целым числам, выполняются по общепринятым математическим правилам и дают в результате целое значение. Те же операции можно применить к вещественным числам и получить вещественное значение. Операции сравнения: больше (>), меньше (<), равно (==), не равно (!=) сравнивают значения чисел и выдают логическое значение: истина (true) или ложь (false). Типы данных в С++. В любом ЯП каждая константа, переменная, результат вычисления выражения или функции должны иметь тип данных. Тип данных – это множество допустимых значений, которые может принимать тот или иной объект, а также множество допустимых операций, которые применимы к нему. Тип также зависит от внутреннего представления информации. Данные различных типов хранятся и обрабатываются по-разному. Тип данных определяет: внутреннее представление данных в памяти компьютера; объем памяти, выделяемый под данные; множество (диапазон) значений, которые могут принимать величины этого типа; операции и функции, которые можно применять к данным этого типа. Необходимо определять тип каждой величины, используемой в программе для представления объектов. Обязательное описание типа позволяет компилятору производить проверку допустимости различных конструкций программы. От выбора типа величины зависит последовательность машинных команд, построенная компилятором. ЯП C++ поддерживает следующие типы данных. Базовые типы - предопределены стандартом языка, указываются зарезервированными ключевыми словами и характеризуются одним значением. Их не надо определять и их нельзя разложить на более простые составляющие без потери сущности данных. Базовые типы объектов создают основу для построения более сложных типов. Производные типы. Производные типы задаются пользователем, и переменные этих типов создаются как с использованием базовых типов, так и типов классов. Типы класса. Экземпляры этих типов называются объектами. Типы данных в С++:Типы данных в С++: Существует четыре спецификатора типа данных, уточняющих внутренне представление и диапазон базовых типов: short (короткий)длина long (длинный) signed (знаковый)знак (модификатор) unsigned (беззнаковый) Целочисленный (целый) тип данных (тип int) Переменные данного типа применяются для хранения целых чисел (integer). Описание переменной, имеющей тип int, сообщает компилятору, что он должен связать с идентификатором (именем) переменной количество памяти, достаточное для хранения целого числа во время выполнения программы. Границы диапазона целых чисел, которые можно хранить в переменных типа int, зависят от конкретного компьютера, компилятора и операционной системы (от реализации). Для 16-разрядного процессора под него отводится 2 байта, для 32-разрядного – 4 байта. Для внутреннего представления знаковых целых чисел характерно определение знака по старшему биту (0 – для положительных, 1 – для отрицательных). Поэтому число 0 во внутреннем представлении относится к положительным значениям. Следовательно, наблюдается асимметрия границ целых промежутков. В целочисленных типах для всех значений определены следующий и предыдущий элементы. Для максимального следующим значением будет являться минимальное в этом же типе, предыдущее для минимального определяется как максимальное значение. То есть целочисленный диапазон условно можно представить сомкнутым в кольцо. Поэтому определены операции декремента для минимального и инкремента для максимального значений в целых типах. От количества отводимой под объект памяти зависит множество допустимых значений, которые может принимать объект: short int – занимает 2 байта, имеет диапазон от –32 768 до +32 767; int – занимает 4 байта, имеет диапазон от –2 147 483 648 до +2 147 483 647; long int – занимает 4 байта, имеет диапазон от –2 147 483 648 до +2 147 483 647; long long int – занимает 8 байтов, имеет диапазон от –9 223 372 036 854 775 808 до +9 223 372 036 854 775 807. Модификаторы signed и unsigned также влияют на множество допустимых значений, которые может принимать объект: unsigned short int – занимает 2 байта, имеет диапазон от 0 до 65 535; unsigned int – занимает 4 байта, имеет диапазон от 0 до 4 294 967 295; unsigned long int – занимает 4 байта, имеет диапазон от 0 до 4 294 967 295; unsigned long long int – занимает 8 байтов, имеет диапазон от 0 до 18 446 744 073 709 551 615. Примеры: unsigned int b; signed int a; int c; unsigned d; signed f; Несколько правил, касающихся записи целочисленных значений в исходном тексте программ. Нельзя пользоваться десятичной точкой. Значения 26 и 26.0 одинаковы, но 26.0 не является значением типа int. Нельзя пользоваться запятыми в качестве разделителей тысяч. Число 23,897 следует записывать как 23897. Целые значения не должны начинаться с незначащего нуля. Он применяется для обозначения восьмеричных или шестнадцатеричных чисел, так что компилятор будет рассматривать значение 011 как число 9 в восьмеричной системе счисления. На практике рекомендуется использовать основной целый тип, то есть тип int. Данные основного целого типа практически всегда обрабатываются быстрее, чем данные других целых типов. Короткий тип short подойдет для хранения больших массивов чисел с целью экономии памяти при условии, что значения элементов не выходят за предельные границы для этих типов. Длинные типы необходимы в ситуации, когда не достаточно типа int. Вещественный (данные с плавающей точкой) тип данных (типы float и double) Для хранения вещественных чисел применяются типы данных float (с одинарной точностью) и double (с двойной точностью). Смысл знаков "+" и "-" для вещественных типов совпадает с целыми. Последние незначащие нули справа от десятичной точки игнорируются. Поэтому варианты записи +523.5, 523.5 и 523.500 представляют одно и то же значение. Для представления вещественных чисел используются два формата: с фиксированной точкой[знак][целая часть].[дробная часть] Например: –8.13; .168 (аналогично 0.168); 183. (аналогично 183.0). с плавающей точкой (экспоненциальной форме)мантисса Е/е порядок Например: 5.235e+02 (5.235 x 102 = 523.5); –3.4Е-03 (–3.4 x 10-03 = – 0.0034) Тип double обеспечивает более высокую точность, чем тип float. Максимальную точность и наибольший диапазон чисел достигается с помощью типа long double. Величина с модификатором типа float занимает 4 байта. Из них 1 бит отводится для знака, 8 бит для избыточной экспоненты и 23 бита для мантиссы. Отметим, что старший бит мантиссы всегда равен 1, поэтому он не заполняется, в связи с этим диапазон модулей значений переменной с плавающей точкой приблизительно равен от 3.14E–38 до 3.14E+38. Величина типа double занимает 8 байтов в памяти. Ее формат аналогичен формату float. Биты памяти распределяются следующим образом: 1 бит для знака, 11 бит для экспоненты и 52 бита для мантиссы. С учетом опущенного старшего бита мантиссы диапазон модулей значений переменной с двойной точностью равен от 1.7E–308 до 1.7E+308. Величина типа long double аналогична типу double. Символьный тип данных (тип char) В стандарте C++ нет типа данных, который можно было бы считать действительно символьным. Для представления символьной информации есть два типа данных, пригодных для этой цели, – это типы char и wchar_t. Переменная типа char рассчитана на хранение только одного символа (например, буквы или пробела). В памяти компьютера символы хранятся в виде целых чисел. Соответствие между символами и их кодами определяется таблицей кодировки, которая зависит от компьютера и операционной системы. Почти во всех таблицах кодировки есть прописные и строчные буквы латинского алфавита, цифры 0, ..., 9, и некоторые специальные символы. Самой распространенной таблицей кодировки является таблица символов ASCII ( American Standard Code for Information Interchange – Американский стандартный код для обмена информацией). Так как в памяти компьютера символы хранятся в виде целых чисел, то тип char на самом деле является подмножеством типа int. Под величину символьного типа отводится 1 байт. Тип char может использоваться со спецификаторами signed и unsigned. В данных типа signed char можно хранить значения в диапазоне от –128 до 127. При использовании типа unsigned char значения могут находиться в диапазоне от 0 до 255. Для кодировки используется код ASCII. Символы с кодами от 0 до 31 относятся к служебным и имеют самостоятельное значение только в операторах ввода-вывода. Величины типа char также применяются для хранения чисел из указанных диапазонов. Тип wchar_t предназначен для работы с набором символов, для кодировки которых недостаточно 1 байта, например в кодировке Unicode. Размер типа wchar_t равен 2 байтам. Если в программе необходимо использовать строковые константы типа wchar_t, то их записывают с префиксом L, например, L "Слово". Например: char c='c'; char a,b; char r[]={'A','B','C','D','E','F','\0'}; char s[] = "ABCDEF"; Логический (булевый) тип данных (тип bool) В языке С++ используется двоичная логика (истина, ложь). Лжи соответствует нулевое значение, истине – единица. Величины данного типа могут также принимать значения true и false. Внутренняя форма представления значения false соответствует 0, любое другое значение интерпретируется как true. Под данные логического типа отводится 1 байт. Перечисляемый тип (тип enum) Данный тип определяется как набор идентификаторов, являющихся обычными именованными целыми константами, которым приписаны уникальные и удобные для использования обозначения. Перечисления представляют собой упорядоченные наборы целых значений. Они имеют своеобразный синтаксис и достаточно специфическую область использования. Переменная, которая может принимать значение из некоторого списка определенных констант, называется переменной перечисляемого типа или перечислением. Данная переменная может принимать значение только из именованных констант списка. Именованные константы списка имеют тип int. Следовательно, память, соответствующая переменной перечисления, – это память, необходимая для размещения значения типа int. Например: enum year {winter, spring, summer, autumn}; enum week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; Тип voidТип void Множество значений этого типа пусто. Тип void имеет три назначения: указание о невозвращении функцией значения; указание о неполучении параметров функцией; создание нетипизированных указателей. Тип void в основном используется для определения функций, которые не возвращают значения, для указания пустого списка аргументов функции, как базовый тип для указателей и в операции приведения типов. Преобразования типовПреобразования типов При вычислении выражений некоторые операции требуют, чтобы операнды имели соответствующий тип, в противном же случае на этапе компиляции выдается сообщение об ошибке. Например, операция взятия остатка от деления (%) требует целочисленных операндов. В ЯП С++ есть возможность приведения значений одного типа к другому. Преобразование типов – это приведение значения переменной одного типа в значение другого типа. Выделяют явное и неявное приведения типов. При явном приведении указывается тип переменной, к которому необходимо преобразовать исходную переменную. При неявном приведении преобразование происходит автоматически, по правилам, заложенным в языке программирования С++. Формат операции явного преобразования типов: имя_типа (операнд) Например, int(x), float(2/5), long(x+y/0.5). Пример.Пример. //Взятие цифры разряда сотых в дробном числе #include "stdafx.h" #include using namespace std; int _tmain(int argc, _TCHAR* argv[]){ float s,t; long int a,b; printf("Введите вещественное число\n"); scanf("%f", &s); t=s*100; a=(int)t; //переменная t приводится к типу int в переменную a b=a%10; printf("\nЦифра разряда сотых числа %f равна %d.", s, b); system("pause"); return 0; } При выполнении математических операций производится неявное (автоматическое) преобразование типов, чтобы привести операнды выражений к общему типу или чтобы расширить короткие величины до размера целых величин, используемых в машинных командах. Выполнение преобразования зависит от специфики операций и от типа операнда или операндов. 1. Преобразование целых типов со знаком. Целое со знаком преобразуется к более короткому целому со знаком, с потерей информации: пропадают все разряды числа, которые находятся выше (или ниже) границы, определяющей максимальный размер переменной. Целое со знаком преобразуется к более длинному целому со знаком. Путем размножения знака. Все добавленные биты двоичного числа будут заняты тем же числом, которое находилось в знаковом бите: если число было положительным, то это будет, соответственно 0, если отрицательным, то 1. Целое со знаком к целому без знака. Сначала целое со знаком преобразуется к целому со знаком, соответствующему целевому типу, если этот тип данных крупнее. У получившегося значения бит знака не отбрасывается, все биты образуют числовое значение. Преобразование целого со знаком к плавающему типу происходит без потери информации, за исключением случая преобразования типа long int или unsigned long int к типу float, когда точность часто может быть потеряна. 2. Преобразование целых типов без знака. Целое без знака преобразуется к более короткому целому без знака или со знаком путем усечения. Целое без знака преобразуется к более длинному целому без знака или со знаком путем добавления нулей слева. Целое без знака преобразуется к целому со знаком того же размера. Если взять для примера, unsigned short и short – числа в диапазоне от 32768 до 65535 превратятся в отрицательные. Целое без знака преобразуется к плавающему типу. Сначала оно преобразуется к значению типа signed long, которое затем преобразуется в плавающий тип. 3. Преобразования плавающих типов. Величины типа float преобразуются к типу double без изменения значения. Величины double преобразуются к float c некоторой потерей точности, то есть, количества знаков после запятой. Если значение слишком велико для float, то происходит потеря значимости, о чем сообщается во время выполнения. При преобразовании величины с плавающей точкой к целым типам она сначала преобразуется к типу long (дробная часть плавающей величины при этом отбрасывается), а затем величина типа long преобразуется к требуемому целому типу. Если значение слишком велико для long, то результат преобразования не определен. Обычно это означает, что на усмотрение компилятора может получиться любой "мусор". В реальной практике с такими преобразованиями обычно сталкиваться не приходится. Ключевые терминыКлючевые термины Базовые типы – это типы данных, которые предопределены стандартом языка, указываются зарезервированными ключевыми словами, характеризуются одним значением и внутренним представлением. Вещественный тип – это базовый тип данных, который применяется для хранения дробных чисел в формате с плавающей точкой. Логический (булевый) тип – это базовый тип данных, который применяется для хранения значений двузначной логики. Неявное приведение типа – это преобразование значения переменной к новому типу, которое происходит автоматически, по правилам, заложенным в языке программирования. Перечисляемый тип – это производный тип данных, он определяется как набор идентификаторов, являющихся именованными целыми константами, которым приписаны уникальные обозначения Преобразование типов – это приведение значения переменной одного типа в значение другого типа. Производные типы – это типы данных, которые задаются пользователем. Ключевые терминыКлючевые термины Символьный тип – это базовый тип данных, который применяется для хранения символов или управляющих последовательностей в виде кода. Тип данных – это множество допустимых значений, которые может принимать тот или иной объект, а также множество допустимых операций, которые применимы к нему. Типы класса – это типы данных, экземплярами которых являются объекты. Целочисленный тип – это базовый тип данных, который применяется для хранения целых чисел. Явное приведение типа – это преобразование значения переменной к новому типу, при котором указывается тип переменной, к которому необходимо привести исходную переменную. Краткие итоги Для организации хранения данных и корректного выполнения операций над ними в языках программирования определены типы данных. Типы характеризуются схожим внутренним представлением данных в памяти компьютера; объемом памяти, выделяемым под данные; множеством (диапазоном) принимаемых значений; допустимыми операциями и функциями. В языке С++ типы классифицируются на базовые, производные и классы. Для базовых типов определены их подмножества и расширения, что обеспечивает повышение точности расчетов или экономный расход памяти. Над типами данных определена операция преобразования типов. Ее следует применять с осторожностью при переходе к типу, у которого меньше по модулю границы диапазонов. Пример 1. Пусть необходимо разделить целых числа. int x,y; x=15; Y=2; Делим: x/y=7. Если сделать преобразования, например: x/y.=7.5 Тогда число 2 является вещественным, значит и результат будет вещественный. Само число 2 с точки зрения математики не изменилось, ведь 2=2.0. Этот же прием можно было применить к 15, результат был бы тем же, а можно было сразу к двум числам, но зачем ,если хватает одного из двух. Пример 2. int i1 = 11; int i2 = 3; float x = (float)i1 / i2; Стандартная библиотека ввода-вывода Си (заголовочный файл stdio.h) Функция консольного форматного выводаВызов функции: printf(форматная_строка, список_вывода); Что выводим: переменные, простые и с индексами, константы, произвольные выражения; перечисление через запятую. В каком виде выводим. Форматная строка – это строка выводимого текста, в который вставлены спецификации форматов для выводимых значений. Спецификации форматовОбщий вид спецификации формата: %ширина_поля.точность спецификатор Число символов (позиций). занимаемых значением. Если ширина недостаточна, то она игнорируется; если избыточна, то значение дополняется пробелами. Число цифр дробной части – только для вещественных чисел. Какое значение выводим Основные спецификаторыd - для целых значений (типов int, char, unsigned); f - для вещественных значений (типов float, double); e - для вещественных значений (типов float, double)с указанием порядка, т. е. в виде: знак_числаm.ddddeзнак_порядкаxxx, где m.dddd - изображение мантиссы числа; m - одна десятичная цифра; dddd - последовательность десятичных цифр; е - признак порядка (десятичного); xxx - десятичные цифры для представления порядка числа. u – для значений без знака; c - для одиночного символа (типов int, char, unsigned); s - для строк. Простейший пример форматного выводаfloat s; int a,b;... printf("a=%2d b=%4d\n s=%4.1f\n", a,b,s); Форма вывода a= b= s= Если a=-2, b=93, s=3.22, то на экране получим: a=-2 b= 93 s= 3.2 форматная строка может содержать управляющие символы. Функция консольного форматного вводаВызов функции: scanf(форматная_строка, список_ввода); Что вводить: адреса вводимых переменных через запятую. Почему адреса? Почему только переменных? В каком виде вводимые значения представлены в консольном экране. Форматная строка при вводе содержит только спецификации форматов. текста не содержит. Почему? Вводимые значения могут разделяться пробелами (одним или несколькими) или переводом строки (нажатием клавиши Enter), после последнего введенного значения надо обязательно нажать Enter. Простейший пример форматного ввода int i; float a; printf("Введите i и a\n"); /* вывод приглашения к вводу */ scanf("%d%f", &i, &a);... /* спецификации могут */ /* не содержать ширины и точности */ Форма ввода Введите i и a { } – альтернативный вывод Замечание. При вводе строк символов с помощью функции scanf() (и с помощью cin) действуют более сложные правила. Так, в буфер устройства ввода считываются все символы до нажатия Enter, а в вводимую строковую переменную передаются символы до первого пробела. Такой принцип работы scanf() имеет свои преимущества, но они слишком трудны при начальном освоении языка Си. Поэтому для ввода и вывода строк лучше пользоваться функциями gets() и puts() из стандартной библиотеки Си. |