ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 01.03.2019
Просмотров: 1193
Скачиваний: 2
for (i=1, j=2; i<n; j++,i++) …
Преобразование типов
Если в выражении появляются операнды различных типов, то они преобразуются к некоторому общему типу, при этом к каждому арифметическому операнду применяется такая последовательность правил:
Если один из операндов в выражении имеет тип long double, то остальные тоже преобразуются к типу long double.
В противном случае, если один из операндов в выражении имеет тип double, то остальные тоже преобразуются к типу double.
В противном случае, если один из операндов в выражении имеет тип float, то остальные тоже преобразуются к типу float.
В противном случае, если один из операндов в выражении имеет тип unsigned long, то остальные тоже преобразуются к типу unsigned long.
В противном случае, если один из операндов в выражении имеет тип long, то остальные тоже преобразуются к типу long.
В противном случае, если один из операндов в выражении имеет тип unsigned, то остальные тоже преобразуются. к типу unsigned.
В противном случае все операнды преобразуются к типу int. При этом тип char преобразуется в int со знаком; тип unsigned char в int, у которого старший байт всегда нулевой; тип signed char в int, у которого в знаковый разряд передается знак из сhar; тип short в int (знаковый или беззнаковый).
Предположим, что вычислено значение некоторого выражения в правой части оператора присваивания. В левой части оператора присваивания записана некоторая переменная, причем ее тип отличается от типа результата в правой части. Здесь правила преобразования очень простые: значение справа от оператора присваивания преобразуется к типу переменной слева от оператора присваивания. Если размер результата в правой части больше размера операнда в левой части, то старшая часть этого результата будет потеряна.
В языке Си можно явно указать тип любого выражения. Для этого используется операция преобразования ("приведения") типа. Она применяется следующим образом:
(тип) выражение
(здесь можно указать любой допустимый в языке Си тип).
Рассмотрим пример:
int a = 30000;
float b;
........
b = (float) a * 12;
(переменная a целого типа явно преобразована к типу float; если этого не сделать, то результат будет потерян, т.к. a * 12 > 32767).
Преобразование типа также может использоваться для преобразования типов аргументов при вызове функций.
13. операцию присваивания
Охарактеризуем основные операции языка Си. Сначала рассмотрим одну из них - операцию присваивания (=). Выражение вида
х = у;
присваивает переменной х значение переменной у. Операцию "=" разрешается использовать многократно в одном выражении, например:
x = y = z = 100;
Рассмотрим стандартный оператор присваивания в си (операции присваивания в языке программирования C ни чем не отливаются от операторов присваивания в таких языках, как php или паскаль)
i = i + 5 (пример 1)
Это выражение в буквальном смысле означает: «Извлечь переменную i, прибавить к переменной i число 5, и записать получившийся результат в переменную i».
Подобная запись логична и понятна для пользователя, который читает программу на C, однако в некоторых случая она может быть чересчур громоздка. Рассмотрим такое выражение:
abs[xwt[32+y]-xwt[285*x]-ads[32-z]] = abs[xwt[32+y]-xwt[285*x]-ads[32-z]] + 5 (пример 2)
Согласитесь, что запись выглядит менее читабельно, чем в первом примере.
В качестве оператора присваивания в языке си предпочтительнее использовать такую запись: i + = 5,
Которая эквивалентна записи i = i + 5.
Наш нечитабельный пример, в левой части которого стояло математическое выражение, теперь можно переписать в сокращенном виде: abs[xwt[32+y]-xwt[285*x]-ads[32-z]] + = 5
В этой конструкции знак «+=» — это оператор присваивания в языке си.
В операциях, где присутствуют 2 аргумента по обе стороны от знака «=» (в левой и правой частях), возможны также и другие операторы присваивания. Вот они: +—*/%>><<&/\|
Выражения с этими знаками записываются так же, как и операция присваивания со сложением. Рассмотрим эти операторы присваивания подробнее:
a += b эквивалентно присваиванию со сложением: a = a + b
a -= b эквивалентно присваиванию с вычитанием: a = a — b
a *= b эквивалентно присваиванию с умножением: a = a * b
a /= b эквивалентно присваиванию с делением: a = a / b
a %= b эквивалентно присваиванию с остатком от деления: a = a % b
a >>= b эквивалентно присваиванию со сдвигом вправо: a = a >> b
a <<= b эквивалентно присваиванию со сдвигом влево: a = a << b
a &= b эквивалентно присваиванию с поразрядным И: a = a & b
a /\ = b эквивалентно присваиванию с поразрядным исключающим ИЛИ: a = a /\ b
a |= b эквивалентно присваиванию с поразрядным включающим ИЛИ: a = a | b
14 Оператор while формально записывается в таком виде:
while (выражение) тело_цикла
Выражение в скобках может принимать ненулевое (истинное) или нулевое (ложное) значение. Если оно истинно, то выполняется тело цикла и выражение вычисляется снова. Если выражение ложно, то цикл while заканчивается.
15 Оператор do-while формально записывается следующим образом:
do {тело_цикла} while (выражение);
Основным отличием между циклами while и do - while является то, что тело в цикле do - while выполняется по крайней мере один раз. Тело цикла будет выполняться до тех пор, пока выражение в скобках не примет ложное значение. Если оно ложно при входе в цикл, то его тело выполняется ровно один раз.
Допускается вложенность одних циклов в другие, т.е. в теле любого цикла могут появляться операторы for, while и do - while.
В теле цикла могут использоваться новые операторы break и continue. Оператор break обеспечивает немедленный выход из цикла, оператор continue вызывает прекращение очередной и начало следующей итерации.
16 Операторы цикла for
Циклы организуются, чтобы выполнить некоторый оператор или группу операторов определенное число раз. В языке Си три оператора цикла: for, while и do - while. Первый из них формально записывается, в следующем виде:
for (выражение_1; выражение_2; выражение_3) тело_цикла
Тело цикла составляет либо один оператор, либо несколько операторов, заключенных в фигурные скобки { ... } (после блока точка с запятой не ставится). В выражениях 1, 2, 3 фигурирует специальная переменная, называемая управляющей. По ее значению устанавливается необходимость повторения цикла или выхода из него.
Выражение_1 присваивает начальное значение управляющей переменной, выражение_З изменяет его на каждом шаге, а выражение_2 проверяет, не достигло ли оно граничного значения, устанавливающего необходимость выхода из цикла.
Примеры:
for (i = 1; i < 10; i++)
{ ...
}
for (сh = 'a'; ch != 'p';) scanf ("%c", &ch);
/* Цикл будет выполняться до тех пор, пока с клавиатуры
не будет введен символ 'p' */
Любое из трех выражений в цикле for может отсутствовать, однако точка с запятой должна оставаться. Таким образом, for ( ; ; ) {...} - это бесконечный цикл, из которого можно выйти лишь другими способами.
В языке Си принято следующее правило. Любое выражение с операцией присваивания, заключенное в круглые скобки, имеет значение, равное присваиваемому. Например, выражение (а=7+2) имеет значение 9. После этого можно записать другое выражение, например: ((а=7+2)<10), которое в данном случае будет всегда давать истинное значение. Следующая конструкция:
((сh = getch( )) == 'i')
позволяет вводить значение переменной сh и давать истинный результат только тогда, когда введенным значением является буква 'i'. В скобках можно записывать и несколько формул, составляющих сложное выражение. Для этих целей используется операция запятая. Формулы будут вычисляться слева направо, и все выражение примет значение последней вычисленной формулы. Например, если имеются две переменные типа char, то выражение
z = (х = у, у = getch( ));
определяет следующие действия: значение переменной у присваивается переменной х; вводится символ с клавиатуры и присваивается переменной у; z получает значение переменной у. Скобки здесь необходимы, поскольку операция запятая имеет более низкий приоритет, чем операция присваивания, записанная после переменной z. Операция запятая находит широкое применение для построения выражений цикла for и позволяет параллельно изменять значения нескольких управляющих переменных.
Допускаются вложенные конструкции, т.е. в теле некоторого цикла могут встречаться другие операторы for.
17 -18 Операторы условных и безусловных переходов
Для организации условных и безусловных переходов в программе на языке Си используются операторы: if - else, switch и goto. Первый из них записывается следующим образом:
if (проверка_условия) оператор_1; else оператор_2;
Если условие в скобках принимает истинное значение, выполняется оператор_1, если ложное - оператор_2. Если вместо одного необходимо выполнить несколько операторов, то они заключаются в фигурные скобки. В операторе if слово else может отсутствовать.
В операторе if - else непосредственно после ключевых слов if и else должны следовать другие операторы. Если хотя бы один из них является оператором if, его называют вложенным. Согласно принятому в языке Си соглашению слово else всегда относится к ближайшему предшествующему ему if.
Оператор switch позволяет выбрать одну из нескольких альтернатив. Он записывается в следующем формальном виде:
switch (выражение)
{
case константа_1: операторы_1;
break;
case константа_2: операторы_2;
break;
........ ........
default: операторы_default;
}
Здесь вычисляется значение целого выражения в скобках (его иногда называют селектором) и оно сравнивается со всеми константами (константными выражениями). Все константы должны быть различными. При совпадении выполнится соответствующий вариант операторов (один или несколько операторов). Вариант с ключевым словом default реализуется, если ни один другой не подошел (слово default может и отсутствовать). Если default отсутствует, а все результаты сравнения отрицательны, то ни один вариант не выполняется.
Для прекращения последующих проверок после успешного выбора некоторого варианта используется оператор break, обеспечивающий немедленный выход из переключателя switch.
Допускаются вложенные конструкции switch.
Рассмотрим правила выполнения безусловного перехода, который можно представить в следующей форме:
goto метка;
Метка - это любой идентификатор, после которого поставлено двоеточие. Оператор goto указывает на то, что выполнение программы необходимо продолжить начиная с оператора, перед которым записана метка. Метку можно поставить перед любым оператором в той функции, где находится соответствующий ей оператор goto. Ее не надо объявлять.
19
Оператор continue (C)
Оператор continue передает элемент управления в следующую итерацию ближайшего внешнего оператора do, for или while, в которой она отображается, минуя все оставшиеся операторы в теле оператора do, for или while.
Синтаксис
jump-statement:
continue;
Следующая итерация оператора do, for или while определяется следующим образом.
В операторе do или while следующая итерация начинается с повторного вычисления выражения оператора do или while.
Оператор continue в операторе for приводит к вычислению выражения цикла оператора for. Затем компилятор повторно вычисляет условное выражение и в зависимости от результата либо завершает, либо выполняет итерацию тела оператора. Дополнительные сведения об операторе for и его нетерминальных символах см. в разделе Оператор for.
Ниже приводится пример оператора continue.
while ( i-- > 0 )
{
x = f( i );
if ( x == 1 )
continue;
y += x * x;
}
В этом примере тело оператора выполняется при i больше 0. Для первой переменной f(i) присваивается значение x; затем, если x равно 1, выполняется оператор continue. Остальные операторы в теле игнорируются, и выполнение возобновляется в начале цикла с вычисления теста цикла.
19 Указатели и операции с ними
Указатели - это переменные, показывающие место или адрес памяти, где расположены другие объекты (переменные, функции и др.). Так как указатель содержит адрес некоторого объекта, то через него можно обращаться к этому объекту.
Унарная операция & дает адрес объекта, поэтому оператор
у = &х;
присваивает адрес переменной х переменной у. Операцию & нельзя применять к константам и выражениям; конструкции вида &(х+7) или &28 недопустимы.
Унарная операция * воспринимает свой операнд как адрес некоторого объекта и использует этот адрес для выборки содержимого, поэтому оператор
z = *y;
присваивает z значение переменной, записанной по адресу у. Если
y = &x;
z = *у;
то z = x.
Объекты, состоящие из знака * и адреса (например, *а), необходимо определить. Делается это, например, так:
int *а, *b, *с;
char *d;
Определение вида char *d говорит о том, что значение, записанное по адресу d, имеет тип char.
Указатели могут встречаться и в выражениях. Если у - указатель на целое, т.е. имело место объявление int *у, то *у может появиться там же, где и любая другая переменная, не являющаяся указателем. Таким образом, следующие выражения вполне допустимы:
*у = 7;
*x *=5;
(*z)++;
Первое из них заносит число 7 в ячейку памяти по адресу у, второе увеличивает значение по адресу х в пять раз, третье добавляет единицу к содержимому ячейки памяти с адресом z. В последнем случае круглые скобки необходимы, так как операции с одинаковым приоритетом выполняются справа налево. В результате если, например, *z = 5, то (*z)++ приведет к тому, что *z = 6, а *z++ всего лишь изменит сам адрес z (операция ++ выполняется над адресом z, а не над значением *z по этому адресу).
Указатели можно использовать как операнды в арифметических операциях. Если у - указатель, то унарная операция y++ увеличивает его значение; теперь оно является адресом следующего элемента. Указатели и целые числа можно складывать. Конструкция у + n (у - указатель, n - целое число) задает адрес n-гo объекта, на который указывает у. Это справедливо для любых объектов (int, char, float и др.); транслятор будет масштабировать приращение адреса в соответствии с типом, указанным в определении объекта.
Любой адрес можно проверить на равенство (==) или неравенство (!=) со специальным значением NULL, которое позволяет определить ничего не адресующий указатель.
20 Массивы
Массив состоит из элементов одного и того же типа. Ко всему массиву целиком можно обращаться по имени. Кроме того, можно выбирать любой элемент массива. Для этого необходимо задать индекс, который указывает на его относительную позицию. Число элементов массива назначается при его определении и в дальнейшем не изменяется. Если массив объявлен, то к любому его элементу можно обратиться следующим образом: указать имя массива и индекс элемента в квадратных скобках. Массивы определяются так же, как и переменные: