Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Сабуров С.В. - Язык программирования C и C++ - 2006

.pdf
Скачиваний:
312
Добавлен:
13.08.2013
Размер:
1.42 Mб
Скачать

Язык программирования Си

Преобразование типов при присваивании

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

Знаковое целое преобразуется к короткому знаковому целому (short signed int) посредством усечения старших битов.

Знаковое целое преобразуется к длинному знаковому целому (long signed int) путем размножения знака влево. Преобразование знаковых целых к плавающим величинам происходит без потери информации, за исключением потери некоторой точности, когда преобразуются величины long в float. При преобразовании знакового целого к беззнаковому целому (unsigned int), знаковое целое преобразуется к размеру беззнакового целого и результат интерпретируется как беззнаковая величина.

Тип unsigned int эквивалентен или unsigned short, или unsigned long типам в зависимости от оборудования. Преобразование из unsigned int производятся как для unsigned short или unsigned long в

зависимости от того, что подходит.

Преобразование плавающих типов

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

Плавающие величины преобразуются к целым типа long. Преобразование к другим целым типам выполняется как для long. Дробная часть плавающей величины отбрасывается при преобразовании к long; если результат слишком велик для long, то результат преобразования неопределен.

Преобразование адресных типов

Указатель на величину одного типа может быть преобразован к указателю на величину другого типа. Результат может быть, однако, неопределенным из за отличия в требованиях к выравниванию и размерам памяти.

77

Язык программирования Си

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

Значение указателя может быть преобразовано к целой величине. Путь преобразования зависит от размера указателя.

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

Если поддерживаются специальные ключевые слова near, far, huge, то может быть сделано неявное преобразование адресных величин. В частности, компилятор может по умолчанию создавать указатели определенного размера и производить преобразования получаемых адресных величин, если в программе не появится forward объявление, переопределяющее это умолчание.

Преобразования других типов

Из определения типа enum следует, что величины enum являются величинами типа int. Поэтому преобразования в и из типа enum осуществляется как для int типов. Тип int эквивалентен типам short или long в зависимости от реализации.

Не допустимы преобразования объектов типа структур и совмещений.

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

Преобразования type!cast

Явное преобразование типа может быть сделано посредством type cast. Преобразования type cast имеют следующую синтаксическую форму:

(<type name)<operand>

78

Язык программирования Си

где <type name> специфицирует особенности типа, а <operand> является величиной, которая должна быть преобразована к специфицированному типу.

Преобразование операнда осуществляется в процессе присвоения его переменной типа <type name>. Правила преобразования для операции присваивания допустимы для преобразований type cast полностью. Имя типа void может быть использовано в операции cast, но результирующее выражение не может быть присвоено любому объекту.

Преобразования, выполняемые операциями

Преобразования, выполняемые операциями Си, зависят от самих операций и от типа операнда или операндов. Многие операции выполняют обычные арифметические преобразования.

Си разрешает некоторую арифметику с указателями. В адресной арифметике целые величины преобразуются к определенным адресам памяти.

Преобразования при вызовах функций

Тип преобразования, выполняемый над аргументами в вызове функции, зависит от того, было ли forward объявление, определяющее типы аргументов для вызываемой функции.

Если forward объявление было и оно включает определение типов аргументов, то компилятор осуществляет контроль типов.

Если forward объявления не было, или если в forward объявлении опущен список типов аргументов, то над аргументами вызываемой функции производятся только обычные арифметические преобразования. Преобразования производятся независимо для каждого аргумента вызова. Смысл этих преобразований сводится к тому, что величины типа float преобразуются к double, величины типов char и short преобразуются к int, величины типов unsigned char и unsigned short преобразуются к unsigned int. Если поддерживаются специальные ключевые слова near, far, huge, то могут быть также сделаны неявные преобразования адресных величин, посылаемых в функцию. Эти неявные преобразования могут быть переопределены заданием в forward объявлении списка типов аргументов, что позволит компилятору выполнить контроль типов.

79

Язык программирования Си

Операторы

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

break <compound> continue do

<expression> for

goto if <null> return switch while

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

break default for return case do goto switch

continue else

if while

Операторами, допустимыми внутри операторов Си, могут быть любые операторы. Оператор, который является компонентом другого оператора, называется «телом» включающего оператора.Часто оператор тело является составным оператором, состоящим из одного или более операторов.

80

Язык программирования Си

Составной оператор ограничивается фигурными скобками. Все другие операторы Си заканчиваются точкой с запятой ;.

Любой из операторов Си может быть спереди помечен меткой, состоящей из имени и двоеточия. Операторные метки опознаются только оператором goto.

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

Оператор break

Синтаксис:

break;

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

Внутри вложенных операторов оператор break завершает только операторы do, for, switch или while. Чтобы передать управление вне вложенной структуры, могут быть использованы операторы return и goto.

Составной оператор

Синтаксис:

[<declaration>]

.

.

.

<statement>

[<statement>]

.

.

.

Действия при выполнении составного оператора состоят в том, что выполнение его операторов осуществляется в порядке их появления, за исключением случаев, когда очередной оператор явно передает управление в другое место.

81

Язык программирования Си

Помеченные операторы

