Глава 1. Базовые понятия языка 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Глава 1. Базовые понятия языка



ЯЗЫК СИ

Глава 1. Базовые понятия языка

Словарь языка СИ

 

Язык СИ оперирует со следующим набором символов:

1) большие и маленькие буквы латинского алфавита A,B,C,..., Z, a,b,c,...,z

2) арабские цифры 0,1,2,...,9;

3) Специальные символы:

“, { } [ ] () + - / % \; ‘.:?

< = > _! & * # ~ ^

4) неизображаемые символы – пробел, табуляция, переход на новую строчку;

5) В комментариях, строках и символьных константах могут использоваться другие символы (например, русские буквы).

6) комбинации специальных символов образуют составленные символы:

/* - комментарий;

/* это комментарий*/

В стандартном языке СИ комментарии запрещено вкладывать друг в друга.

/* текст-1 /* текст-2 */ текст-3 */ текст-3 не считается комментарием.

Лексема – единица текста программы, которая при компиляции воспринимается как единое целое и по смыслу не может быть разделена на более мелкие элементы.

В языке СИ 6 классов лексем: свободно выбираемые и используемые идентификаторы, служебные (ключевые) слова, константы, строки (строковые константы), операции (знаки операций), разделители (знаки пунктуации).

Идентификаторы.

Идентификатором переменной может быть любая последовательность латинских букв, цифр и знака подчеркивания, которое начинается с буквы или знака подчеркивания. Пробелы в идентификаторах не допускаются.

X D8 d8 G_ALT GAMMA128 _X.

Прописные и строчные буквы различаются.

Идентификаторы могут иметь любую длину, но компилятор учитывает не более 31 символа.

В качестве идентификаторов нельзя использовать служебные (ключевые) слова и стандартные имена языка (sin, printf и т.д.).

Служебные (ключевые) слова.

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

 

auto break case char const continue default do
double else enum extern float for goto if
int long register return short signet sizeof Static
struct switch typedef union unsigned void volatile Wile

По смысловой нагрузке служебные слова группируются следующим образом:

Для обозначения типов данных используются спецификаторы типов и квалификаторы типов.

К спецификаторам типов относятся:

char - символьный;

double - вещественный двойной точности с плавающей точкой;

enum - перечисляемый тип (перечисление) - определе­ние целочисленных констант, для каждой из ко­торых вводятся имя и значение;

float - вещественный с плавающей точкой;

int- целый;

long - целый увеличенной длины (длинное целое);

short - целый уменьшенной длины (короткое целое);

struct - структура (структурный тип);

signed - знаковый, т.е. целое со знаком (старший бит считается знаковым);

union - объединение (объединяющий тип);

unsigned - беззнаковый, т.е. целое без знака (старший бит не считается знаковым);

void - отсутствие значения;

typedef - вводит синоним обозначения типа (определяет сокращенное наименование для обозначения типа).

Квалификаторы типа:

const - квалификатор объекта, имеющего постоянное значение, т.е. доступного только для чтения;

volatile - квалификатор объекта, значение которого может измениться без явных указаний программиста.

Квалификаторы типа информируют компилятор о необходимости и (или) возможности особой обработки объектов в процессе оптимизации кода программы.

Для обозначения классов памяти используются:

auto - автоматический;

extern - внешний; register - регистровый; static - статический.

Для построения операторов используются служебные слова:

break - выйти из цикла или переключателя;

continue - завершить текущую итерацию цикла (продолжить цикл, перейдя к следующей итерации);

do - выполнять (заголовок оператора цикла с постусловием);

for - для (заголовок оператора параметрического цикла);

goto - перейти (безусловный переход);

if - если - обозначение условного оператора;

return - возврат (из функции);

switch - переключатель;

while - пока (заголовок цикла с предусловием или завершение цикла do).

К служебным словам также отнесены следующие идентификаторы:

default - определяет действия при отсутствии нужного варианта в операторе switch;

case - определяет вариант в операторе switch;

else - входит в оператор if, определяя альтернативную ветвь;

sizeof - операция определения размера операнда (в байтах).

Добавим еще одно соглашение, обычно соблюдаемое авторами компиляторов и стандартных библиотек языка Си. Идентификаторы, начинающиеся с одного или двух символов подчеркивания "_", зарезервированы для использования в библиотеках и компиляторах. Поэтому такие идентификаторы не рекомендуется выбирать в качестве имен в прикладной программе на языке Си. Следующее соглашение относительно имен относится уже не к стандарту и не к реализациям, а отображает стиль оформления текста программы. Рекомендуется при программировании имена констант записывать целиком заглавными буквами.

Стандартные математические функции (файл math.h):

Функция Краткое описание
abs нахождение абсолютного значения выражения типа int
acos вычисление арккосинуса. Аргументы этой и других тригонометрических функций задаются в радианах
asin вычисление арксинуса
atan вычисление арктангенса х
atan2 вычисление арктангенса от у/х
cabs нахождение абсолютного значения комплексного числа
ceil нахождение наименьшего целого, большего или равного х
_clear87 получение значения и инициализация слова состояния сопроцессора и библиотеки арифметики с плавающей точкой
_control87 получение старого значения слова состояния для функций арифметики с плавающей точкой и установка нового состояния
cos вычисление косинуса
cosh вычисление гиперболического косинуса
exp вычисление экспоненты
fabs нахождение абсолютного значения типа double
floor нахождение наибольшего целого, меньшего или равного х
fmod нахождение остатка от деления х/у
_fpreset повторная инициализация пакета плавающей арифметики
frexp вычисляет для х вещественную мантиссу m и целое n так, что x=m*2n
hypot вычисление гипотенузы
labs нахождение абсолютного значения типа long
ldexp вычисление х*2e
log вычисление натурального логарифма
log10 вычисление логарифма по основанию 10
matherr управление реакцией на ошибки при выполнении функций математической библиотеки
modf разложение х на дробную и целую часть
pow вычисление х в степени у
sin вычисление синуса
sinh вычисление гиперболического синуса
sqrt нахождение квадратного корня
_status87 получение значения слова состояния с плавающей точкой
tan вычисление тангенса
tanh вычисление гиперболического тангенса

В библиотеке определен также ряд констант, таких как M_PI (число π), M_E (основание натурального логарифма e) и др.

 

Константы и строки

 

По определению, константа представляет значение, которое не может быть изменено. Синтаксис языка определяет пять типов констант: символы, константы перечисляемого типа, вещественные числа, целые числа и нулевой указатель ("null-указатель"). Все константы, кроме нулевого указателя, отнесены в языке Си к арифметическим.

Символы, или символьные константы. Для изображения отдельных знаков, имеющих индивидуальные внутренние коды, используются символьные константы. Каждая символьная константа - это лексема, которая состоит из изображения символа и ограничивающих апострофов. Например: 'А', 'а', 'В','8', '0','+', ';' и т.д.

Внутри апострофов можно записать любой символ, изображаемый на дисплее или принтере в текстовом режиме. Однако в ЭВМ используются и коды, не имеющие графического представления на экране дисплея, клавиатуре или принтере. Примерами таких кодов служит код перехода курсора дисплея на новую строку или код возврата каретки (возврат курсора к началу текущей строки). Для изображения в программе соответствующих символьных констант используются комбинации из нескольких символов, имеющих графическое представление. Каждая такая комбинация начинается с символа ‘\’ (обратная косая черта - backslash). Такие наборы литер, начинающиеся с символа ‘\’, в литературе по языку Си называют управляющими последовательностями. Ниже приводится их список:

'\n'- перевод строки;

'\t' - горизонтальная табуляция;

'\r' - возврат каретки (курсора) к началу строки;

'\\' - обратная косая черта \;

'\n''- апостроф (одиночная кавычка);

'\'" - кавычка (символ двойной кавычки);

'\0'-нулевой символ;

'\а' - сигнал-звонок;

'\b'- возврат на одну позицию (на один символ);

'\f' - перевод (прогон) страницы;

'\v'- вертикальная табуляция;

'\?' - знак вопроса.

Целые константы. Синтаксисом языка определены целые константы: десятичные, шестнадцатеричные и восьмеричные. Основание определяется префиксом в записи константы. Для десятичных констант префикс не используется. Десятичные целые определены как последовательности десятичных цифр, начинающиеся не с нуля (если это не число нуль):

44 684 0 1024

Каждая конкретная реализация языка вводит свои ограничения на предельные значения констант. Например, компилятор Turbo С в отношении целых констант соответствует стандарту и допускает целые десятичные от 0 до 32767, а длинные целые - от 0 до 2147483647.

Вещественные константы. Для представления веществен­ных (нецелых) чисел используются константы, представляемые в памяти ЭВМ в форме с плавающей точкой. Каждая вещественная константа состоит из следующих частей: целая часть (десятичная целая константа); десятичная точка; дробная часть (десятичная целая константа); признак показателя "е" или "E"; показатель десятичной степени (десятичная целая константа, возможно, со знаком). При записи констант с плавающей точкой могут опускаться целая или дробная часть (но не одновременно); десятичная точка или символ экспоненты с показателем степени (но не одновременно). Примеры констант с плавающей точкой:

44. 3.14159 44еО.314159Е1 0.0

Данные вещественных типов

Тип данных Размер, бит Диапазон абсолютных величин
float   от 3.4Е-38 до 3.4Е+38
double   от1.7Е-308до1.7Е+308
long double   от3.4Е-4932до1.1Е+4932

Вещественная константа 3.141592653589793 будет воспринята как имеющая тип double, и ей будет выделено 8 байт (64 бита). Тот же тип выбирается для константы 3.14, так как по умолчанию всем вещественным константам присваивается тип double.

Если программиста не устраивает тип, который компилятор приписывает константе, то тип можно явно указать в записи константы с помощью суффиксов: F (или f) - float (для вещественных), U (или u) - unsigned (для целых), L (или l) - long (для целых и вещественных). Например:

3.14159F - константа типа float (выделяется 4 байта);

3.14L - константа типа long double (выделяется 10 байт).

С помощью суффикса U (или u) можно представить целую константу в виде беззнакового целого. Например:

50000U - константа типа unsigned int.

Константе 50000U выделяются 2 байта (вместо четырех, как было бы при отсутствии суффикса. В этом случае, т.е. для unsigned int, знаковый бит используется для представления одного из разрядов кода числа и диапазон значений становится от 0 до 65535.

Суффикс L (или l) позволяет выделить целой константе 4 байта (32 бита):

500L - константа типа long, которой выделяется 4 байта;

0L - целая константа типа long длиной 4 байта.

Совместное использование в любом порядке суффиксов U (или u) и L (или l) позволяет приписать целой константе тип unsigned long, и она займет в памяти 32 разряда (бита), причем знаковый разряд будет использоваться для представления раз­ряда кода (а не знака). Примеры:

0LU - целая константа типа unsigned long длиной 4 байта;

2424242424UL - константа типа unsigned long.

Нулевой указатель. Null-указатель, называемый нулевым указателем, это единственная неарифметическая константа. Ее роль и функциональные возможности станут ясны при изучении аппарата указателей. В конкретных реализациях null-указатель может быть представлен либо как 0, либо как 0L, либо как именованная константа NULL. Здесь нужно отметить, что значение константы NULL не обязано быть нулем и имеет право не совпадать с кодом символа '0'.

Константы перечисляемого типа. Целочисленные именованные константы можно вводить с помощью перечисления:

enum тип перечисления {список_именованных_констант};

где enum - служебное слово, вводящее перечисление;

тип перечисления - его название - необязательный про­извольный идентификатор;

список_именованных_констант - разделенная запятыми последовательность идентификаторов или именованных кон­стант вида:

имя_ константы=значение_константы

Примеры:

enum {ONE=1, TWO, THREE, FOUR};

enum DAY {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,

THURSDAY, FRIDAY, SATURDAY};

enum BOOLEAN {NO, YES};

Если в списке нет ни одного элемента со знаком '=', то значе­ния констант начинаются с 0 и увеличиваются на 1 слева напра­во. Таким образом, N0 равно 0, YES равно 1, SUNDAY имеет значение 0 и FRIDAY имеет значение 5. Именованная константа со знаком '=' получает соответствующее значение (ONE=1), a следующие за ней именованные константы без явных значений увеличиваются на 1 каждая. В нашем примере TWO равно 2, THREE равно 3, FOUR равно 4.

Строки, или строковые константы. Формально строки (в соответствии, со стандартом) не относятся к константам языка Си, а представляют собой отдельный тип его лексем. Для них в литературе используется еще одно название "строковые литералы". Строковая константа определяется как последовательность символов, заключенная в двойные кавычки (не в апострофы):

"Образец строки"

Среди символов строки могут быть эскейп-последовательности, т.е. сочетания знаков, соответствующие неизображаемым символам, или символам, задаваемым их внутренними кодами. В этом случае, как и в представлениях отдельных символьных констант, их изображения начинаются с обратной косой черты ‘\’:

"\n Текст \n разместится \n в 3-х строках дисплея"

 

Переменные

 

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

В соответствии с типами значений, допустимых в языке Си, рассмотрим символьные, целые и вещественные переменные автоматической памяти. Переменные автоматической памяти существуют в том блоке, где они определены. В наиболее распространенном случае таким блоком является текст основной (main) функции программы.

Простейшая форма определения переменных:

тип список_имен_переменных;

где имена переменных - это выбранные программистом идентификаторы, которые в списке разделяются запятыми;

тип - один из типов.

Определены целочисленны е типы:

char -целый длиной не менее 8 бит;

short int- короткий целый (допустима аббревиатура short);

int - целый;

long - длинный целый.

Каждый из целочисленных типов может быть определен либо как знаковый signed либо как беззнаковый unsigned (по умолчанию signed).

Различие между этими двумя типами - в правилах интерпретации старшего бита внутреннего представления. Спецификатор signed требует, чтобы старший бит внутреннего представления воспринимался как знаковый; unsigned означает, что старший бит внутреннего представления входит в код представляемого числового значения, которое считается в этом случае беззнаковым. Выбор знакового или беззнакового представления определяет предельные значения, которые можно представить с помощью описанной переменной. Например, на IBM PC переменная типа unsigned int позволяет представить числа от 0 до 65535, а переменной типа signed int (или просто int) соответствуют значения в диапазоне от -32768 до +32767.

Примеры определений целочисленных переменных:

char symbol, cc;

unsigned char code;

int number, row;

unsigned long long_number;

Обратите внимание на необходимость символа "точка с запятой" в конце каждого определения.

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

float - вещественный одинарной точности;

double - вещественный удвоенной точности;

long double- вещественный максимальной точности.

Значения всех вещественных типов в ЭВМ представляются с "плавающей точкой", т.е. с мантиссой и порядком,

Примеры определений вещественных переменных:

float х, X, ссЗ, pot_8;

double a, Stop, B4;

Инициализация переменных. В соответствии с синтаксисом языка переменные автоматической памяти после определения по умолчанию имеют неопределенные значения. Надеяться на то, что они равны, например, 0, нельзя. Однако переменным можно присваивать начальные значения, явно указывая их в определениях:

тип имя_ переменной=начальное значение;

Этот прием назван инициализацией. В отличие от присваивания, которое, осуществляется в процессе выполнения программы, инициализация выполняется при выделении для переменной участка памяти. Примеры определений с инициализацией:

float pi=3.1415, cc=1.23;

unsigned int. year=1997;

Именованные константы. В языке Си, кроме переменных, могут быть определены константы, имеющие фиксированные названия (имена). В качестве имен констант используются произвольно выбираемые программистом идентификаторы, не совпадающие с ключевыми словами и с другими именами объектов. Традиционно принято, что для обозначений констант выбирают идентификаторы из больших букв латинского алфавита и символов подчеркивания. Такое соглашение позволяет при просмотре большого текста программы на языке Си легко отличать имена переменных от названий констант.

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

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

const тип имя_константы=значение_константы;

Здесь const - квалификатор типа, указывающий, что определяемый объект имеет постоянное значение, т.е. доступен только для чтения;

тип - один из типов объектов;

имя константы -идентификатор;

значение_константы должно соответствовать ее типу. Примеры:

const double Е=2.718282;

const long M=99999999;

const F=765;

В последнем определении тип константы не указан, по умолчанию ей приписывается тип int.

Третью возможность вводить именованные константы обеспечивает препроцессорная директива

#define имя_константы значение константы

Обратите внимание на отсутствие символа "точка с запятой" в конце директивы.

Отличие определения именованной константы

const double Е=2.718282;

от определения препроцессорной константы с таким же значением

#define EULER 2.718282

состоит внешне в том, что в определении константы Е явно задается ее тип, а при препроцессорном определении константы EULER ее тип определяется "внешним видом" значения константы. Например, следующее определение

#define NEXT 'Z'

вводит обозначение NEXT для символьной константы 'Z'. Это соответствует такому определению:

const char NEXT = 'Z';

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

#define EULER 2.718282

а ниже ее в тексте используется имя константы EULER, например, в таком виде:

double mix = EULER;

d = alfa*EULER;

то препроцессор заменит каждое обозначение EULER на ее значение и сформирует такой текст:

double mix = 2.718282;

d = alfa*2.718282;

Далее текст от препроцессора поступает к компилятору, который уже "и не вспомнит" о существовании имени EULER, использованного в препроцессорной директиве #define. Константы, определяемые на препроцессорном уровне с помощью директивы #define, очень часто используются для задания размеров массивов, что будет продемонстрировано позже. Подстановка не выполняется в комментариях и в строковых константах.

Именно с помощью набора именованных препроцессорных констант стандарт языка Си рекомендует авторам компиляторов определять предельные значения всех основных типов данных. Для этого в языке определен набор фиксированных имен, каждое из которых является именем одной из констант, определяющих то или иное предельное значение. Например:

FLT_MAX - максимальное число с плавающей точкой типа float;

CHAR_BIT- количество битов в байте;

INT_МIN - минимальное значение для данных типа int.

Чтобы использовать в программе указанные именованные препроцессорные константы, недостаточно записать их имена в программе. Предварительно в текст программы необходимо включить препроцессорную директиву такого вида:

#include <имя заголовочного _файла>

где в качестве имени заголовочного_файпа подставляются:

limits.h - для данных целых типов;

float.h - для вещественных данных.

#include <limits.h>

#include <float.h>

Операции

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

За исключением операций "[]", "()" и "?:", все знаки операций распознаются компилятором как отдельные лексемы. В зависимости от контекста одна и та же лексема может обозначать разные операции, т.е. один и тот же знак операции может употребляться в различных выражениях и по-разному интерпретироваться в зависимости от контекста. Например, бинарная операция & - это поразрядная конъюнкция, а унарная операция & - это операция получения адреса.

Операции ранга 1 имеют наивысший приоритет. Операции одного ранга имеют одинаковый приоритет, и если их в выражении несколько, то они выполняются в соответствии с правилом ассоциативности либо слева направо (→), либо справа налево (). Если один и тот же знак операции приведен в таблице дважды (например, знак *), то первое появление (с меньшим по номеру, т.е. старшим по приоритету, рангом) соответствует унарной операции, а второе - бинарной.

Опишем кратко возможности отдельных операций.

Приоритеты (ранги) операций

Ранг Операции Ассоциативность
  () [] → •
  ! ~ + - ++ -- & * (тип) sizeof  
  * / % (мультипликативные бинарные)
  + - (аддитивные бинарные)
  «» (поразрядного сдвига)
  < <= >= > (отношения)
  =!= (отношения)
  & (поразрядная конъюнкция "И")
  Ù (поразрядное исключающее "ИЛИ")
  | (поразрядная дизъюнкция "ИЛИ")
  && (конъюнкция "И")
  || (дизъюнкция "ИЛИ")
  ?: (условная операция)  
  = *= /= %= += -= &= Ùл= |= «=»=  
  , (операция "запятая")

Унарные (одноместные) операции. Для изображения одноместных префиксных и постфиксных операций используются следующие символы:

& - операция получения адреса операнда (ранг 2);

* - операция обращения по адресу, т.е. раскрытия ссылки, иначе операция разыменования (доступа по адресу к значению того объекта, на который указывает операнд). Операндом должен быть указатель (ранг 2);

- - унарный минус, изменяет знак арифметического операнда (ранг 2);

+ - унарный плюс, введен для симметрии с унарным минусом (ранг 2);

~ - поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента - побитовое отрицание (ранг 2)\

!- НЕ - логическое отрицание значения операнда (ранг 2). Применяется к скалярным операндам. Целочисленный результат 0 (если операнд ненулевой, т.е. истинный) или 1 (если операнд нулевой, т.е. ложный). Напомним, что в качестве логических значений в языке используют целые числа: 0 - ложь и не нуль, т.е. (!0) - истина. Отрицанием любого ненулевого числа будет 0, а отрицанием нуля будет 1. Таким образом:!1 равно 0;!2 равно 0;!(-5) равно 0;!0 равно 1;

++ - увеличение на единицу (инкремент или автоувеличение -ранг 2).

-- - уменьшение на единицу (декремент или автоуменьшеие - ранг 2) - унарная операция, операндом которой должно быть леводопустимое выражение, т.е. не константа и не выражение:

sizeof - операция (ранг 2) вычисления размера (в байтах) для объекта того типа, который имеет операнд. Разрешены два формата операции:

sizeof выражение

sizeof (mun).

sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.

Бинарные (двуместные) операции делятся на следующие группы:

• аддитивные;

• мультипликативные;

• сдвигов;

• поразрядные;

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

• логические;

• присваивания;

• выбора компонента структурированного объекта;

• операция "запятая";

• скобки в качестве операций.

Аддитивные операции:

+ - бинарный плюс - сложение арифметических операндов или сложение указателя с целочисленным операндом (ранг 4);

- - бинарный минус - вычитание арифметических операндов или вычитание указателей (ранг 4).

Мультипликативные операции:

* - умножение операндов арифметического типа (ранг 3);

/ - деление операндов арифметического типа (ранг 3). При целочисленных операндах абсолютное значение результата округляется до целого. Например, 20/3 рав­но 6, -20/3 равно -6, (-20)/3 равно -6, 20/(-3) равно -6;

% - получение остатка от деления целочисленных операндов (деление по модулю - ранг 3). При неотрицательных операндах остаток положительный. В противном случае остаток определяется реализацией. В компиляторе Turbo С:

13%4 равняется 1, (-13)%4 равняется -1; 13%(-4) равно +1, а (-13)%(-4) равняется -1.

При ненулевом делителе для целочисленных операндов всегда выполняется соотношение: (a/b)*b + a%b равно а.

Операции отношений (сравнения):

< меньше, чем (ранг 6);,

> больше, чем (ранг 6);

<= меньше или равно (ранг 6);

>= больше или равно (ранг б);

== равно (ранг 7);

!= не равно (ранг 7).

Операнды операций отношений должны быть арифметического типа или могут быть указателями. Результат целочисленный: 0 (ложь) или 1 (истина). Последние две операции (операции сравнения на равенство) имеют более низкий приоритет по сравнению с остальными операциями отношений. Таким образом, выражение

(х < В ==А < х) есть 1,

когда значение х находится в интервале от А до В и А<В либо х, А, В равны. (Вначале вычисляются х<В и А<х, к результатам применяется операция сравнения на равенство ==.)

Логические бинарные операции:

&& - конъюнкция (И) арифметических операндов или отношений (ранг 11. Целочисленный результат 0 (ложь) или 1 (истина);

|| - дизъюнкция (ИЛИ) арифметических операндов или отношений (ранг 12). Целочисленный результат 0 (ложь) или 1 (истина). (Вспомните о существовании унарной операции отрицания '!'.)

Результаты отношений и логических операций:

3<5 равняется 1;

3>5 равняется 0;

3=5 равняется 0;

3!=5 равняется 1;

3!=5 || 3=5 равняется 1;

3+4>5 && 3+5>4 && 4+5>3 равняется 1.

Операции присваивания (ранг 14)

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

Перечислим операции присваивания, отметив, что существуют одна простая операция присваивания и ряд составных операций:

= - простое присваивание: присвоить значение выражения-операнда из правой части операнду левой части. Пример: Р = 10.3 - 2*х;

*= - присваивание после умножения: присвоить операнду левой части произведение значений обоих операндов. Р *= 2 эквивалентно Р = Р * 2;

/= - присваивание после деления: присвоить операнду левой части частное от деления значения левого операнда на значение правого. Р /= 2.2 - d эквивалентно Р=- Р / (2.2 - d);

%= - присваивание после деления по модулю: присвоить операнду левой части остаток от целочисленного деления значения левого операнда на значение правого операнда. N %= 3 эквивалентно N = N % 3;

= - присваивание после суммирования: присвоить операнду левой части сумму значений обоих операндов А += В эквивалентно А = А + В;

-= - присваивание после вычитания: присвоить операнду левой части разность значений левого и правого операндов. X -= 4.3 - Z эквивалентно X = X - (4.3 - Z);

Обратите внимание, что для всех составных операций присваивания форма присваивания Е1 ор= Е2 эквивалентна Е1 = El op (E2), где ор - обозначение операции.

Запятая в качестве операции (ранг 15)

Несколько выражений, разделенных запятыми ",", вычисляются последовательно слева направо. В качестве результата сохраняются тип и значение самого правого выражения. Например, если переменная х имеет тип int, то значением выражения (х=3, 3*х) будет 9, а переменная х примет значение 3.

Условная трехместная операция (ранг 13). В отличие от унарных и бинарных операций условная тернарная операция используется с тремя операндами. В изображении условной операции применяются два символа '?' и ':' и три выражения-операнда:

выражение_1? выражение_2: выражение_3

Первым вычисляется значение выражения_1. Если оно истинно, т.е. не равно нулю, то вычисляется значение выражения_2, которое становится результатом. Если при вычислении выражения_1 получится 0, то в качестве результата берется значение выражения_3. Классический пример:

х < 0? -х: х;

Выражение возвращает абсолютную величину переменной х.

Операция явного преобразования типа. Операция преобразования (приведения) типа (ранг 2) имеет следующий формат:

(имя_типа) операнд

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

 

Разделители

 

Разделители, или знаки пунктуации, входят в число лексем языка:

[] () {},;: * = #

Квадратные скобки. Для ограничения индексов одно- и многомерных массивов, а также при записи индексированных элементов используются квадратные скобки [ ]. Примеры:

int A[5]; А -одномерный массив из пяти элементов;

int х, е[3][2]; е -двумерный массив (матрица) размером 3x2.

Выражение с индексированными элементами: е[0][0] = х= А[2] = 4; означает, что начальному элементу массива е, переменной х и третьему элементу массива А присваивается значение 4. Так как индексы в массивах всегда начинаются с 0, то элемент А[2] соответствует третьему элементу массива.

Круглые скобки. Назначение круглых скобок ():

1) выделяют выражения-условия (в операторе "если"):

if (х < 0) х = -х;

2) входят как обязательные элементы в определение и описание (в прототип) любой функции, где выделяют соответственно список формальных параметров и список спецификаций параметров:

