
- •Программирование на языках высокого уровня. Алгоритмические языки
- •Содержание
- •Разработка (проектирование) одномодульных программ
- •Представление информации в языке Си
- •Массивы
- •УказатеЛи
- •Выражения и операции
- •Управляющие операторы
- •Функции
- •Типы данных, определяемые пользователем
- •Приемы программирования
- •Приложение 2. Арифметические основы компьютеров
- •Литература
Выражения и операции
Выражения
В любой программе требуется производить вычисления. Для вычисления значений используют выражения, которые состоят из операндов, знаков операций и скобок. Операции задают действия, которые необходимо выполнить. Каждый операнд является, в свою очередь, выражением или одним из его частных случаев, например, константой или переменной.
Рассмотрим примеры выражений:
Выражения |
Использованные операции |
Операнды |
(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 (практика) |