Базовые элементы языка С. Алфавит и словарь языка 


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



ЗНАЕТЕ ЛИ ВЫ?

Базовые элементы языка С. Алфавит и словарь языка



Операции языка С.

Операция, применяемая к одному операнду, наз. унарной, операция с двумя операндами- бинарная.

1. Арифметические операции (+, -, *, /, ++ (операция инкремента-увеличения на 1), -- (операция дикремента- уменьшения на 1), % (деление по модулю- примен. к целым числам), остальные операции применимы к любым типам данных. Если делимое и делитель целые числа, то результат - целое число, если один из операндов вещественного типа, то результат - вещественный.

Операции инкремента и декремента применяются только к переменным (а++: постфиксная форма, ++а: префиксная). При использовании постфиксной формы операции инкремента и декремента выполняются после того, как значение переменной использовалось в выражении, а при префиксной форме - до использования выражения.

2. Логические операции:! (отрицание), && (конъюнкция--И), I I (дизъюнкция—ИЛИ).

В СИ имеются поразрядовые лог. операции (битовые): & (поразрядовая конъюнкция), I (поразрядовая дизъюнкция), ^ (исключающее ИЛИ), ~ (поразрядовое отрицание).

3. Операции поразрядового сдвига. Выполняются с помощью перевода операнда в двоичную систему счисления, >> (поразрядовый сдвиг вправо), << (сдвиг влево).

Операции языка С.

4. Операции отношений: >, <, >=, <=, ==,!= (не равно). Результат операции отношения явл-ся: 1 (истинно-true) и 0 (ложно-false).

5. Операция присваивания. В языке СИ присваивание-это операция, а не операнд, значит, может несколько раз входить в выражение (а=в=с). Есть дополнительные операции присваивания, совмещающие присваивание с выполнением других операций: +=, -=, *=, /=, %= (пр. а+=2 ---> а=а+2)

6. Операция определения размера (sizeof).

Sizeof (тип) или sizeof (выражение). Результат операции - целое число равное количеству байт в памяти, кот-е занимает полученная величина в результате вычисления.

7. Операция следования, её формат:

выраж-е 1, выраж-е 2

Сначала вычисляется выраж-е 1, затем выраж2, а рез-том явл выраж-е 2. Вычисление выраж-я 1 м повлиять на выраж-е 2.

 

Условная операция (?)

Явл единственной тернарной операцией, т.е. имеет 3 операнда. Формат:

выраж-е 1? выраж-е 2: выраж-е 3

Сначала проверяется выраж-е 1(т.е. условие), если оно истинно (т.е. не = 0), то рез-том б выраж-е 2, иначе - выраж-е 3. ПР-Р: max=(а<=b)?b:a;

Ранг – поряд № в ряду приоритетов. Если 1 операция, повтор-щаяся в выр-ии неск раз, вып-ся спр налево, то опер назыв правоассоциат-й, иначе левоасс.

 

Условные операторы (if, switch).

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

Условный оператор--- if.

а).If (выражение) оператор1;

Else оператор2;

б) вложенный оператор if:

if (х) { if (y) оператор 1;}

else оператор 2;

в) неполная форма—if (выр-ние) оператор1;

г) If (условие) оператор1;

Else If (условие) оператор2;

Else If (условие) оператор3;

Else оператор;

Выражение - некоторое условие, содержащее операции отношения и логич. операции. Значение выражения приводится к целому, интерпретируется след. образом: 0-ложь, 1-истина. Если выражение истинно, то вып-ся оператор 1, если нет - оператор2.

Выражение записывается в ().

Составной оператор - последовательность операторов, заключенных в { }.

Оператор выбора---switch.

Switch (целочисленное выражение)

{case конст.1:

список операторов;

break;

case конст.2:

список операторов; break;

default: список операторов;}

Выполнение операторов происходит в след. порядке:

выполняется целочисленное выражение, полученное значение последовательно сравнивается с константами после служебного слова case. При совпадении значений операторов вып-ся операторы, стоящие после двоеточия. Если не с одной из констант совпадений не произошло, то вып-ся операторы, стоящие после default. Для того, чтобы обойти выполнение операторов последующих ветвей исп-ся операторы выхода или перехода.

Иногда используется оператор break-оператор выхода. После его выполнения завершается работа оператора выбора, т.е. происходит «обход» других ветвей.

If, #else, #elif

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

