Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Програм-е на ЯВУ / Программирование на языках выского уровня, алгоритмические языки.doc
Скачиваний:
63
Добавлен:
11.04.2014
Размер:
1.74 Mб
Скачать

Выражения и операции

Выражения

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

Рассмотрим примеры выражений:

Выражения

Использованные операции

Операнды

(a + 0.12)/6

+ (сложение)

/ (деление)

a(переменная), 0.12(константа)

(a + 0.12) (выражение), 6(константа)

x && y || !z

! (логическое НЕ)

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

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

z (переменная)

у (переменная), !z (выражение)

у (переменная), y || !z (выражение)

t*sin(x)/(0.2+k)

+ (сложение)

/ (деление)

* (умножение)

0.2 (константа), k (переменная)

sin(x) (выражение),(0.2+k) (выражение)

t(переменная), sin(x)/(0.2+k) (выражение)

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

Для изменения порядка выполнения операций используются круглые скобки. Благодаря им, выражение t * sin(x)/(0.2 + k) будет выполняться в следующем порядке: сначала будет вычислено выражение 0.2 + k, затем выражение sin(x) будет разделено на полученное значение, и, наконец, промежуточный результат будет умножен на t.

Операции

В языке Си имеются следующие классы операций:

  • арифметические операции;

  • операции отношения;

  • логические операции;

  • побитовые операции;

  • операции присваивания;

  • адресные операции;

  • операции над массивами;

  • операции над структурами и объединениями;

  • прочие операции.

Оператор

Пример

Выполняемое действие

Арифметические операции

*

var1 * var2

умножает одно число на другое: 6*3 будет 18

/

var1 / var2

делит одно число на другое: 6/3 будет 2

+

var1 + var2

суммирует два числа: 6+3 будет 9

var1 – var2

-var

отнимает от одного числа другое: 6–3 будет 3; может использоваться как унарный минус: -a, -5

%

var1 % var2

возвращает остаток от деления двух чисел: 5%3 будет 2, 6%3 будет 0, 3%6 будет 3

++

var++

++var

увеличивает число на 1: var= 5, var++ будет 6

––

var––

––var

уменьшает число на 1: var= 5, var–– будет 4

Операции отношения

>

var1 > var2

возвращает ИСТИНА, если значение слева больше значения справа: 3 > 5 будет ЛОЖЬ, 3 > 1 будет ИСТИНА, 3 > 3 будет ЛОЖЬ

>=

var1 >= var2

возвращает ИСТИНА, если значение слева больше значения справа или равно ему: 3 >= 5 будет ЛОЖЬ, 3 >= 1 будет ИСТИНА, 3 >= 3 будет ИСТИНА

<

var1 < var2

возвращает ИСТИНА, если значение слева меньше значения справа: 3 < 5 будет ИСТИНА, 3 < 1 будет ЛОЖЬ, 3 < 3 будет ЛОЖЬ

<=

var1 <= var2

возвращает ИСТИНА, если значение слева меньше значения справа или равно ему: 3 <= 5 будет ИСТИНА, 3 <= 1 будет ЛОЖЬ, 3 <= 3 будет ИСТИНА

= =

var1 = = var2

возвращает ИСТИНА, если значение слева равно значению справа: 3 = = 5 будет ЛОЖЬ, 3 = = 3 будет ИСТИНА

!=

var1 != var2

возвращает ИСТИНА, если значение слева не равно значению справа: 3 != 5 будет ИСТИНА, 3 != 3 будет ЛОЖЬ

Логические операции

!

!var1

логическое отрицание: !0 будет ИСТИНА,!2 будет ЛОЖЬ

&&

var1 && var2

логическое И: 1 && 1 будет ИСТИНА, 2 && 0 будет ЛОЖЬ

||

var1 || var2

логическое ИЛИ: 1 || 1 будет ИСТИНА, 2 || 0 будет ИСТИНА, 0 || 0 будет ЛОЖЬ

Побитовые операции

~

~var

побитовое отрицание – нули меняются на единицы и наоборот: ~1011 будет 0100

<<

var1 << var2

сдвиг влево на указанное количество битов: 1011 << 2 будет 1100

>>

var1 >> var2

сдвиг вправо на указанное количество битов: 1011 >> 2 будет 0010

&

var1 & var2

побитовое И: 1011 & 1010 будет 1010

|

var1 | var2

побитовое ИЛИ: 1011 | 1010 будет 1011

^

var1 ^ var2

побитовое ИСКЛЮЧИТЕЛЬНОЕ ИЛИ: 1011 ^ 1010 будет 0001

Операции присваивания

=

var1 = var2

переменной слева присваивается значение справа: var = 5 будет 5; возможно многократное присваивание, которое выполняется справа-налево: var1 = var2 = 5

*=

var1 *= var2

умножает значение переменной, указанной слева, на значение указанное справа: var = 5, var *= 2 будет 10

/=

var1 /= var2

делит значение переменной, указанной слева, на значение, указанное справа: var = 6, var /= 2 будет 3

+=

var1 += var2

добавляет значение, указанное справа, к значению переменной, указной слева: var = 6, var += 2 будет 8

–=

var1 –= var2

отнимает от значение переменной, указанной слева, значение, указное справа: var = 6, var –= 2 будет 4

%=

var1 %= var2