float F(float x, int k) /* Определение функции*/

{ тело_функции }

float F(float, int); /* Описание функции – ее.прототип */

3) круглые скобки обязательны при определении указателя на функцию:

int (*pfunc)(); /* Определение указателя pfunc на функцию */

4) группируют выражения, изменяя естественную последовательность выполнения операций:

у = (а + b) / с; /*• Изменение приоритета операций */

5) входят как обязательные элементы в операторы циклов:

for (i=0, j=l; i<j; i+=2, j++) тело_цикла;

while (i<j) тело_цикла;

do тело_циклаwhile (k>0);

6) необходимы при явном преобразовании типа. Примеры:

long i = 12L; /* Определение переменной */

float brig; /* Определение переменной */

brig = (float)i; /* Явное приведение типа */

brig получает значение 12L, преобразованное к типу float;

Фигурные скобки. Для обозначения соответственно начала и конца составного оператора или блока используют фигурные скобки {}. Пример использования составного оператора в условном операторе:

if (d > x) { d--; x++; }

Пример блока - тело любой функции:

float absx (float x)

{

return x>0.0?x:-x;

}

Обратите внимание на отсутствие точки с запятой после закрывающейся скобки '}', обозначающей конец составного оператора или блока.

Фигурные скобки используются при инициализации массивов и структур при их определении:

/* Инициализация массива: */

int month [ ] ={ 1, 2, 3, 4, 5, б, 7, 8, 9, 10,11, 12 };

Запятая. Запятая может быть использована в качестве операции, а может применяться как разделитель. В последнем случае она разделяет элементы списков. Во-первых, это спискиначальных значений элементов массивов и компонентов структур при их инициализации (примеры только что даны).

Другой пример списков - списки формальных и фактических параметров и их спецификаций в функциях.

Третье использование запятой как разделителя - в заголовке оператора цикла:

for (x=pl,y=p2,i=2; i<n; z=x+y; x=y, y=z, i++);

Запятая как разделитель используется также в описаниях и определениях объектов (например, переменных) одного типа:

Int i, n,-

float x, у, z, pi, p2;

Запятая в качестве операции уже рассматривалась. Следует обратить внимание на необходимость с помощью круглых скобок отделять запятую-операцию от запятой-разделителя. Например, для элементов следующего массива m используется список с тремя начальными значениями:

int i=l, m[ ]={ i, (i=2,i*i), i };

В данном примере запятая в круглых скобках выступает в роли знака операции. Операция присваивания "=" имеет более высокий приоритет, чем операция "запятая". Поэтому вначале i получает значение 2, затем вычисляется произведение i*i, и этот результат служит значением выражения в скобках. Однако значением переменной i остается 2. Значениями m[0], m[1], m[2] будут соответственно 1, 4, 2.

Точка с запятой. Каждый оператор, каждое определение и каждое описание в программе на языке Си завершает точка с запятой ';'. Любое допустимое выражение, за которым следует ';', воспринимается как оператор. Это справедливо и для пустого выражения, т.е. отдельный символ "точка с запятой" считается пустым оператором. Пустой операто



Поделиться:


Последнее изменение этой страницы: 2017-02-10; просмотров: 199; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.130.130 (0.243 с.)