Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Неявное преобразование типов




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

Неявные преобразования типов данных происходят в следующих случаяx:

 1) при выполнении арифметических действий,

2) при выполнении операции присваивания, если значение левой и правой части выражения различается по типу,

3) при передаче аргументов в функцию.

В независимости от причины, вызвавшей неявное преобразование, все они подчиняются общим правилам, которые состоят в следующем:

1) все операнды выражения преобразуются к типу операнда с наибольшем размером памяти.

Согласно этому правилу float преобразуется в double, а long – в unsigned long и т.д.

2) операнд типа char всегда преобразуется к типу int по следующим правилам:

unsigned char преобразуется в int, у которого знаковый разряд всегда нулевой;

signed char преобразуется в int, у которого знаковый разряд совпадает со знаком из char.

3) В выражении тип правой части преобразуется к типу левой части выражения. Если размер результата в правой части больше размера операнда в левой части, то часть результата будет потеряна.

Пример.

double ft, sd;

unsigned char ch;

unsigned long in;

int i;

sd = ft*(i+ch/in);

В этом выражении преобразования типов данных будут выполняться в следующей последовательности:

Операнд ch преобразуется к типу unsigned int (правило для типа char).

Затем он преобразуется к типу unsigned long (к большему операнду выражения ch/in), по этой же причине i преобразуется к unsigned long.

Результат операции, заключенной в круглые скобки, будет иметь тип unsigned long.

Затем он преобразуется к типу double (к большему операнду выражения ft*(i+ch/in)).

Результат всего выражения будет иметь тип double.

 

Логические операции и операции отношения

Операции отношения используются для проверки условий, это бинарные операторы (с двумя операндами). В качестве первого операнда может выступать переменная или константа, которая сравнивается со вторым оператором – литералом, переменной или константой. Результат сравнения всегда логический – TRUE (истина – "да") или FALSE (ложь – "нет"). В С FALSE кодируется 0, а все что не 0, то TRUE. Поэтому логические переменные TRUE и FALSE можно заменять целыми переменными типа int.

К операциям отношения относятся:

> больше

< меньше

>= больше или равно

<= меньше или равно.

Все они имеют одинаковый ранг. Непосредственно за ними по уровню старшинства следуют операции сравнения на равенство или неравенство:

== равно (сравнение);

!= не равно.

Операции отношения ниже рангом, чем арифметические операции, поэтому выражение i < lim +3 понимается как i < (lim +3).

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

К логическим операциям относятся:

&& - логическое "И" (конъюнкция), бинарная операция,

|| - логическое "ИЛИ" (дизъюнкция), бинарная операция,

! – логическое "НЕ" (отрицание), унарная операция.

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

Также как и у операций отношения, у логических операций результат бинарный – FALSE или TRUE (0 или 1).

Результат операции логическое И имеет значение TRUE только если оба операнда имеют значение TRUE. Результат операции логическое ИЛИ имеет значение TRUE, если хотя бы один из операндов имеет значение TRUE. Если значения первого операнда достаточно, чтобы определить результат операции, второй операнд не вычисляется.

 

Поразрядные (побитовые) операции

Как известно, на машинном уровне вся информация представлена в виде 0 и 1, но обычно для того, чтобы выполнять вычисления, программисту не обязательно знать это представление, языки высокого уровня берут на себя эту рутинную работу, и позволяют программисту оперировать данными в привычной для себя форме.

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

Побитовые операции используются для анализа и изменения отдельных битов числа и применяются только к переменным целого типа: int, char и их вариантам. Побитовые операции нельзя применять к переменным типа float, double, void, а также к более сложным типам данных.

Отдельные биты переменной можно рассматривать как логические значения, т.к. они могут принимать лишь два значения 0 или 1, которые в С рассматривают как FALSE или TRUE.

К побитовым операциям относятся

~ отрицание (инверсия)

& логическое И

| логическое ИЛИ

^ исключающее ИЛИ (отрицание равенства).

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

При поразрядной конъюнкции, или поразрядном И бит результата равен 1 только тогда, когда соответствующие биты обоих операндов равны 1.

При поразрядной дизъюнкции, или поразрядном ИЛИ бит результата равен 1 тогда, когда соответствующий бит хотя бы одного из операндов равен 1.

При поразрядном исключающем ИЛИ бит результата равен 1 только тогда, когда соответствующий бит только одного из операндов равен 1.

Пример.

#include <iostream.h>

int main()

{

cout << "\n 6&5 =" << (6&5);

cout << "\n 6|5 =" << (6|5);

cout << "\n 6^5 =" << (6^5);

return 0;

}

Результат работы программы:

6&5 = 4;

6 | 5 = 7;

6 ^ 5 = 3.

 

Операции сдвига

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

Существуют две операции сдвига:

<< - сдвиг влево

>> - сдвиг вправо.

При сдвиге влево правые освобождающиеся биты устанавливаются в 0.

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

 

