sem07 (1114915)
Текст из файла
1Занятие №71.1 Вычисление выраженийРассмотрим некоторые особенности вычисления выражений в языке Си.1.1.1 Преобразования типов при вычислении выраженийПеред вычислением арифметических операций транслятор может выполнять два действия с аргументами: целочисленное повышение (integer promotion) и балансировка.Рангом целого типа назовём число согласно таблице 1:012345_Boolchar, unsigned char, signed charshort, unsigned shortint, unsigned intlong, unsigned longlong long, unsigned long longТаблица 1: Ранги целых типовЦелочисленное повышение выполняется для аргументов типов _Bool, char,unsigned char, signed char, short, unsigned short, перечислимых типов, представляемых указанными выше целочисленными типами, и битовых полей.
Целочисленноеповышение выполняется при передаче параметров, если соответствующий тип формальногопараметра не задан, а также для аргументов операций, за исключением операции sizeof.Если тип аргумента, для которого выполняется целочисленное повышение, таков, что любое значение этого типа имеет представление в типе int, результат целочисленного повышения имеет тип int, а в противном случае результат целочисленного повышения имеет типunsigned int.
Практически это значит, что тип результата при выполнении целочисленного повышения зависит от размеров целых типов в данном компиляторе языка Си. Например, если размер типа char — 8 бит, short — 16 бит, int — 32 бита, то результат целочисленного повышения всегда имеет тип int. Для архитектуры с размером типов short иint 16 бит тип short повышается в тип int, а тип unsigned short — в тип unsignedint.Балансировка.
В случае вычисления инфиксного выражения, которое имеет два арифметических операнда, транслятор определяет тип выражения с помощью балансировки типов операндов. Для балансировки типов транслятор применяет следующие правила.Для комплексного типа назовём соответствующим вещественным типом тип, набазе которого построен данный комплексный тип. Наприме, для типа float _Complexсоответствующим вещественным типом будет тип float.
Для всех прочих типов соответствующий вещественный тип — это он сам.• Если соответствующий вещественный тип одного из операндов — long double,то соответствующий вещественный тип другого операнда преобразовывается в longdouble. Если после этого один из операндов имеет тип _Complex long double,то и другой операнд преобразовывается в тип _Complex long double. Таким образом, например, сложение аргумента типов _Complex float и long double дастрезультат типа _Complex long double.1• Иначе если соответствующий вещественный тип одного из операндов — double, тосоответствующий вещественный тип другого операнда преобразовывается в double.Если после этого один из операндов имеет тип _Complex double, то и другой операнд преобразовывается в тип _Complex double.• Иначе если соответствующий вещественный тип одного из операндов — float, то соответствующий вещественный тип другого операнда преобразовывается в float.
Если после этого один из операндов имеет тип _Complex float, то и другой операндпреобразовывается в тип _Complex float.• Иначе над обоими аргументами выполняется целочисленное повышение. Далее дляопределения типа аргументов и типа результата используются следующие правила.– Если типы аргументов совпадают, дальнейших преобразований не производится.– Иначе если оба типа аргументов — знаковые, или оба типа аргументов — беззнаковые, в качестве балансированного типа выбирается тот тип аргумента, рангкоторого выше. Так, при сложении аргументов типа int и long результат будетиметь тип long независимо от размера каждого из типов.– Иначе если ранг типа аргумента, имеющего беззнаковый тип, не ниже ранга аргумента со знаковым типом, балансированный тип будет тип аргумента беззнакового типа. Например, при сложении аргументов типа int и unsigned longрезультат будет иметь тип unsigned long.– Иначе если тип операнда, имеющего знаковый тип, может представить все значения типа другого операнда, тогда балансированным типом будет знаковый тип.Например, на архитектуре с размером типа long 32 бита и размером типа longlong 64 бита, результат сложения аргументов типа unsigned long и longlong будет иметь тип long long.– Иначе балансированными типом будет беззнаковый тип, соответствующий знаковому типу.
Например, на архитектуре с размером типов int и long 32 бита,результат сложения аргументов типа unsigned int и long будет иметь типunsigned long.Каждый из операндов преобразовывается в балансированный тип, арифметическая операция выполняется над значениями одинакового типа, и результат операции имеет балансированный тип.Для вычислений с плавающей точкой может использоваться вещественный тип с большей точностью, чем требуется типом аргументов.
Соответственно, промежуточные результаты могут храниться в этом типе. Это, однако, не изменяет балансированных типов аргументовопераций.Например, в предыдущих стандартах Си требовалось, чтобы вычисления с плавающейточкой велись в типе не менее точном, чем double.
Сейчас это требование снято. С другойстороны, на архитектуре i386 вычисления с плавающей точкой часто ведутся в типе longdouble, так как в регистрах FPU значения хранятся в типе long double. Но если длявычислений с плавающей точкой используются инструкции SSE/SSE2, то используемыйтип совпадает с типом выражение, то есть для сложения двух аргументов типа float используется инструкция сложения аргументов типа float.2Поскольку результат вычисления выражения с плавающей точкой зависит от порядкавыполнения операций и от типов промежуточных значений, на детали выполнения операцийс плавающей точкой необходимо обращать внимание.1.1.2 Порядок вычисления выражения и побочные эффектыПорядок, в котором транслятор вычисляет подвыражения неопределён и зависит от реализации.
Например, операторy = *p++;может быть эквивалентно либоtemp = p; p += 1; y = *temp;либоy = *p; p += 1;Если в программе встретилось выражениеf() + g()компилятор может расположить вызовы функций f и g в произвольном порядке.При вызове функции, например f(a, b), компилятор может вычислять выражения впроизвольном порядке.Порядок вычисления выражения важен, когда выражение имеет некоторый побочныйэффект, например, заносит значение в переменную, либо модифицирует состояние файла.Программа на Си содержит точки согласования. В точках согласования точно известно, какие побочные эффекты имели место, а какие должны произойти. Например, каждоевыражение, записанное как оператор имеет точку согласования в конце.
Гарантируется, чтов фрагментеy = 37;x += y;значение 37 будет помещено в y до того, как значение y будет использовано при вычислении x.Точки согласования могут находится внутри выражения. Операции «запятая», вызовфункции, логическое «и», логическое «или» содержат точки согласования. Например,if ((c = getchar()) != EOF && isprint(c))isprint(c) будет вычислено только после того, как новое значение, возвращённоеgetchar(), будет занесено в переменную c.Между двумя точками согласования один и тот же объект может модифицироватьсятолько один раз, и значение, читаемое из модифицируемого объекта может использоваться только для вычисления нового значения этого объекта.Например,val = 10 * val + (c - ’0’); // хорошоi= ++i + 2;// плохо31.2 Инициализация составных типовМассивы, структуры и перечисления точно также, как и простые типы могут быть проинициализированы в точке определения.
Массивы типов char, signed char, unsignedchar могут быть проинициализированы строкой. Для одномерного массива произвольноготипа инициализация выглядит следующим образом:<тип> <имя>[<размер>] = { <зн. 1>, <зн. 2>, ... <зн.
K> };Все инициализирующие значения должны иметь тип, совпадающий с типом массива. Их недолжно быть больше, чем размер массива, если их меньше, чем размер массива, оставшиесяэлементы инициализируются по умолчанию. Например,char str[20] = { ’a’, ’ ’, ’s’, ’t’, ’r’, ’i’, ’n’, ’g’, ’\0’ };Если массив содержит инициализацию, тогда размер массива может быть опущен. Он будетвычислен по количеству инициализирующих элементов.Структура инициализируется похожим образом.<тип> <имя> = { <зн. 1>, <зн.
2>, ..., <зн. K>};В этом случае полям структуры последовательно присваиваются указанные значения. Уобъединений может быть проинициализирован только первый элемент.Если массив сам имеет тип массива (многомерный массив), или тип структуры, илиструктура имеет поля типа массива или структуры, инициализаторы могут быть вложенными.Напримерstruct circle { double x, y, r; };struct circle cc[2] = {{1.0, 2.0}, {1.3,2.0,0.4}};Если фигурные скобки, отделяющие внутренние инициализаторы, опускаются, инициализация идёт подряд, переходя при необходимости границы типов. Например, если в указанном выше примере опустить внутренние фигурные скобки, cc[1] пример значение{1.0,2.0,1.3}, а cc[2] — {2.0,0.4,0.0} (если переменная cc — глобальная).Обратите внимание, что если инициализирована только часть элементов локального массива, значение остальных элементов массива останется неопределённым.
В следующем примереvoid func(void){int x[10] = { 0, 0 };}значение элементов x[0] и x[1] будет установлено равным 0, а значениеостальных элементов — неопределено!Стандарт C99 допускает инициализацию локальных переменных структурного и массивового типов, в которой иницализирующие выражения не являются константными. Например, следующий пример допустим в C99, но не допустим в C90.void func(double x, double y){struct circle cc = { x, y, x + y };}Массивы переменного размера, однако, не могут быть проинициализированы.4void func(int n){int a[n] = { 1 }; // неверно!!!}В стандарте C99 поддерживается явное указание имени поля или индекса массива приинициализации.
Характеристики
Тип файла PDF
PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.
Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.