присваивает переменной, указанной слева, остаток, получаемый в результате деления исходного значения этой переменной на значение, указанное справа: var = 6, var %= 4 будет 2

&=

var1 &= var2

выполнение поразрядной операции И с присвоением полученного результата переменной, указанной слева: var = 0, var &= 1 будет 0

|=

var1 |= var2

выполнение поразрядной операции ИЛИ с присвоением полученного результата переменной, указанной слева: var = 0, var |= 1 будет 1

^=

var1 ^= var2

выполнение поразрядной операции ИСКЛЮЧИТЕЛЬНОЕ ИЛИ с присвоением полученного результата переменной, указанной слева: var = 10, var ^= 2 будет 8

>>=

var1 >>= var2

выполняет сдвиг вправо значения переменной, указанной слева, на число битов, равное значению, указанному справа: var = 8, var >>= 2 будет 2

<<=

var1 <<= var2

выполняет сдвиг влево значения переменной, указанной слева, на число битов, равное значению, указанному справа: var = 8, var <<= 2 будет 32

Адресные операции

&

&var

возвращает адрес переменной var

*

*p_var

обращается к переменной c заданным адресом p_var

Операции над массивами

[]

var[i]

обращается к i-му элементу массива: mass[0] – обращаемся к первому элементу маасива

Операции над структурами и объединениями

.

var.f

обращается к полю f структурированной переменной var

->

p_var->f

обращается к полю f, если известен адрес (p_var) структурированной переменной

Прочие операции

? :

exp1 ?

exp2 : exp3

условная операция – если истинно выражение exp1, то выполняется выражение exp2, иначе выполняется выражение exp3: (x > y)? x : y – определение максимума

sizeof

sizeof(var)

sizeof(<type>)

возвращает размер памяти в байтах, занимаемый переменной или типом данных: sizeof(short int) будет 2;

short int mass[100], sizeof(mass) будет 200

Рассмотрим некоторые операции более подробно.

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

Рассмотрим пример использования префиксной и постфиксной форм операций ++ и --:

int x= 5;

int y= 60;

x++; // результат оператора выражения: x= 6

++y; // результат оператора выражения: y= 61

printf(“x= %d, y= %d\n”, x, y); // x= 6, y= 61

printf(“x= %d, y= %d\n”, x++, ++y); // x= 6, y= 62

Используя логические операции, нужно помнить, что в языке Си число 0 соответствует логическому значение ЛОЖЬ, а любое другое целочисленное значение – ИСТИНА. Ниже приведен пример такого подхода:

int a= 3;

int x;

x= a - 5; // x = -2

if(x) printf(“TRUE”); // будет распечатано “TRUE”

else printf(“FALSE”);

Побитовые операции (&,|,^,~,>>,<<) применяются только к целочисленным операндам и работают с их двоичными представлениями. При выполнении операций операнды анализируются побитово. Пример такой операции приведен ниже:

&

10000001

=129

01111111

=127

00000001

=1

Операции побитового сдвига (>>,<<) эквивалентны операции целочисленного деления/умножения числа на 2. Например:

3

<< 1

6

00000011

00000110

7

>> 2

1

00000111

00000001

Операция условия (?:) – тренарная, т.е. имеет три операнда. Ее формат:

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

Первый операнд оценивается с точки зрения его эквивалентности нулю (операнд, равный нулю, рассматривается как ЛОЖЬ, не равный нулю – как ИСТИНА). Если результат вычисления операнда 1 равен ИСТИНА, то результатом условной операции будет значение второго операнда, иначе – третьего операнда. Пример использования операции условия:

max= (x > y) ? x : y; // определение максимума двух чисел x и y

Окончание занятия №14 (лекция)

Рассмотренные выше операции имеют следующие приоритеты:

Приоритет

Операторы

Высший приоритет

[] () . ->

++ –– ~ ! & * sizeof

* / %

+ –

>> <<

< <= > >=

= = !=

&

^

|

&&

||

? :

Низший приоритет

= *= /= %= += –= <<= >>= &= ^= |=

Преобразование типов в выражениях

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

Ниже приведены правила для автоматического приведения типов при вычислении арифметических выражений.

1. Все переменные типа char и short int преобразуются в int, все переменные типа float преобразуются в double.

2. Для любой пары операндов: если один из операндов long double, то и другой преобразуется в long double; если один из операндов double, то и другой преобразуется в double; если один из операндов long, то и другой преобразуется в long; если один из операндов unsigned, то и другой преобразуется в unsigned.

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

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

int A;

A= 3/2; // A = 1 – дробная часть отбрасывается

Пример автоматического преобразования типов в выражениях:

char c;

int i;

float f;

double d;

long double r;

r = c * 2 + (i - 0.5) + (f + d) - 7

| char int int double float double int

| | | | | | | |

| int int double double double double |

| \ / \ / \ / |

| int double double double

| | | \ /

| | double double

| | \ /

| | \ /

| double double

| \ /

| \ /

long double  double

Возможно явное приведение типов по требованию программиста, используя следующую конструкцию: (тип)выражение

Примеры явного приведения типов:

float result;

float x= 5.9;

result= (int)x/2; // result= 2.0

result= (int)(x/2); // result= 2.0

result= (int)x/2.0; // result= 2.5

result= (int)(x/2.0); // result= 2.0

Окончание занятия №15 (практика)