Операция sizeof

Операция определения размера sizeof предназначена для вычисления размера объекта или типа в байтах, и имеет две формы:

sizeof выражение

 sizeof (тип)

Пример.

#include <iostream.h>

int main()

{

float x=1;

cout << " sizeof (float):" << sizeof (float);

cout << "\n sizeof x:" << sizeof x;

cout << "\n sizeof (x+1.0):" << sizeof (x+1.0);

return 0;

}

Результат работы программы:

sizeof (float): 4

sizeof x: 4

sizeof (x+1.0): 8

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

 

2.9 Операции отрицания (-, !, ~)

Арифметическое отрицание (унарный минус) изменяет знак операнда целого или вещественного типа на противоположный. Логическое отрицание (!) дает в результате значение 0, если операнд есть истина, и значение 1, если операнд равен 0. Операнд должен быть целого или вещественного типа, а может иметь также тип указатель. Поразрядное отрицание (~), часто называемое побитовым, инвертирует каждый разряд в двоичном представлении целочисленного операнда.

 

Операция следования

Символом операции следования является "," (запятая). Выражения, разделенные этим символом, выполняются слева направо строго в том порядке, в котором они перечислены. Результатом операции является результат последнего выражения. Поскольку запятая может использоваться и в качестве разделителя, важно не путать эти два ее значения.

Пример.

//в первой строке запятая – разделитель, а не операция

int a=3, b=8, С;

//а сейчас уже операция следования

C=k++, k+b;

(b--, С)*=3;

Первую операцию следования можно заменить следующей последовательностью команд:

C=k++, C=k+b;

В результате получим С = 12.

Вторую операцию следования можно заменить последовательностью команд:

b--; С*=3;

в результате получаем b=7; С = 36.

В качестве разделителя запятая может применяться в следующих случаях:

1) в функциях для разделения аргументов, если их более одного. Например, fl(x, y).

2) при объявлении переменных (см. первую строку примера).

В качестве операции запятая часто используется в операторе for.

 

Условная операция (?:)

Эта операция тернарная, т.е. имеет три операнда. Ее формат

Операнд_1 ? операнд_2 : операнд_3

Первый операнд может иметь арифметический тип или быть указателем. Он оценивается с точки зрения его эквивалентности 0 (операнд, равный 0, рассматривается как false, не равный 0 – как true). Если результат вычисления операнда 1 равен true, то результатом условной операции будет значение второго операнда, иначе – третьего операнда. Вычисляется всегда либо второй, либо третий операнд. Их тип может различаться. Условная операция является сокращенной формой условного оператора if.

Пример.

#include <stdio.h>

int main()

{

int a=11, b=4, max;

max = (b>a)? b : a;

pintf("Наибольшее число: %d", max);

return 0;

}

Результат работы программы:

Наибольшее число: 11.

 

Другой пример применения условной операции. Требуется, чтобы некоторая целая величина увеличивалась на 1, если ее значение не превышает n, а иначе принимала значение 1:

i = (i<n)? i+1 : 1.

 



Выражения

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

Примеры выражений:

(a + 0.12) /6

X && y || !z

(t*sin(x)-1.05t-4)

Операции выполняются в соответствии с приоритетами. Для изменения порядка выполнения операций используют круглые скобки. Если в одно выражении записано несколько операций одинакового приоритета, унарные операции, условная операция и операция присваивания выполняются справа налево, остальные – слева направо. Например, а=b=с означает а = (b=c), а а+b+с означает (a+b)+c. Порядок вычисления подвыражений внутри выражений не определен. Например, нельзя считать, что в выражении sin (x+2) + cos (y+1) обращение к синусу будет выполнено раньше, чем к косинусу, и что х+2 будет вычислено раньше, чем у+1.

Результат вычисления выражения характеризуется значением и типом. Например, если а и b – переменные целого типа и описаны как

int a=2, b=5;

то выражение а +и имеет значение 7 и тип int, а выражение а=и имеет значение, равное помещенному в переменную а (в данном случае 5) и тип, совпадающий с типом этой переменной. Таким образом, в С++ допустимы выражения вида а=b=с. Сначала вычисляется выражение b=с, а затем его результат становится правым операндом для операции присваивания переменной а.

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

Преобразования бывают двух типов:

- Изменяющие внутреннее представление величин (с потерей точности или без потери точности);

- Изменяющие только интерпретацию внутреннего представления.

К первому типу относится, например, преобразование целого типа в вещественное (без потери точности) и наоборот (возможно, с потерей точности), ко второму – преобразование знакового целого в беззнаковое.

В любом случае величины типов char, signed char, unsigned char, short int и unsigned short int преобразуются в тип int, если он может представить все значения, или в unsigned int в противном случае.

После этого операнды преобразуются к типу наиболее длинного из них, и он используется как тип результата.










Последнее изменение этой страницы: 2018-05-10; просмотров: 149.

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