Подобно другим операторам Си, любой оператор в составном операторе может быть помечен. Поэтому передача управления внутрь составного оператора возможна. Однако, передачи управления внутрь составного оператора опасны, когда составной оператор содержит объявления, которые инициализируют переменные. Объявления в составном операторе предшествуют выполняемым операторам, так что передача управления непосредственно на выполняемый оператор внутри составного оператора минует инициализацию. Результат будет непредсказуем.

Оператор continue

Синтаксис:

continue;

Оператор continue передает управление на следующую итерацию в операторах цикла do, for, while, в которых он может появиться. Оставшиеся операторы в теле вышеперечисленных циклов при этом не выполняются. Внутри do или while циклов следующая итерация начинается с перевычисления выражения do или while операторов. Для оператора for следующая итерация начинается с выражения цикла оператора for.

Оператор do

Синтаксис: do <statement>

while (<expression>);

Тело оператора do выполняется один или несколько раз до тех пор, пока выражение <expression> станет ложным (равным нулю). Вначале выполняется оператор <statement> тела, затем вычисляется выражение <expression>. Если выражение ложно, то оператор do завершается и управление передается следующему оператору в программе. Если выражение истинно (не равно нулю), то тело оператора выполняется снова и снова проверяется выражение. Выполнение тела оператора продолжается до тех пор, пока выражение не станет ложным. Оператор do может также завершить выполнение при выполнении операторов break, goto или return внутри тела оператора do.

82

Язык программирования Си

Оператор!выражение

Синтаксис:

expression;

Выражение <expression> вычисляется в соответствии с правилами «Выражения и присваивания».

В Си присваивания являются выражениями. Значением выражения является значение, которое присваивается.

Оператор for

Синтаксис:

for ([<init expression>];[<cond expression>];[<loop exp>]) statement

Тело оператора for выполняется нуль и более раз, до тех пор, пока условное выражение <cond expression> не станет ложным. Выражения инициализации <init expression> и цикла <loop expression> могут быть использованы для инициализации и модификации величин во время выполнения оператора for.

Первым шагом при выполнении оператора for является вычисление выражения инициализации, если оно имеется. Затем вычисление условного выражения с тремя возможными результатами:

1.Если условное выражение истинно (не равно нулю), то выполняется тело оператора. Затем вычисляется выражение цикла (если оно есть). Процесс повторяется снова с вычислением условного выражения.

2.Если условное выражение опущено, то его значение принимается за истину и процесс выполнения продолжается, как показано выше. В этом случае оператор for может завершиться только при выполнении в теле оператора операторов break, goto, return.

3.Если условное выражение ложно, то выполнение оператора for заканчивается и управление передается следующему оператору в программе.

Оператор for может завершиться при выполнении операторов break, return, goto в теле оператора.

Оператор goto передает управление непосредственно на оператор, помеченный <name>. Помеченный оператор выполняется сразу после выполнения оператора goto. Если

83

Язык программирования Си

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

Пример:

if (errorcode>0) goto exit;

.

.

.

exit:return (errorcode);

В примере оператор goto передает управление на оператор, помеченный меткой exit, когда происходит ошибка.

Формат меток

Метка — это простой идентификатор. Каждая метка должна быть отлична от других меток в той же самой функции.

Оператор if

Синтаксис:

if (<expression>) <statement 1> [else

<statement 2>]

Тело оператора if выполняется селективно, в зависимости от значения выражения <expression>. Сначала вычисляется выражение. Если значение выражения истина (не нуль), то выполняется оператор <statement 1>. Если выражение ложно, то выполняется оператор <statement 2>, непосредственно следующий за ключевым словом else. Если выражение <expression> ложно и предложение else ... опущено, то управление передается на выполнение оператора, следующего за

оператором if. Пример: if (i>0) y=x/i; else

84

Язык программирования Си

x=i;

y=f(x);

Вложения

Си не поддерживает оператор else if, но тот же самый эффект достигается посредством сложенных операторов if. Оператор if может быть вложен в предложение if или предложение else другого оператора if. Когда операторы if вкладываются, то используются фигурные скобки, чтобы сгруппировать составные операторы, которые проясняют ситуацию.

Если фигурные скобки отсутствуют, то компилятор может принять неверное решение, сочетая каждое else с более близким if, у которого отсутствует else.

Пример:

/****** example 1 ******/

if (i>0) /* without braces */ if (j>i)

x=j; else x=i;

/****** example 2 ******/

if (i>0) /* with braces */ if (j>1)

x=j;

else x=i;

Оператор null

Синтаксис:

;

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

Пример:

for (i=0; i<10; line [i++]=0)

;

85

Язык программирования Си

Такие операторы, как do, for, if, while, требуют, чтобы в теле оператора был хотя бы один оператор. Оператор null удовлетворяет требованиям синтаксиса в случаях, когда не требуется тела оператора. В приведенном примере третье выражение оператора for инициализирует первые 10 элементов массива line нулем. Тело оператора включает оператор null, т.к. нет необходимости в других операторах.

Помеченный оператор null

Оператор null, подобно любому другому Си оператору, может быть помечен меткой. Чтобы пометить объект, который не является оператором, такой как закрывающаяся фигурная скобка составного оператора, можно вставить перед объектом помеченный оператор null.

Оператор 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;

86

Соседние файлы в предмете Программирование на C++