21. Аддитивные операции обычны.
22. Бинарная операция сдвига используется для двух аргументов только целого типа. Левый аргумент надо преобразовать к двоичному виду. Правый аргумент указывает, на сколько бит необходимо произвести сдвиг.
При сдвиге влево x << y левые биты числа x пропадают, новые биты справа заполняются нулями. Операция x << y равносильна умножению x × 2y.
23. При сдвиге вправо x >> y правые биты числа x пропадают, новые биты слева заполняются знаком числа x. Если x отрицательно, то новые биты равны 1, при положительном х новые биты равны 0. Операция x >> y равносильна делению нацело x / 2y.
Пример.
char x = 20, y = -10;
unsigned char z = 20;
Тогда x >> 2 = 0001 01002 >> 2 = 0000 01012 = 5
x << 2 = 0001 01002 << 2 = 0101 00002 = 80
x << 3 = 0001 01002 << 3 = 1010 00002 = 160 – 256 = -94 – логическая ошибка выхода за диапазон типа char
y >> 3 = 1111 01102 >> 3 = 1111 11102 = -2
z >> 3 = 0001 01002 >> 3 = 0000 00102 = 2
24-26. Операции отношения и сравнения обычны. В случае истины они возвращают 1, при нарушении возвращают 0.
27-29. Побитовые операции применяются для целых аргументов.
Таблица 4.
Таблицы истинности
& | 0 | 1 | ^ | 0 | 1 | | | 0 | 1 | ||
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | ||
1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
Пример.
7 & 9 = 0000 0111 & 0001 0001 = 0000 00012 = 1
7 ^ 9 = 0000 0111 ^ 0001 0001 = 0001 01102 = 22
7 | 9 = 0000 0111 | 0001 0001 = 0001 01112 = 23
30-31. Логические операции возвращают 1 (истину) или 0 (ложь).
Компилятор оптимизирует логические выражения таким образом, что если по результату вычисленного подвыражения можно сделать вывод относительно результата всего выражения, то дальнейшее вычисление выражения не выполняется.
Пример.
7 && 9 = 1
32. Операция «Условие» позволяет иногда заменить условный оператор if-else на операцию.
Пример. Максимальное из двух чисел равно max = (x > y) ? x : y;
Максимальное из трех чисел равно
max = (x > y) ? ( x > z ? x : z) : ( y > z ? y : z);
33. Результатом присваивания является значение того, что присвоено левому аргументу.
34. Комбинированное присваивание x op = y является компактной записью оператора x = x op y. Однако компилятор эту замен не производит. Комбинированное присваивание является отдельной операцией.
35. «Запятая» является, пожалуй, самой экзотической операцией языка Си. Результатом выражения x,y является число y.
Пример.
x = 2,5; // x = 2, так как присваивание сильнее запятой
x = (2,5); // x = 5
По-видимому, здесь хотели написать x=2.5
Правила преобразований типов В выраженияхЕсли операнд имеет тип не int и не double, то сначала приводится:
- signed char --> int расширением знакового бита (7)
- unsigned char --> int дополнением нулями слева
- short --> int расширением знакового бита (15)
- unsigned short --> unsigned int дополнением нулями слева
- enum --> int порядковый номер в перечислимом типе
- float --> double дробная часть дополняется нулями
Если какой-нибудь операнд имеет тип double, unsigned long, long или unsigned int то и другой операнд приводится к тому же типу. Результат: того же типа.
Если оба операнда имеют тип int, то результат тоже типа int.
При вызове функций их аргументы – тоже выражения, поэтому в них приводятся char,short к int и float к double. Это говорит о том, что аргументы (формальные параметры) функций можно всегда объявлять как int и double вместо char,short и float соответственно.
Зато спецификатор unsigned является существенным.
В присваиванияхop = expr;
Тип выражения expr приводится к типу левой части – op. При этом возможны приведения более "длинного" типа к более "короткому" при помощи усечения, вроде:
- int --> char обрубается старший байт.
- long --> int обрубается старшее слово.
- float --> int отброс дробной части
- double --> int и обрубание мантиссы, если не лезет.
- double --> float округление дробной части.
Вот еще некоторые приведения типов:
- signed --> unsigned виртуально (просто знаковый бит
- unsigned --> signed считается значащим или наоборот).
- unsigned int --> long добавление нулей слева.
- int --> long расширение знакового бита.
- float --> int преобразование внутреннего.
- int --> float представления: машинно зависимо.
Некоторые преобразования могут идти в несколько стадий, например:
- char --> long это
- char --> int --> long
char --> unsigned long это
- char --> int --> unsigned long
Что напечатает следующая программа?
#include <stdio.h>
main()
{
int x;
x= -3 + 4 * 5 - 6; printf("%d\n",x);
x= 3 + 4 % 5 - 6; printf("%d\n",x);
x= -3 * 4 % - 6 / 5 ; printf("%d\n",x);
x= (7 + 6) % 5 / 2 ; printf("%d\n",x);
return 0;
}
Операции присваивания.Что напечатает следующая программа ?
#include <stdio.h>
#define PRINTX printf("%d\n",x)
main()
{
int x=2,y,z;
x *= 3 + 2; PRINTX;
x *= y = z =4 ; PRINTX;
x = y == z; PRINTX;
x == (y = z); PRINTX;
return 0;
}
Логические операции и операции инкремента.
Что напечатает следующая программа ?
#include <stdio.h>
#define PRINT(int) printf("%d\n",int)
main()
{
int x,y,z;
x=2; y=1; z=0;
x = x && y || z; PRINT(x);
PRINT(x || ! y && z);
x=y=1;
z = x ++ - 1; PRINT(x);
PRINT(z);
z += - x ++ + ++ y; PRINT(x);
PRINT(z);
z = x / ++ x; PRINT(z);
return 0;
}
Поразрядные операции.Что напечатает следующая программа ?
#include <stdio.h>
#define PRINT(int) printf("%d\n",int)
main()
{
int x,y,z;
x=03; y=02; z=01;
PRINT( x | y & z );
PRINT( x | y & ~z );
PRINT( x ^ y & ~z );
PRINT( x & y && z );
x=1; y=-1;
PRINT( ! x | x );
PRINT( ~ x | x );
PRINT( x ^ x );
x <<= 3; PRINT(x);
y <<= 3; PRINT(y);
y >>= 3; PRINT(y);
return 0;
}
Отношения и условияЧто напечатает следующая программа ?
#include <stdio.h>
#define PRINT(int) printf("%d\n",int)
main()
{
int x=1,y=1,z=1;
x += y += z;
PRINT( x < y ? y : x );
PRINT( x < y ? x ++ : y ++ );
PRINT(x);
PRINT(y);
PRINT( z += x < y ? x ++ : y ++);
PRINT(y);
PRINT(z);
x=3; y=z=4;
PRINT( (z >= y >= x) ? 1 : 0);
PRINT( z >= y && y >=x );
return 0;
}
Выполнение операций и их приоритетыЧто напечатает следующая программа ?
#include <stdio.h>
#define PRINT(x,y,z) printf("x=%d\t y=%d\t z=%d\n",x,y,z)
main()
{
int x,y,z;
x=y=z=1;
++ x || ++ y && ++ z; PRINT(x,y,z);
x=y=z=1;
++ x && ++ y || ++ z; PRINT(x,y,z);
x=y=z=1;
++ x && ++ y && ++ z; PRINT(x,y,z);
x=y=z=-1;
++ x && ++ y || ++ z; PRINT(x,y,z);
x=y=z=-1;
++ x || ++ y && ++ z; PRINT(x,y,z);
x=y=z=-1;
++ x && ++ y && ++ z; PRINT(x,y,z);
return 0;
}
Основные типы данныхЧто напечатает следующая программа?
#include <stdio.h>
#define PRINTd(x) printf("%d\n",x);//десятичное число со знаком
#define PRINTc(x) printf("%c\n",x);//символ с ascii-кодом x
#define PRINTo(x) printf("%o\n",x);//восьмеричное число со знаком
#define PRINTs(x) printf("%s\n",x);//строковая константа
int integer =5;
char character='5';
char* string ="5";
main()
{
PRINTd(string);
PRINTd(character);
PRINTd(integer);
PRINTs(string);
PRINTc(character);
PRINTc(integer=53);
PRINTd( '5'>5 );
{
int sx=-8;
unsigned ux=-8;
PRINTo(sx); PRINTo(ux);
PRINTo( sx>>3 ); PRINTo( ux>>3 );
PRINTd( sx>>3 ); PRINTd( ux>>3 );
}
return 0;
}
Приведение целых и вещественных типовЧто напечатает следующая программа ?
#include <stdio.h>
#define PRi(x) printf("i=%.8g\t",(double)x)
#define PRl(x) printf("l=%.8g\t",(double)x)
#define PRf(x) printf("f=%.8g\t",(double)x)
#define PRd(x) printf("d=%.8g\t",(double)x)
#define NL putchar('\n')
#define PRINT4(x1,x2,x3,x4) PRi(x1);PRl(x2);PRf(x3);PRd(x4);NL
main()
{
double d;
float f;
long l;
int i;
i=l=f=d= 100/3; PRINT4(i,l,f,d);
d=f=l=i= 100/3; PRINT4(i,l,f,d);
i=l=f=d= 100/3.; PRINT4(i,l,f,d);
d=f=l=i= (double)100/3; PRINT4(i,l,f,d);
i=l=f=d= (double)(100000/3); PRINT4(i,l,f,d);
d=f=l=i= (double)100000/3; PRINT4(i,l,f,d); return 0;
}
Приведение целых и вещественных выраженийЧто напечатает следующая программа ?
#include <stdio.h>
#define NL putchar('\n')
#define PR(x) printf("%g\t",(double)x)
#define PRINT1(x1) PR(x1);NL
#define PRINT2(x1,x2) PR(x1);PR(x2);NL
main(){
double d=3.2 ,x; int i=2 ,y;
x= ( y= d/i ) *2; PRINT2(x,y);
y= ( x= d/i ) *2; PRINT2(x,y);
y= d *( x= 2.5/d ); PRINT1(y);
x= d *( y= ( (int)2.9 + 1.1 )/d );
PRINT2(x,y);
return 0;
}
Ответы к заданиям1. 11 1 0 1
2. 10 40 1 1
3. 1 1 2 0 3 0 1
4. 3 3 1 1 1 -1 0 8 -8 -1
5. 3 2 3 3 4 4 4 0 1
6. x=2 y=1 z=1 x=2 y=2 z=1
x=2 y=2 z=2
x=0 y=-1 z=0
x=0 y=0 z=-1
x=0 y=-1 z=-1
7. 175 - младший байт адреса в десятичной форме 53 5 5 5 1
sx= 177770
ux= 177770
sx>>3 = 177777 знак переносится при сдвиге
ux>>3 = 17777 знак не переносится при сдвиге
-1
8191
8. i=33 l=33 f=33 d=33 i=33 l=33 f=33
d=33
i=33 l=33 f=33.333332 d=33.333333
i=33 l=33 f=33 d=33
i=-32203 l=33333 f=33333 d=33333
i=-32203 l=-32203 f=-32203 d=-32203
9. x=2 y=1 x=1.6 y=3
y=2
x=0 y=0
Дополнительные задания1. Напишите выражение для определения суммы 0-го и 3-го битов числа int x.
2. Напишите выражение для определения количества единиц в числе char х.
3. Установить в единицу 3-ий и 5-ый биты переменной int x. Сбросить в ноль 9-ый и 13-ый биты переменной int x.
4. Что напечатает фрагмент программы
int x=100, y=7, z;
z = (x / y) % 5 * 3;
printf(“%d”, z);
5. Что напечатает фрагмент программы
int x=10, y=-70, z;
z = x << 3 + y >> 2;
printf(“%d”, z);
6. Переменная int x содержит четырехзначное натуральное число abcd. С помощью операций / и % найдите цифры a, b, c, d.
7. Найдите с помощью операций «условие» максимальное из трех чисел. Использовать только один оператор в виде max = …… ;
8. Запишите в виде одного логического выражения принадлежность точки (x, y) уpезанному единичному квадpату
Рис.1.
1. Керниган Б., Ритчи Д., Фьюэр А. Язык программирования Си: Задачи по языку Си. М.: Финансы и статистика, 1985. – 192с.
2. Керниган Б., Ритчи Д. Язык программирования Си. М.: Финансы и статистика, 1992. - 272с.
3. Подбельский В.В., Фомин С.С. Программирование на языке Си. Учеб. пособие. М.: Финансы и статистика, 2004. 600 с.
... программы на Паскале на язык СИ требует от программиста приложения значительных интеллектуальных усилий, а реализация конвертора для языка Паскаль возможна лишь при наличии существенных временных и материальных ресурсов. Помимо синтаксических ограничений входная программа конвертора имеет ряд чисто семантических ограничений, связанных с реализацией собственно конвертора. Перечислим основные из ...
... буквы из имеющихся двадцати шести букв/. 4.5. Правила, определяющие область действия. Функции и внешние переменные, входящие в состав “C”-программы, не обязаны компилироваться одновременно; программа на исходном языке может располагаться в нескольких файлах, и ранее скомпилированные процедуры могут загружаться из библиотек. Два вопроса представляют интерес: Как следует составлять описания, чтобы ...
... . Объясните, для чего служат разрешения и привилегии в Windows NT. Зав. кафедрой -------------------------------------------------- Экзаменационный билет по предмету СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ Билет № 22 Перечислите возможности и инструменты системы программирования Microsoft Developer Studio. Укажите для чего предназначается буфер в системах ввода-вывода, ...
0 комментариев