
- •Введение
- •Язык программирования Си Элементы языка программирования.
- •Множества символов
- •Буквы и цифры
- •Пробельные символы
- •Знаки пунктуации и специальные символы
- •Операции
- •Константы
- •Целые константы
- •Константы с плавающей точкой
- •Константа-символ
- •Строковые литералы
- •Идентификаторы
- •Ключевые слова
- •Комментарии
- •Лексемы
- •Структура программы
- •Исходная программа
- •Исходные файлы
- •Выполнение программ
- •Время жизни и видимость
- •Классы имен
- •Объявления
- •Спецификаторы типов
- •Область значений величин
- •Деклараторы
- •Деклараторы массивов, функций и указателей
- •Составные деклараторы
- •Объявления переменной
- •Объявление простой переменной
- •Объявление перечисления
- •Объявления структур
- •Объявление совмещений
- •Объявление массива
- •Объявление указателей
- •Объявление функций
- •Объявление классов
- •Классы памяти
- •Объявления переменной на внешнем уровне
- •Объявление переменной на внутреннем уровне
- •Объявление функции на внешнем и внутреннем уровнях
- •Инициализация
- •Базовые типы и типы указателей
- •Составные типы
- •Строковые инициализаторы
- •Объявления типов
- •Типы структур, совмещений и перечислений
- •Объявления typedef
- •Имена типов
- •Выражения и присваивания
- •Введение
- •Операнды
- •Константы
- •Идентификаторы
- •Вызовы функций
- •Индексные выражения
- •Выражение выбора структурного элемента
- •Выражения с операциями
- •Выражения в скобках
- •Type-cast выражения
- •Константные выражения
- •Операции
- •Обычные арифметические преобразования.
- •Операции дополнения
- •Операция адресации и разадресации
- •Операция sizeof
- •Мультипликативные операции
- •Аддитивные операции
- •Операции сдвига
- •Операции отношений
- •Побитовые операции
- •Логические операции
- •Операция последовательного вычисления
- •Условная операция
- •Операции присваивания
- •Lvalue-выражения
- •Унарные инкремент и декремент
- •Простое присваивание
- •Составное присваивание
- •Старшинство и порядок выполнения
- •Побочные эффекты
- •Преобразования типов
- •Преобразование типов при присваивании
- •Преобразования type-cast
- •Преобразования, выполняемые операциями
- •Преобразования при вызовах функций
- •Операторы
- •Введение
- •Оператор break
- •Составной оператор
- •Оператор continue
- •Оператор do
- •Оператор-выражение
- •Оператор for
- •Goto и помеченные операторы
- •Оператор if
- •Оператор null
- •Оператор return
- •Оператор switch
- •Оператор while
- •Функции
- •Введение
- •Определение функции
- •Класс памяти
- •Тип возврата
- •Формальные параметры
- •Тело функции
- •Объявления функции
- •Вызовы функций
- •Фактические аргументы
- •Вызовы с переменным числом аргументов
- •Рекурсивные вызовы
- •Директивы препроцессора и указания компилятору
- •Поименованные константы и макросы
- •Директива # define
- •Директива #undef
- •#Include файлы
- •Условная компиляция
- •Директивы #if, #elif, #else, #endif
- •Директивы #ifdef и #ifndef
- •Управление нумерацией строк
Оператор return
Синтаксис:
return [<expression>];
Выполнение:
Оператор return заканчивает выполнение функции, в которой он появляется, и возвращает управление в вызывающую функцию. Управление передается в вызывающую функцию в точку, непосредственно следующую за вызовом. Значение выражения <expression>, если оно есть, возвращается в вызывающую функцию. Если выражение <expression> опущено, то возвращаемая функцией величина не определена.
Пример
main ()
{
void draw (int,int);
long sq (int);
.
.
.
y=sq (x);
draw (x,y);
.
.
.
}
long sq (x)
int x;
{
return (x*x);
}
void draw (x,y)
int x,y;
{
.
.
.
return;
}
Функция main вызывает две функции, sq и draw. Функция sq возвращает значение x*x в main. Величина возврата присваивается переменной y. Функция draw объявляется как функция void и не возвращает значения. Попытка присвоить возвращаемое значение функции draw привело бы к ошибке.
Выражение <expression> оператора return заключено в скобки, как показано в примере. Язык не требует скобок.
Отсутствие оператора return
Если оператор return не появился в определении функции, то управление автоматически передается в вызывающую функцию после выполнения последнего оператора в вызванной функции. Значение возврата вызванной функции при этом не определено. Если значение возврата не требуется, то функция должна быть объявлена с типом возврата void.
Оператор switch
Синтаксис:
switch (<expression>)
{
[<declaration>]
.
.
.
[case <constant-expression>:]
.
.
.
[<statement>]
.
.
.
break;
[case <constant-expression>:]
.
.
.
[<statement>]
.
.
.
[default:
<statement>]
}
Выполнение:
Оператор switch передает управление одному из операторов <statement> своего тела. Оператор, получающий управление, - это тот оператор, чье case-константное выражение <constant-expression> равно значению switch-выражения <expression> в круглых скобках.
Выполнение тела оператора начинается с выбранного оператора и продолжается до конца тела или до тех пор, пока очередной оператор <statement> передает управление за пределы тела.
Оператор default выполнится, если case-константное выражение <constant-expression> не равно значению switch-выражения <expression>. Если default-оператор опущен, а соответствующий case не найден, то выполняемый оператор в теле switch отсутствует. Switch-выражение <expression> - это целая величина размера int или короче. Оно может быть также величиной типа enum. Если <expression> короче чем int, оно расширяется до int.
Каждое case-константное выражение <cjnstant-expression> преобразуется к типу switch-выражения. Значение каждого case-константного выражения должно быть уникальным внутри тела оператора.
Case и default метки в теле оператора switch существенны только при начальной проверке, когда определяется стартовая точка для выполнения тела оператора. Все операторы появляющиеся между стартовым оператором и концом тела, выполняются, не обращая внимания на свои метки, если какой-то из операторов не передает управления из тела оператора switch.
В заголовке составного оператора, формирующего тело оператора switch, могут появиться объявления, но инициализаторы, включенные в объявления, не будут выполнены. Назначение оператора switch состоит в том, чтобы передать управление непосредственно на выполняемый оператор внутри тела, обойдя строки, которые содержат инициализацию.
Примеры:
/***.....* example 1 *.....***/
switch (c)
{
case 'A':
capa++;
case 'a':
lettera++;
default:
total++;
}
/***.....* example 2 *.....***/
switch (i)
{
case -1:
n++;
break;
case 0:
z++;
break;
case 1:
p++;
break;
}
В первом примере все три оператора в теле switch выполняются, если c равно 'A'. Передача управления осуществляется на первый оператор capa++, далее операторы выполняются в порядке их следования в теле.
Если c равно 'a', то переменные lettera и total инкрементируются. Наконец, если c не равно ни 'A' ни 'a', то инкрементируется только переменная total.
Во втором примере в теле switch после каждого оператора следует оператор break. Оператор break осуществляет принудительный выход из switch после выполнения одного из этих операторов. Последний оператор break не является обязательным, поскольку без него управление было бы передано из тела на конец составного оператора, но он включен для единообразия.
Множественные метки
Оператор тела switch может быть помечен множественными метками, как показано в нижеследующем примере:
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f': hexcvt (c);
Хотя любой оператор внутри тела оператора switch может быть помечен, однако не требуется оператора, чтобы появилась метка. Операторы без меток могут быть смешаны с помеченными операторами. Следует помнить, однако, что если switch оператор передал управление одному из операторов своего тела, то все следующие за ним операторы в блоке выполняются, не обращая внимания на свои метки.