Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьшения длины пробега и улучшения маневрирования ВС при...
Топ:
Проблема типологии научных революций: Глобальные научные революции и типы научной рациональности...
Интересное:
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Аура как энергетическое поле: многослойную ауру человека можно представить себе подобным...
Дисциплины:
2019-12-21 | 163 |
5.00
из
|
Заказать работу |
|
|
При обработке выражений компилятор разбивает каждое выражение на отдельные подвыражения. Арифметические операторы требуют, чтобы их операнды были одного типа данных. Чтобы это гарантировать, компилятор использует следующие правила:
Если операндом является целое число меньше (по размеру/диапазону) типа int, то оно подвергается интегральному расширению в int или в unsigned int.
Если операнды разных типов данных, то компилятор вычисляет операнд с наивысшим приоритетом и неявно конвертирует тип другого операнда в соответствие к типу первого.
Приоритет типов операндов:
long double (самый высокий);
double;
float;
unsigned long long;
long long;
unsigned long;
long;
unsigned int;
int (самый низкий).
Мы можем использовать оператор typeid() (который находится в заголовочном файле typeinfo), чтобы узнать решающий тип в выражении.
В следующем примере у нас есть две переменные типа short:
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> #include <typeinfo> // для typeid() int main() { short x(3); short y(6); std::cout << typeid(x + y).name() << " " << x + y << std::endl; // вычисляем решающий тип данных в выражении x + y return 0; } |
Поскольку значениями переменных типа short являются целые числа и тип short меньше (по размеру/диапазону) типа int, то он подвергается интегральному расширению в тип int. Результатом добавления двух int-ов будет тип int:
int 9
Рассмотрим другой случай:
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> #include <typeinfo> // для typeid() int main() { double a(3.0); short b(2); std::cout << typeid(a + b).name() << " " << a + b << std::endl; // вычисляем решающий тип данных в выражении a + b return 0; } |
Здесь short подвергается интегральному расширению в int. Однако int и double по-прежнему не совпадают. Поскольку double находится выше в иерархии типов, то целое число 2 преобразовывается в 2.0 (тип double), и два double-а равно double:
|
double 5
С этой иерархией иногда могут возникать интересные ситуации. Например:
1 2 3 4 5 6 7 8 | #include <iostream> int main() { std::cout << 5u - 10; // 5u означает значение 5 типа unsigned int return 0; } |
Ожидается, что результатом выражения 5u − 10 будет -5, поскольку 5 − 10 = -5. Но результат:
4294967291
Здесь значение signed int (10) подвергается расширению в unsigned int (которое имеет более высокий приоритет), и выражение вычисляется как unsigned int. А поскольку unsigned — это только положительные числа, то происходит переполнение, и мы имеем, что имеем.
Это одна из тех многих веских причин избегать использования типа unsigned int вообще.
Явное преобразование типа
Операция используется, как и следует из ее названия, для явного преобразования величины из одного типа в другой. Это требуется в том случае, когда неявного преобразования не существует. При преобразовании из более длинного типа в более короткий возможна потеря информации, если исходное значение выходит за пределы диапазона результирующего типа.
Формат операции:
(тип) выражение;
Здесь тип — это имя того типа, в который осуществляется преобразование, а выражение чаще всего представляет собой имя переменной, например;
long b= 300;
int a = (int) b; // данные не теряются
byte d = (byte) a; // данные теряются
13
Инкремент и декремент
Операции инкремента (++) и декремента (--), называемые также операциями увеличения и уменьшения на единицу, имеют две формы записи — префиксную, когда знак операции записывается перед операндом, и постфиксную. В префиксной форме сначала изменяется операнд, а затем его значение становится результирующим значением выражения, а в постфиксной форме значением выражения является исходное значение операнда, после чего он изменяется.
Пример операций инкремента и декремента
using System;
namespace ConsoleApplication1
{ class Classl
{ static void Main()
{int x = 3, у = 3;
Console.Write("Значение префиксного выражения: "');
|
Console.WriteLine(++x);
Console,Write("Значение х после приращения: ");
Console.WriteLine(x);
Console.Write("Значение постфиксного выражения: ").;
Console.WriteLine(y++);
Console.Write("Значение у после приращения: ");
Console.WriteLine(у);} } }
Результат работы программы:
Значение префиксного выражения: 4
Значение х после приращения: 4
Значение постфиксного выражения: 3
Значение у после приращения: 4
Операции отрицания
Арифметическое отрицание (унарный минус -) меняет знак операнда на противоположный. Стандартная операция отрицания определена для типов int, long, float, double и decimal. К величинам других типов ее можно применять, если для них возможно неявное преобразование к этим типам (см. рис. 3.1). Тип результата соответствует типу операции.
Логическое отрицание (!) определено для типа bool. Результат операции —значение false, если операнд равен true, и значение true, если операнд равен false.
Поразрядное отрицание (~), часто называемое побитовым, инвертирует каждый разряд в двоичном представлении операнда типа int, uint, long или ulong.
Пример операций отрицания
using System;
namespace ConsoleApplication1
{ class Classl
{ static void Main()
{
sbyte a = 3, b = -63, с = 126;
bool d = true;
Console.WriteLine(-a); // Результат -3
Console.WriteLine(-c); // Результат -126
Console.WriteLine(!d); // Результат false
Console.WriteLine(~a); // Результат -4
Console.WriteLinet(~b); // Результат 62
Console.WriteLine(~c); // Результат -127 } } }
|
|
История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...
Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!