Возможно, самыми распространенными директивами условной компиляции являются #if, #else, #elif и #endif. Они дают возможность в зависимости от значения константного выражения включать или исключать те или иные части кода.

В общем виде директива #if выглядит таким образом:

#if константное выражение

последовательность операторов

#endif

Если находящееся за #if константное выражение истинно, то компилируется код, который находится между этим выражением и #endif. В противном случае этот промежуточный код пропускается. Директива #endif обозначает конец блока #if.

Директива #else работает в основном так, как else — ключевое слово языка С: задает альтернативу на тот случай, если не выполнено условие #if.

Директива #elif означает "else if" и устанавливает для множества вариантов компиляции цепочку if-else-if. После #elif находится константное выражение. Если это выражение истинно, то компилируется находящийся за ним блок кода, и больше не проверяются никакие другие выражения #elif. В противном же случае проверяется следующий блок этой последовательности. В общем виде #elif выглядит таким образом:

#if выражение

последовательность операторов

#elif выражение 1

последовательность операторов

#elif выражение 2

последовательность операторов

#elif выражение 3

последовательность операторов

#elif выражение 4

.

#elif выражение N

последовательность операторов

#endif

Другой способ условной компиляции — это использование директив #ifdef и #ifndef, которые соответственно означают "if defined" (если определено) и "if not defined" (если не определено). В общем виде #ifdef выглядит таким образом:

#ifdef имя_макроса

последовательность операторов

#endif

Блок кода будет компилироваться, если имя макроса было определено ранее в операторе #define.

В общем виде оператор #ifndef выглядит таким образом:

#ifndef имя_макроса

последовательность операторов

#endif

Блок кода будет компилироваться, если имя макроса еще не определено в операторе #define.

 

35.

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

Замена идентификаторов
#define идентификатор строка
Пример:
#define ABC 100
Заменяет каждое вхождение идентификатора ABC в тексте программы на 100:
#undef идентификатор
Пример:
#undef ABC
Отменяет предыдущее определение для идентификатора ABC.

 

32.

26.

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

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

(конспект)

 

Связь указателей и массивов в языке Си.

В языке Си имя массива - это адрес памяти, начиная с которой расположен массив, то есть адрес первого элемента массива. Если объявлен целочисленный массив int m[25], то m является указателем на массив. Поэтому написать в программе
p=m; или
p=&m[0]
это одно и то же, так как первая и вторая команды дают одно и то же число - адрес первого элемента массива m[25]. Для того, чтобы обратиться к 11-му элементу массива m, можно написать m[10] или *(m+10). Результат должен быть одним и тем же.

 

23.

Указательные выражения – выражения с указателями.

В языке С допустимы только две арифметические операции над указателями: суммирование и вычитание. Предположим, текущее значение указателя p1 типа int * равно 2000. Предположим также, что переменная типа int занимает в памяти 2 байта. Тогда после операции увеличения

p1++;

указатель p1 принимает значение 2002, а не 2001. То есть, при увеличении на 1 указатель p1 будет ссылаться на следующее целое число. Это же справедливо и для операции уменьшения. Например, если p1 равно 2000, то после выполнения оператора

p1--; значение p1 будет равно 1998.

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

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

p1 = p1 + 12;

"передвигает" указатель p1 на 12 объектов в сторону увеличения адресов. Кроме суммирования и вычитания указателя и целого, разрешена еще только одна операция адресной арифметики: можно вычитать два указателя. Благодаря этому можно определить количество объектов, расположенных между адресами, на которые указывают данные два указателя; правда, при этом считается, что тип объектов совпадает с базовым типом указателей. Все остальные арифметические операции запрещены. А именно: нельзя делить и умножать указатели, суммировать два указателя, выполнять над указателями побитовые операции, суммировать указатель со значениями, имеющими тип float или double и т.д.

 

17.

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

1) char array[7] = "Строка";

char s[ ] = {'С', 'т', 'р', 'о', 'к', 'а', '\0'};

2) char *b;

Для ввода и вывода строк символов помимо scanf() и printf() могут использоваться функции gets() и puts() (их прототипы находятся в файле stdio.h).

Если string - массив символов, то ввести строку с клавиатуры можно так:

gets(string);

(ввод оканчивается нажатием клавиши <Enter>). Вывести строку на экран можно следующим образом:

puts(string);

 

Приоритет операций.

