Выражение и его интерпретация
Выражение в языке С++ – это последовательность операндов, операций и символов-разделителей. Операнды – это переменные, константы либо другие выражения. Разделителями в С++ являются символы [ ] () { },;: … * = #, каждый из которых выполняет свою функцию. Выражение может состоять из одной или более операций и определять выполнение целого ряда элементарных шагов по преобразованию информации. Примеры выражений: (a + 0.12)/6 x && y ||!z (t * sin(x)-1.05)/((2 * k + 2) * (2 * k + 3)) Компилятор соблюдает строгий порядок интерпретации выражений, называемый правилами предшествования. Этот порядок может быть изменен, если отдельные части выражения заключить в круглые скобки. Элементарная операция по преобразованию информации задается знаком операции. По числу операндов, участвующих в операции, различают следующие типы: - унарные (имеющие один операнд); - бинарные (имеющие два операнда); - тернарные (имеющие три операнда). По типу выполняемой операции различают: - арифметические операции; - операции отношения; - логические операции; - операции с разрядами; - операции сдвига; - операцию условия; - операцию присваивания; - операцию sizeof; - операцию преобразования типов. Арифметические операции Язык С++ (С) включает: · арифметические операции сложения (задается знаком +), вычитания и унарный минус (–), умножения (*), деления (/), операцию определения остатка (%); · операции инкремента (++) и декремента (--). Операции сложения, вычитания, умножения и деления являются стандартными и выполняются так же, как и в большинстве других алгоритмических языках. Операция определения остатка (%) (или деления по модулю) служит для определения остатка от деления числа целого типа, стоящего слева от знака, на целое число, расположенное справа от знака. Ее поясняет следующий пример:
int x=7, y=3, z; z=x%y; // z=1 – остаток от целого деления 7/3 z=x/y; // z=2 – результат деления целых чисел Операции инкремента и декремента соответственно увеличивают и уменьшают операнд на 1. Операции ++ и -- могут применяться только к переменным. Используются две формы их записи: префиксная (знак операции располагается слева от операнда) и постфиксная (знак операции справа от операнда). В префиксной форме сначала выполняется увеличение операнда на 1, и увеличенное значение используется в выражении. В постфиксной форме сначала берется значение операнда, и только после этого его значение увеличивается на 1. Например: int x=0, y=1, z=0; z=x++; // в результате z=0, x=1 z=++x; // z=2, x=2 z=++y; // z=2, y=2 Форма записи операций ++ и -- сказывается в составных выражениях. Например, три оператора присваивания вида number=number+1; sum=sum+1; x=x+1; могут быть записаны более кратко number+=1; sum+=1; x+=1;, а с использованием операций инкремента в префиксной форме: ++number; ++sum; ++x; или в постфиксной форме: number++; sum++; x++; Операции отношения С++ поддерживает следующие операции отношения: · > – больше; дает результат 1, если операнд слева от знака больше операнда справа; в противном случае дает 0; · < – меньше; дает результат 1, если операнд слева меньше операнда справа; в противном случае дает 0; · = = – равно; дает результат 1, если операнд слева от знака равен операнду справа; в противном случае дает 0; · >= – больше или равно; дает результат 1, если операнд слева от знака больше или равен операнду справа; в противном случае дает 0; · <= – меньше или равно; дает результат 1, если операнд слева от знака меньше или равен операнду справа; в противном случае дает 0; · != – не равно; дает результат 1, если операнд слева от знака не равен операнду справа; в противном случае дает значение 0.
Операнды могут быть арифметического типа или указателями. Операции сравнения на равенство и неравенство имеют меньший приоритет, чем остальные операции сравнения. При сравнении float (вещественных величин) лучше пользоваться только операциями < и >, т.к. ошибки округления могут привести к тому, что числа окажутся неравными, хотя по логике они должны быть равны (например, 3*1/3 равно 1,0, но 3*1/3 в вещественном формате будет представлена как 0,999999…, и произведение не будет равно 1). Логические операции Логические операции и операции отношения используются при формировании логических выражений, имеющих только два значения: 1, если логическое выражение ИСТИННО; 0, если логическое выражение ЛОЖНО. Логические выражения наиболее часто используют вместе с операторами управления потоком вычислений – операторами циклов и ветвлений. С++ поддерживает следующие логические операции: · && – логическое И; дает результат 1 (ИСТИНА), если все операнды имеют значение 1 (ИСТИНА); в противном случае дает значение 0 (ЛОЖЬ); · || – логическое ИЛИ; дает результат 1 (ИСТИНА), если хотя бы один из операндов имеет значение 1 (ИСТИНА); в противном случае дает значение 0 (ЛОЖЬ); ·! – логическое НЕ; дает результат 1 (ИСТИНА), если операнд справа от знака имеет значение 0 (ЛОЖЬ); в противном случае дает значение 1 (ИСТИНА). Возможные результаты выполнения логических операций представлены в таблице 4. Таблица 4. Логические операции
Операнды логических выражений вычисляются слева направо. Если значения первого операнда достаточно, чтобы определить результат операции, то второй операнд не вычисляется. Логические операции не вызывают стандартных арифметических преобразований. Они оценивают каждый операнд с точки зрения его эквивалентности нулю. Результатом логической операции является 0 или 1, тип результата int. Операции с разрядами Поразрядные логические операции приводят к изменению значения переменной. Действия производятся над данными целого и символьного типа. Они называются поразрядными, потому что они выполняются отдельно над каждым разрядом независимо от разряда, находящегося слева или справа.
· ~ – поразрядное НЕ – дополнение до 1 или поразрядное отрицание. Это унарная операция изменяет каждую 1 на 0, а 0 на 1. ~(11010) получим (00101) · & – поразрядное И служит для сбрасывания битов. Эта бинарная операция сравнивает последовательно разряд за разрядом два операнда. Результат равен 1, если оба соответствующих разряда операндов равны 1. (10010011) & (00111101) => (00010001) · | – поразрядное ИЛИ служит для установки битов. Эта бинарная операция сравнивает последовательно разряд за разрядом два операнда. Результат равен 1, если один (или оба) из соответствующих разряда операндов равен 1. (10010011) | (00111101) => (10111111) · ^ – поразрядное Исключающее ИЛИ. Результат равен 1, если один из разрядов равен 1 (но не оба). (10010011) ^ (00111101) => (10101110) Операции сдвига Операции сдвига осуществляют поразрядный сдвиг операнда. Величина сдвига определяется значением правого операнда. Сдвигаемые разряды теряются. При сдвиге вправо знаковый разряд размножается. · << – сдвиг влево. Разряды левого операнда сдвигаются влево на число позиций, указанное правым операндом. Освобождающиеся позиции заполняются нулями, а разряды, сдвигаемые за левый предел левого операнда, теряются. (10001010)<<2 = = 1000101000 · >> – сдвиг вправо. Разряды левого операнда сдвигаются вправо на число позиций, указанное правым операндом. Разряды, сдвигаемые за правый предел левого операнда, теряются. Для беззнаковых чисел освобожденные слева разряды заполняются нулями. Для чисел со знаком левый разряд принимает значение знака. (10001010)>>2 = = 00100010 Эти операции выполняют эффективное умножение и деление на степени 2: number<<n – умножает number на 2 в n -й степени number>>n – делит number на 2 в n -й степени Операция условия В языке C++ имеется одна тернарная операция – условная операция, которая имеет следующий формат: операнд_1? операнд_2: операнд_3 Операнд_1 должен быть целого или плавающего типа или быть указателем. Он оценивается с точки зрения его эквивалентности 0. Если операнд_1 не равен 0, то вычисляется операнд_2, и его значение является результатом операции. Если операнд_1 равен 0, то вычисляется операнд_3, и его значение является результатом операции. Следует отметить, что вычисляется либо операнд_2, либо операнд_3, но не оба.
Операцию условия удобно использовать, когда имеется некоторая переменная, которой можно присвоить одно из двух возможных значений. Примеры: · x = (y<0)? –y: y; означает, что если у меньше 0, то х=-у, в противном случае х=у. · max = (a>b)? a: b; переменной max присваивается максимальное значение из переменных a и b. Условные выражения компактны и приводят к получению более компактного машинного кода. Операция присваивания Язык С++ имеет несколько особенностей выполнения операции присваивания. Помимо простого присваивания посредством операции "=", С++ поддерживает составные операции присваивания, которые перед присваиванием выполняют дополнительные операции над своими операндами. Формат операции простого присваивания (=): операнд1 = операнд2; Сначала вычисляется выражение, стоящее в правой части операции, а потом его результат записывается в область памяти, указанную в левой части. Например: int a=3,b=5,c=7; //Результаты работы фрагмента программы: a=b;b=a;c=c+1; // a=5;b=5;c=8. Операция составного присваивания состоит из простой операции присваивания, скомбинированной с другой бинарной операцией. В составном присваивании вначале выполняется операция, специфицированная аддитивным оператором, а затем результат присваивается левому операнду. Выражение составного присваивания, например, имеет вид операнд1 += операнд2 и может быть понято как операнд1 = операнд1 + операнд2 Однако выражение составного присваивания неэквивалентно расширенной версии, поскольку в выражении составного присваивания операнд1 вычисляется только один раз, в то время как в расширенной версии оно вычисляется дважды: в операции сложения и в операции присваивания. В общем случае формат операции составного присваивания можно представить так: операнд1 (бинарная операция) = операнд2, где (бинарная операция) – одна из операций, задаваемых знаками *, /, +, -, %. Результатом операции составного присваивания являются значение и тип левого операнда. Например: a += b; // a = a + b; a -= b; // a = a - b; a *= b; // a = a * b; a /= b; // a = a / b; a %= b; // a = a % b; Операция sizeof С помощью операции sizeof можно определить размер памяти, которая соответствует идентификатору или типу. Она имеет следующий формат: sizeof (выражение) В качестве выражения может быть использован любой идентификатор (кроме имени функции), либо имя типа, заключенное в скобки. Если в качестве выражения указано имя массива, то результатом является размер всего массива (т.е. произведение числа элементов на длину типа). Результатом операции sizeof является размер в байтах типа или объявленной переменной, а применительно к массивам операция возвращает число байтов, необходимое для размещения всех элементов массива. Если определяется размер переменной, то имя переменной можно также указывать через пробел после sizeof без круглых скобок.
Преобразование типов Результат вычисления выражения характеризуется значением и типом. Операнды бинарной операции могут быть разного типа. В этом случае перед ее выполнением компилятор предварительно приводит операнды к одному типу. Преобразование типов выполняется по следующим правилам: 1) операнды разных типов приводятся к “старшему”, т.е. более длинному типу. Ниже перечислены типы в порядке убывания старшинства: самый старший – long double, double, float, unsigned long, long int, unsigned int, char – самый младший; 2) при выполнении операции присваивания результат приводится к типу переменной слева от знака операции. Явное приведение типа операндов выполняется с помощью операции type(expression);, где type – любой допустимый тип языка С++. Результатом операции type(expression) является значение выражения expression, преобразованное к типу type. Пример: … int x; float y=1.6; … x = int(5.2) + int(y); … В результате выполнения данного фрагмента программы получим x =6. Преобразование младшего (меньшего по размеру типа) к старшему происходит корректно, а старшего к младшему может вызвать затруднения (все число может не поместиться в выделенной под него области памяти, и тогда результат операции будет не верный).
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|