Академический Документы
Профессиональный Документы
Культура Документы
{
<Список описаний>
<Список операторов> (1)
}
В формуле (1), если отсутствует тип значений функции, то по
умолчанию используется int. Конструкция в [] может присутствовать
или отсутствовать.
Список описаний и список операторов – это последовательность
операторов языка Си. Каждый оператор Си завершается ; (хотя в
некоторых случаях синтаксис этого не требует). Встречаются
ситуации, когда в программе отсутствует – ; и нет предупреждения
транслятора.
Каждый оператор в свою очередь – это последовательность более
мелких единиц программы – «лексем».
Лексема – минимальная единица программы, наделенная смыслом.
В Си множество лексем разбито на группы:
1. Ключевые слова - зарезервированы (выделены жирным шрифтом).
2. Символы – разделители ( , ; < > ).
3. Идентификаторы – последовательность латинских букв и цифр,
начинающаяся с буквы (в этой последовательности можно использовать -).
Длина меньше или равна 16 или 32. Строчные и прописные буквы
различаются, Константы записываются большими, переменные маленькими
буквами.
4. Константы.
5. Комментарии.
6. Невидимые символы (перевод строки и т.д.).
Комментарий является разделителем лексем, он допускается в любом
месте, где разрешено использовать пробел . В Си длина одной строки
программы не определена. Практически она реализуется длиной
строки редактора. Строковую константу языка Си нельзя переносить
на другую строку. Невидимые символы – это, большей частью,
символы редактирования, такие как пробел, табуляция, возврат
каретки, конец файла ( вставляется редактором). Обязательно
следует разделять между собой пары лексем из 1ой и 3ей групп.
Любой оператор языка Си может начинаться с любой позиции любой
строки. Ни одна лексема, кроме комментариев (только для Си) не
может продолжаться на следующей строке. Там где уместен пробел,
можно записать комментарий или любую последовательность
невидимых символов.
Тело функции (1) состоит из двух списков: список описаний (операторы
описания) и список операторов описывающий действия ( операторы действий).
Рассмотрим синтаксис и семантику операторов действия (=> - это):
Список операторов => Оператор (2.1)
=> Оператор Список операторов (2.2)
=>switch (выражение)
{
сase константное выражение 1: Оператор1
…
case константное выражение n: Оператор n
default: Оператор1
} (3.8)
=> break; (3.9)
=>continue; (3.10)
=> return; (3.11)
=> return выражение; (3.12)
=> goto Метка; (3.13)
=> Метка: Оператор (3.14)
=> ; (3.15)
Метка => Идентификатор
(3.16)
Оператор1 => пусто
=> Список операторов (3.17)
Составной оператор => { [Список описаний]
[Список операторов]
} (4).
Из формул (2.1), (2.2) следует, что Список операторов состоит из
одного или нескольких Операторов действия. Из формул (3.1) и (4) –
совокупность Операторов описания и Операторов действия
заключенная в фигурные скобки есть Составной оператор, который
принято считать одним Оператором действия. Составной оператор и
Операторы (3.3) – (3.8) имеют не тривиальную
структуру(конструкторы), а Операторы (3.2) и (3.9) – (3.15) можно
отнести к элементарным.
3.Семантика операторов - конструкторов
Выражение1;
while (Выражение2)
{оператор
Выражение3 ; (5)
}
Если отсутствует первое и третье выражение, то семантика оператора цикла
задана формулой (5), в которой опущены операторы выражение1 и выражение 3,
если отсутствует выражение2, то вместо него по умолчанию используется
константа, равная единице.
3.2.Оператор SWITCH
Замечание к синтаксису:
Вариант default может находиться в любом месте, а не только на последнем.
Семантика:
Вычисляется выражение после switch.
Его значение сравнивается со значениями константных выражений в
порядке их следования. Если ни одно значение в опции case не
совпадает со значением выражения, то если присутствует вариант
default, то выполняется его оператор, иначе – ни один оператор
switch не выполняется. Если значение некоторого константного
выражения совпало со значением выражения, то выполняется
оператор данного варианта.
Если в операторе switch выполнился кокой либо вариант, в том числе
и default, то следующими выполняются все ниже лежащие варианты.
Чтобы обеспечить выполнение только одного варианта нужно
использовать оператор break.
Тип выражения switch – int.
Пример:
int a, b, c ;
if (a= =b)
a+=b;
if (a>b)
{a--; b++;}
else {++a; --b;}
while (c==(a=b))
c=a/b;
do
c/=2;
while(c);
Оператор break – прерывает выполнение таких конструкторов как while, do while, for и
switch.
while (1)
{…
if (a==b) break;
…
}
s=0.0; i=4;
do
if (i) {s=s+1./i; i=i-1;}
else break;
while (s<=a);
s=0.0; i=4;
do
if (i)
s+=1.0/i--;
else
break;
while (s<=a);
do
if (i--)
s+=1.0/i;
else
break;
while(s<=a) ;
for (i=4,s=0; s<=a; s+=1.0/i--)
if(!i) break;
…goto M3;
…goto M2;
…gotoM1;
M1: …
…
M2: …
…
M3:…
Другие варианты нежелательны, но допускаются. Уместное использование
goto:
1) ясность программы не уменьшается;
2) программа сокращается.
Правильное использование goto- это показатель уровня квалификации
программиста.
Пустой оператор - используется там, где не требуется никаких действий.
for (i=1, s=0.0; i<=100; s+=i*i++);
Других операторов действий в Си нет. Все остальные действия типа:
ввода и вывода, открытия и закрытия файлов, математических операций,
работы со строками - реализованы через соответствующие библиотеки (в
виде библиотек функций или классов).
5.Операция присваивания
Адрес имя
b: c: d:
С: Х
<адрес х>
Если левый операнд для операции присваивания выражен именем
переменной, то транслятор понимает это как адрес переменной.
Здесь неявно присутствует операция разыменования (определения
адреса по имени).
Семантика:
1. Вычисляется значение выражения.
2. Вычисляется адрес левого оператора.
3. Выполняется присваивание в зависимости от вида операции.
Операция присваивания => = | += | –+ | *= | /= | %= | >>= | <<= |
&= | ^= | |=
( | - или)
Выражение :
Адрес *= выражение тождественно Адрес = значение
(адрес)*выражение
Примеры:
x=5.3
y*=(x+5); тождественно y=у*(х+5)
у*=х+5; тождественно у=у*х+5
сhar = [-128, 127] signed short int unsigned short int (от 0 до 216-1)
signed char = [-128, 127] signed int unsigned int (от 0 до 216-1)
unsigned char = [0, 255]. signed long int unsigned long int (от 0 до 232-1)
7.Унарные операции
Семантика:
Любой массив Си –вектор своих компонентов. Индекс по каждой
размерности начинается с 0.
Z0 Z19
Вектор z.
X0
X1
X9
Двухмерный массив X.
Y0
Y1
Y14
Трехмерный массив Z.
Список инициализации представляет собой последовательность однородных
инициализирующих списков, каждый список заключается в “{}”, и только для
одномерных векторов его список инициализации представлен списком значений.
Элементы списка инициализации отделяются друг от друга запятой.
Примеры:
сhar z [20] = {‘M’, ‘A’, ‘Ш’, ‘A’, ‘_’, ‘К’ ,‘У’, ‘П’, ‘И’, ‘Л’, ‘А’, ‘Ш’, ‘Л’, ‘Я’,
‘П’, ‘К’, ‘У’, ‘_’, ‘!’};
int y [15] [5][4]=
{{{1,1,1,1},{2,2,2,2},{3,3,3,3},{4,4,4,4},{5,5,5,5}},…,{{…},{…},{…},{…},
{75,75,75,75}}};
Не все элементы массива можно инициализировать, но для пропущенного
элемента инициализации его запятая в списке сохраняется, если она (они) не в
конце списка.
int y [10]= {1,2,,,,6,7}-инициализированы первый , второй , шестой и
седьмой элементы. При объявлении массива в [] можно ничего не указывать,
если присутствует список инициализации.
Пример:
В памяти .
Принципиально структура памяти для массива z=[20] и стринговой константы
одна и та же – последовательность смежных байтов. И то и другое - оба массивы.
В Си нет операции над строками как над единым целым, даже операции
присваивания.
Нельзя записать
х= “ошибка#1”;
Её можно только инициализировать
char x [20] = “ это правильно”;
char y[]=”это тоже правильно”;
Символьные (или литерные) константы: ’литера’ – и гарантировано, что литеры с кодом 0-127
принадлежат стандартной таблице ASCII.
В различных компиляторах коду от 128 до 255, если данные типа unsigned char, или, что то же
самое, код от -127 до -1, если данное типа signed char могут соответствовать различные символы,
это зависит как от транслятора (компилятора), так и от драйверов клавиатуры.
Пусть некоторая литера имеет внутренний код 10000000 и он присвоен переменной lit. В
зависимости от того какому типу принадлежит lit имеем следующее число, если char lit ≡ signed
char lit, то lit=(100000002)со знаком следовательно 10000000 – 1 - получили обратный код
01111111 для числа 10000000 2 =12710 следовательно lit=-127, если unsigned char lit, то
}
Следующий пример - преобразование литер латинского алфавита с нижнего регистра на
верхний:
main()
{char lit;
for (lit='a';lit<='z';lit++)
cout<<”строчная литера”<<lit<<”прописная”<<lit+’A’-‘a’;
}
В этом примере имеет место следующее преобразование типов:
lit='a'- проходит без преобразования,
lit<='z' => int,
lit++ тождественно lit=lit+1}=> int => char,
то же самое происходит при вычислении lit+'A'-'a'.
В этом примере числовые значения литер используются для определения расстояния между
ними.
12.Числовые и целые константы
Целочисленную константу Си можно изобразить в трех системах счисления(СС)
– десятичной, восьмеричной и шестнадцатеричной.
В каждой системе счисления константы имеют следующую структуру
изображения –
[признак системы счисления]последовательность цифр систем
счисления[суффикс длинны и знака]
а) признак десятичной СС - константа начинается с десятичной цифры, но не
нуля;
б) признак восьмеричной СС - константа начинается с 0;
в) признак шестнадцатеричной СС - константа начинается с 0x или 0X.
Суффикс длинны L или l, суффикс знаки u или U .
Если константа не имеет суффикса, то она принадлежит int, если ее значение
принадлежит int, иначе long int. Все константы без знака. Отрицательных
констант не существует, -57 - это не константа, а выражение.
Пример:
В десятичной СС 5 - это int , а 55555 - long int .
В восьмеричной СС 05 - int, 055555==5*84+5*83+5*82+5*8 +5= |101|101|101|
101|101| - int.
В шестнадцатеричной СС 0x55555 - long int .
Если константа имеет суффикс l , то у нее тип (ее значение) принадлежит long
int, а если u - unsigned int , или unsigned long int, если суффикс – ul.
Пример:
57ul принадлежит unsigned long.
5710=7*8+1=0718=3*16+9=0х3916
Восьмеричные и шестнадцатеричные представления используются редко для
задач числового плана, но в системном программировании это не редкость.
13. Поразрядные логические операции
Пусть каким-то образом закодировано некоторое множество элементов,
Например:
{a1, a2, …, an} n<=32, пусть n=32.
Если a1, а2, …, аn – это стол, стул, табуретка и т.д., то изобразить эти элементы
невозможно. В Си нет операций над множествами (нет множественного типа),
Если X – множество из n элементов, а B включено в Х, то характеристический
вектор множества B – h(B) называется цепочка из 0 или 1, при этом 1 в этой
цепочке стоит на i-том месте тогда и только тогда, когда xi принадлежит B, где
0005
- (похоже на вычитание)
0004
0001
Но
32 ۸ 31=63 =>
10 0000
1 1111 - (похоже на сложение)
11 1111
~0 => 1
~1 =>0
Определить какие элементы не входят во множество А – ответ ~h(A).
Приоритет побитовых операций:
1) ~
2) &
3) ^
4) |
}
}
return (h);
}
Например, если номера - 1 5 3 14 15, то имеем:
Нумерация:
32 … 15 14 … 5 3 1
… 1 1 … 1 1 1
31 … … 4 3 2 1 0
нумерация
15.Функции, моделирующие операцию над множествами
Объединения множеств:
unsigned long int union–set (unsigned long int A, unsigned long
int B)
{return (A|B);
}
Пересечения множеств:
unsigned long int common–set (unsigned long int A, unsigned
long int B)
{return (A&B);
}
16. Маски
Логические операции часто нужны для выделения групп битов.
А восьмеричные и шестнадцатеричные константы используются
для создания масок:
Пример 1:
В битовом представлении некоторого числа выделить группу
битов с четвертого по седьмой включительно, считая слева на
право.
4-7 бит
0 0 F 0
Построим маску int mas; – константу, с помощью которой
выделяется группа битов.
тогда int result = n&0xF0;
Операция & для маски - сбрасывает в нули все разряды
соответствующие нулевым разрядам маски и оставляет без
изменения разряды соответствующие единичным разрядам маски.
Пример 2:
В битовом представление некоторого числа устанавливается 1 в
знаковом разряде (пусть int - 2 байта) остальные остаются без
изменений.
int result = 0x8000| (n&0x7FFF)
(выделить знак)
0 0 0
1 0 1
0 1 1
1 1 0
17.Операции сдвигов разрядов
Синтаксис
[целая часть] [дробная часть] [степень] [суффикс] , где
а)может отсутствовать дробная часть, но тогда присутствует степень;
б) может отсутствовать целая часть и степень;
в) может отсутствовать степень, но тогда должна быть точка.
Примеры:
5. 5.0
.03 0.003 – правильная форма записи.
19.Логические выражения
0 1 0 0
1 0
Пример:
a=(a= =b)?a:b – а присваивается значение а, если а равно b или b в противном
случае;
a=(a>b)?((a>c)?a:c):(b>c)?b:c – а присваивается наибольшее изтрех a, b, c .