В приводимой ниже таблице сведены правила старшинства и ассоциативности всех операций. Операции, расположенные в одной строке, имеют один и тот же уровень старшинства; строки расположены в порядке убывания старшинства. Так, например, операции *, " / " и " % " имеют одинаковый уровень старшинства, который выше, чем уровень операций " + " и " - ".

Оператор

| () [] ->

| ~ ++ -- - f (type) * & sizeof

| * / %

| + -

| << >>

| < <= > > =

| ==!=

| &

| ^

| &&

| ?:

| = += -= и т.п.

 

Переменные.

В языке СИ для хранения различных данных используются переменные. Каждая переменная имеет свое имя, и ей можно присваивать различные значения. Используя переменные, можно строить различные выражения. Каждое выражения представляет собой одну или несколько переменных и числовых констант, связанных арифметическими и (или) логическими операциями. В языке СИ переменные делятся на типы. Переменная каждого типа может принимать значения из одного определенного диапазона. Например: переменная типа char — это только целые числа. В языке СИ любая переменная, прежде чем она будет использована, должна быть описана. При описании задается ее тип. В дальнейшем диапазон принимаемых значений должен строго соответствовать выбранному типу переменной. Описание переменной и задание ее типа необходимы потому, что оттранслированная с языка СИ программа выделяет для хранения значений каждой переменной определенные ресурсы памяти. Посмотрим, как выглядит строка описания переменной в программе. Она представляет собой запись следующего вида: Тип Имя. Имя переменной выбирает программист. Допускается использование только латинских букв, цифр и символа подчеркивания. Начинаться имя должно с буквы или символа подчеркивания.

 

15.

Оператор break обеспечивает прекращение выполнения самого внутреннего из объединяющих его операторов switch, do, for, while. После выполнения оператора break управление передается оператору, следующему за прерванным.

Оператор continue, как и оператор break, используется только внутри операторов цикла, но в отличие от него выполнение программы продолжается не с оператора, следующего за прерванным оператором, а с начала прерванного оператора. Формат оператора следующий:

 

continue;

Оператор continue, как и оператор break, прерывает самый внутренний из объемлющих его циклов.

Оператор goto

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

Формат этого оператора следующий:

goto имя-метки;

...

имя-метки: оператор;

 

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

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

Оператор return

Оператор return завершает выполнение функции, в которой он задан, и возвращает управление в вызывающую функцию, в точку, непосредственно следующую за вызовом. Функция main передает управление операционной системе. Формат оператора:

 

return [выражение];

 

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

Если в какой-либо функции отсутствует оператор return, то передача управления в вызывающую функцию происходит после выполнения последнего оператора вызываемой функции. При этом возвращаемое значение не определено. Если функция не должна иметь возвращаемого значения, то ее нужно объявлять с типом void.

Таким образом, использование оператора return необходимо либо для немедленного выхода из функции, либо для передачи возвращаемого значения.

 

Поиск.

Задача поиска. Пусть заданы линейные списки: список элементов В=<К1,К2,К3,...,Кn> и список ключей V= (в простейшем случае это целые числа). Требуется для каждого значения Vi из V найти множество всех совпадающих с ним элементов из В.

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

Бинарный поиск

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

 

