Обработка арифметических выражений — КиберПедия 

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Обработка арифметических выражений

2019-12-21 163
Обработка арифметических выражений 0.00 из 5.00 0 оценок
Заказать работу

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

Если операндом является целое число меньше (по размеру/диапазону) типа 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 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.01 с.