34. Стандартная библиотека С++ включает в себя как сущности, специфичные для С++, так и, частично, стандартную библиотеку C с небольшими изменениями[источник не указан 217 дней], которые делают её более подходящей для языка C++[источник не указан 217 дней]. Стандарт C++ содержит нормативную ссылку на стандарт C от 1990 года и не определяет самостоятельно те функции стандартной библиотеки, которые заимствуются из стандартной библиотеки C. Доступ к возможностям стандартной библиотеки C++ обеспечивается с помощью включения в программу (посредством директивы #include) соответствующих стандартных заголовочных файлов. Всего в стандарте C++ определено 50 таких файлов.

 

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

void* operator new(std::size_t) throw(std::bad_alloc);

void* operator new[](std::size_t) throw(std::bad_alloc);

void operator delete(void*) throw();

void operator delete[](void*) throw();

 

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

 

45.

Открытие файла

Функция fopen() открывает поток и связывает с этим потоком определенный файл. Затем она возвращает указатель этого файла. Чаще всего (а также в оставшейся части этой главы) под файлом подразумевается дисковый файл. Прототип функции fopen() такой:

FILE *fopen(const char *имя_файла, const char *режим);

 

где имя_файла — это указатель на строку символов, представляющую собой допустимое имя файла, в которое также может входить спецификация пути к этому файлу. Строка, на которую указывает режим, определяет, каким образом файл будет открыт. В табл. 9.2 показано, какие значения строки режим являются допустимыми. Строки, подобные "r+b" могут быть представлены и в виде "rb+".

Закрытие файла

Функция fclose() закрывает поток, который был открыт с помощью вызова fopen().Функция fclose() записывает в файл все данные, которые еще оставались в дисковом буфере, и проводит, так сказать, официальное закрытие файла на уровне операционной системы. Отказ при закрытии потока влечет всевозможные неприятности, включая потерю данных, испорченные файлы и возможные периодические ошибки в программе. Прототип функции fclose() такой:

int fclose(FILE *уф);

 

где уф — указатель файла, возвращенный в результате вызова fopen(). Возвращение нуля означает успешную операцию закрытия. В случае же ошибки возвращается EOF. Чтобы точно узнать, в чем причина этой ошибки, можно использовать стандартную функцию ferror() (о которой вскоре пойдет речь). Обычно отказ при выполнении fclose() происходит только тогда, когда диск был преждевременно удален (стерт) с дисковода или на диске не осталось свободного места.

 

Запись и чтение символов

Самыми простыми из консольных функций ввода/вывода являются getchar(), которая читает символ с клавиатуры, и putchar(), которая отображает символ на экране. Первая из этих функций ожидает, пока не будет нажата клавиша, а затем возвращает значение этой клавиши. Кроме того, при нажатии клавиши на клавиатуре на экране дисплея автоматически отображается соответствующий символ. Вторая же функция, putchar(), отображает символ на экране в текущей позиции курсора. Вот прототипы функций getchar() и putchar():

int getchar(void);

int putchar(int c);

 

Как видно из прототипа, считается, что функция getchar() возвращает целый результат. Однако возвращаемое значение можно присвоить переменной типа char, что обычно и делается, так как символ содержится в младшем байте. (Старший байт при этом обычно обнулен.) В случае ошибки getchar() возвращает EOF.

Что же касается putchar(), то несмотря на то, что эта функция объявлена как принимающая целый параметр, она обычно вызывается с символьным аргументом. На самом деле из ее аргумента на экран выводится только младший байт. Функция putchar() возвращает записанный символ или, в случае ошибки, EOF.

Стирание файлов

Функция remove() стирает указанный файл. Вот ее прототип:

int remove(const char *имя_файла);

 

В случае успешного выполнения эта функция возвращает нуль, а в противном случае — ненулевое значение.

 

Связанные списки

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

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

Двоичные деревья

При обсуждении деревьев применяется специальная терминология. Первый элемент дерева называется корнем (root). Каждый элемент данных называется вершиной дерева (node), а любой фрагмент дерева называется поддеревом (subtree). Вершина, к которой не присоединены поддеревья, называется заключительным узлом (terminal node) или листом (leaf). Высота (height) дерева равняется максимальному количеству уровней от корня до листа. При работе с деревьями можно допустить, что в памяти они существуют в том же виде, что и на бумаге. Но помните, что дерево — всего лишь способ логической организации данных в памяти, а память линейна.

Способ упорядочивания дерева зависит от того, как к нему впоследствии будет осуществляться доступ. Процесс поочередного доступа к каждой вершине дерева называется обходом (вершин) дерева (tree traversal). Рассмотрим следующее дерево:

d

↙ ↘

b f

↙ ↘ ↙ ↘

a c e g

Существует три порядка обхода дерева: симметричный обход (inorder), прямой обход, упорядоченный обход, обход сверху, или обход в ширину (preorder) и обход в обратном порядке, обход в глубину, обратный обход, обход снизу (postorder). При симметричном обходе обрабатывается сначала левое поддерево, затем корень, а затем правое поддерево. При прямом обходе обрабатывается сначала корень, затем левое поддерево, а потом правое. При обходе снизу сначала обрабатывается левое поддерево, затем правое и, наконец корень. Последовательность доступа при каждом методе обхода показана ниже:

Симметричный обход a b c d e f g

Прямой обход d b a c f e g

Обход снизу a c b e g f d

 

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

 

Массивы структур

Структуры часто образуют массивы. Чтобы объявить массив структур, вначале необходимо определить структуру (то есть определить агрегатный тип данных), а затем объявить переменную массива этого же типа. Например, чтобы объявить 100-элементный массив структур типа addr, напишите следующее:

struct addr addr_list[100];

Это выражение создаст 100 наборов переменных, каждый из которых организован как определено в структуре addr.

Чтобы получить доступ к определенной структуре, указывайте имя массива с индексом. Например, чтобы вывести ZIP-код из третьей структуры, напишите следующее:

printf("%d", addr_list[2].zip);

Как и в других массивах переменных, в массивах структур индексирование начинается с 0.

Для справки: чтобы указать определенную структуру, находящуюся в массиве структур, необходимо указать имя этого массива с определенным индексом. А если нужно указать индекс определенного элемента в структуре, то необходимо указать индекс этого элемента. Таким образом, в результате выполнения следующего выражения первому символу члена name, находящегося в третьей структуре из addr_list, присваивается значение 'X'.

addr_list[2].name[0] = 'X';

 

Средство typedef

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

Общий вид декларации typedef (оператора typedef) такой:

typedef тип новое_имя;

 

где тип — это любой тип данных языка С, а новое_имя — новое имя этого типа. Новое имя является дополнением к уже существующему, а не его заменой.

 

Например, для float можно создать новое имя с помощью

typedef float balance;

Это выражение дает компилятору указание считать balance еще одним именем float. Затем, используя balance, можно создать переменную типа float:

balance over_due;

 

Теперь имеется переменная с плавающей точкой over_due типа balance, a balance является еще одним именем типа float.

Теперь, когда имя balance определено, его можно использовать и в другом операторе typedef. Например, выражение

typedef balance overdraft;

 

дает компилятору указание признавать overdraft в качестве еще одного имени balance, которое в свою очередь является еще одним именем float.

Использование операторов typedef может облегчить чтение кода и его перенос на новую машину. Однако новый физический тип данных таким способом вы не создадите.

 

Базовые элементы языка С. Алфавит и словарь языка

Множество символов, используемых в языке С, можно разделить на пять групп.

 

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

2. Группа прописных и строчных букв русского алфавита и арабские цифры

3. Знаки нумерации и специальные символы (таблица 3). Эти символы используются с одной стороны для организации процесса вычислений, а с другой - для передачи компилятору определенного набора инструкций.

4. Управляющие и разделительные символы. К той группе символов относятся: пробел, символы табуляции, перевода строки, возврата каретки, новая страница и новая строка. Эти символы отделяют друг от друга объекты, определяемые пользователем, к которым относятся константы и идентификаторы. Последовательность разделительных символов рассматривается компилятором как один символ (последовательность пробелов).

5. Кроме выделенных групп символов в языке С широко используются так называемые, управляющие последовательности, т.е. специальные символьные комбинации, используемые в функциях ввода и вывода информации. Управляющая последовательность строится на основе использования обратной дробной черты (\) (обязательный первый символ) и комбинацией латинских букв и цифр Последовательности вида \ddd и \xddd (здесь d обозначает цифру) позволяет представить символ из набора кодов ПЭВМ как последовательность восьмеричных или шестнадцатеричных цифр соответственно. Следует отметить, что в строковых константах всегда обязательно задавать все три цифры в управляющей последовательности.

Отметим тот факт, что если обратная дробная черта предшествует символу, не являющемуся управляющей

последовательностью (т.е. не включенному в табл.4) и не являющемуся цифрой, то эта черта

игнорируется, а сам символ представляется как литеральный.

Кроме определения управляющей последовательности, символ обратной дробной черты (\) используется

также как символ продолжения. Если за (\) следует (\n), то оба символа игнорируются, а следующая

строка является продолжением предыдущей. Это свойство может быть использовано для записи длинных

строк.

Из символов алфавита формир-ся лексемы языка (слова) – min-ые значимые ед-цы текста в программе: ID, ключевые слова, знаки операций, константы, разделители (скобки, точка, запятая,)

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

символа может использоваться символ подчеркивание (_). Два идентификатора, для образования которых

используются совпадающие строчные и прописные буквы, считаются различными. Например: abc, ABC,

A128B, a128b.

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

идентификаторе, хотя значимыми являются первые 31 символ. Идентификатор создается на этапе

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

последующих операторах разрабатываемой программы. Следует отметить важные особенности при выборе идентификатора.

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

использовать на компьютерах других типов.

В-третьих, ID переменной обычно пишется строчной буквой, ID константы – прописными. Если ID состоит из нескольких слов, то принято либо разделять слова символом (_) подчеркив-я, либо писать каждое слово с большой буквы.

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

auto double int struct break else long switch register tupedef char extern return void case float unsigned default for signed union do if sizeof volatile continue enum short while

Кроме того зарезервированными словами являются:

_asm, fortran, near, far, cdecl, huge, paskal, interrupt.

Ключевые слова far, huge, near позволяют определить размеры указателей на области памяти. Ключевыеслова _asm, cdelc, fortran, pascal служат для организации связи с функциями, написанными на других языках, а также для использования команд языка ассемблера непосредственно в теле разрабатываемой программы на языке С.

Ключевые слова не м/ б использованы в качестве ID.

Константы и переменные

(3) Константы (литералы) – фиксированные величины, которые не могут быть изменены в программе. В языке В языке С константами явл: самоопределенные, арифметические, символьные и строковые данные, ID массивов и функций и эл-ты перечислений.

Арифметические константы м/б целого и вещественного типа. Целочисленные константы подраздел. на десятичные, 8-ричные и 16-ричные.

Десятичная константа состоит из одной или нескольких десятичных цифр, причем первая цифра не

должна быть нулем (в противном случае число будет воспринято как восьмеричное). От 0 до 9.

Восьмеричная константа состоит из последов-ти цифр от 0 до 7, первой из кот не д/б 0.

 

16-ричная константа начинается с обязательной последовательности 0х или 0Х и содержит

одну или несколько шестнадцатеричных цифр (цифры представляющие собой набор цифр шеснадцатеричной

системы счисления: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F).

Каждой целой константе присваивается тип, определяющий преобразования, которые должны быть

выполнены, если константа используется в выражениях. Тип константы определяется следующим образом:

- десятичные константы рассматриваются как величины со знаком, и им присваивается тип int (целая) или long (длинная целая) в соответствии со значением константы. Если константа меньше 32768, то ей присваивается тип int в противном случае long.

- восьмеричным и шестнадцатеричным константам присваивается тип int, unsigned int (беззнаковая

целая), long или unsigned long в зависимости от значения константы согласно табл 8.

 

Для того чтобы любую целую константу определить типом long, достаточно в конце константы поставить

букву "l" или "L". Пример:

5l, 6l, 128L, 0105L, OX2A11L.

Константы вещественного типа м размещ-ся в памяти по формату double, а во внешнем представлении м/и 2 формы: - с фиксированной 10-ичной точкой, - с плавающей 10-ичной точкой.

Символьная константа - представляется символом, заключенном в апострофы. Также исп-ся спец послед-ти символов, т.е. управляющие послед-ти, основные из кот:

’\n’ - символ новой строки

’\t’ – горизонтальная табуляция

‘\0’ – нулевой символ, т.е. пусто.

Символьные константы имеют тип int и при преобразовании типов дополняются знаком.

Строковая константа (литерал) - последовательность символов (включая строковые и прописные буквы

русского и латинского, а также цифры), заключенные в кавычки ("). Например: "Школа N 35", "город

Тамбов", "YZPT КОД".

Отметим, что все управляющие символы, кавычка ("), обратная дробная черта (\) и символ новой строки в строковом литерале и в символьной константе представляются соответствующими управляющими

последовательностями. Каждая управляющая последовательность представляется как один символ.

Например, при печати литерала "Школа \n N 35" его часть "Школа" будет напечатана на одной строке,

а вторая часть "N 35" на следующей строке.

Символы строкового литерала сохраняются в области оперативной памяти. В конец каждого строкового

литерала компилятором добавляется нулевой символ, представляемый управляющей последовательностью

\0.

Строковый литерал имеет тип char[]. Это означает, что строка рассматривается как массив символов.

Отметим важную особенность, число элементов массива равно числу символов в строке плюс 1, так как

нулевой символ (символ конца строки) также является элементом массива. Все строковые литералы

рассматриваются компилятором как различные объекты. Строковые литералы могут располагаться на

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

клавиши ввод. Обратная черта с символом новой строки игнорируется компилятором, что приводит к

тому, что следующая строка является продолжением предыдущей. Например:

"строка неопределенной \n

длины"

полностью идентична литералу

"строка неопределенной длинны"

Для сцепления строковых литералов можно использовать символ (или символы) пробела. Если в

программе встречаются два или более строковых литерала, разделенные только пробелами, то они

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

 

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

программой. Все переменные перед их использованием должны быть объявлены.

 

5.



Поделиться:


Последнее изменение этой страницы: 2016-04-07; просмотров: 272; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

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