Из Википедии, бесплатной энциклопедии
  (Перенаправлено с Float.h )
Перейти к навигации Перейти к поиску

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

Язык C предоставляет основные арифметические типы, такие как целочисленные и действительные числа , а также синтаксис для построения массивов и составных типов. Заголовки для стандартной библиотеки C , которые будут использоваться с помощью директив include , содержат определения поддерживаемых типов, которые имеют дополнительные свойства, такие как предоставление хранилища точного размера, независимо от языковой реализации на конкретных аппаратных платформах. [1] [2]

Основные типы [ править ]

Основные типы [ править ]

Язык C предоставляет четыре основных арифметических спецификатора типа char , int , float и double , а также модификаторы signed , unsigned , short и long . В следующей таблице перечислены допустимые комбинации при указании большого набора объявлений, зависящих от размера хранилища.

  1. ^ a b c d e Минимальные диапазоны от - (2 n − 1 −1) до 2 n − 1 −1 (например, [−127,127]) происходят из различных целочисленных представлений, разрешенных стандартом ( дополнение до единиц , знак-величина , дополнение до двух ). [4] Однако большинство платформ используют дополнение до двух, подразумевая диапазон от -2 м -1 до 2 м -1 -1 с m ≥ n для этих реализаций, например [-128,127] (SCHAR_MIN = -128 и SCHAR_MAX = 127) для 8-битного знака со знаком .
  2. ^ Эти строки формата также существуют для форматирования текста, но работают с двойным.
  3. ^ a b Верхний регистр отличается от нижнего в выводе. Спецификаторы верхнего регистра создают значения в верхнем регистре, а нижний регистр - в нижнем (% A,% E,% F,% G создают такие значения, как INF, NAN и E (показатель степени) в верхнем регистре)

Фактический размер целочисленных типов зависит от реализации. Стандарт требует только соотношения размеров между типами данных и минимального размера для каждого типа данных:

Требования к соотношению заключаются в том, чтобы long longне было меньше чем long, что не меньше чем int, которое не меньше чем short. Поскольку charразмер всегда является минимальным поддерживаемым типом данных, никакие другие типы данных (кроме битовых полей ) не могут быть меньше.

Минимальный размер для charсоставляет 8 бит, минимальный размер для shortи intсоставляет 16 бит, поскольку longон составляет 32 бита и long longдолжен содержать не менее 64 бит.

Тип intдолжен быть целочисленным типом, с которым целевой процессор наиболее эффективно работает. Это обеспечивает большую гибкость: например, все типы могут быть 64-битными. Однако популярны несколько различных схем целочисленной ширины (моделей данных). Поскольку модель данных определяет способ взаимодействия различных программ, в интерфейсе приложения данной операционной системы используется единообразная модель данных. [6]

На практике charобычно имеет размер 8 бит и shortобычно размер 16 бит (как и их беззнаковые аналоги). Это справедливо для самых разных платформ, таких как SunOS  4 Unix 1990-х годов , Microsoft MS-DOS , современный Linux и Microchip MCC18 для встроенных 8-битных микроконтроллеров PIC . POSIX требует, charчтобы размер был ровно 8 бит.

Различные правила в C стандартной марке unsigned charосновного типа , используемый для массивов , пригодных для хранения произвольных объектов не-битового поля: его отсутствие заполнения бит и ловушки представлений, определение представления объекта , [5] , а также возможность наложения спектров. [7]

Фактический размер и поведение типов с плавающей запятой также зависят от реализации. Единственная гарантия - long doubleне меньше double, что не меньше float. Обычно используются 32-битные и 64-битные двоичные форматы с плавающей запятой IEEE 754 .

Стандарт C99 включает новые реальные типы с плавающей запятой float_tи double_t, определенные в <math.h>. Они соответствуют типам, используемым для промежуточных результатов выражений с плавающей запятой, когда FLT_EVAL_METHODэто 0, 1 или 2. Эти типы могут быть шире, чем long double.

C99 также добавил сложные типы: float _Complex, double _Complex, long double _Complex.

Логический тип [ править ]

C99 добавил логический (истина / ложь) тип _Bool. Кроме того, <stdbool.h>заголовок определяется boolкак удобный псевдоним для этого типа, а также содержит макросы для trueи false. _Boolфункционирует аналогично обычному целочисленному типу, за одним исключением: любые присвоения a _Bool, отличные от 0 (false), сохраняются как 1 (true). Такое поведение существует, чтобы избежать целочисленных переполнений в неявных сужающих преобразованиях. Например, в следующем коде:

беззнаковый  символ  b  =  256 ;if  ( b )  { / * что-то сделать * / }

Переменная bпринимает значение false, если unsigned charимеет размер 8 бит. Это связано с тем, что значение 256 не соответствует типу данных, в результате чего используются его младшие 8 бит, что приводит к нулевому значению. Однако изменение типа заставляет предыдущий код вести себя нормально:

_Bool  b  =  256 ;if  ( b )  { / * что-то сделать * / }

Тип _Bool также гарантирует, что истинные значения всегда равны друг другу:

_Bool  a  =  1 ,  b  =  2 ;if  ( a  ==  b )  { / * что-то сделать * / }

Типы разницы в размере и указателе [ править ]

Спецификация языка C включает typedef s и для представления величин, связанных с памятью. Их размер определяется в соответствии с арифметическими возможностями целевого процессора, а не возможностями памяти, такими как доступное адресное пространство. Оба этих типа определены в заголовке ( в C ++).size_tptrdiff_t<stddef.h>cstddef

size_tпредставляет собой целочисленный тип без знака, используемый для представления размера любого объекта (включая массивы) в конкретной реализации. Оператор sizeof возвращает значение типа . Максимальный размер предоставляется через макроконстанту, которая определяется в заголовке ( заголовок в C ++). гарантированно будет иметь ширину не менее 16 бит. Кроме того, POSIX включает целочисленный тип со знаком той же ширины, что и .size_tsize_tSIZE_MAX<stdint.h>cstdintsize_tssize_tsize_t

ptrdiff_tпредставляет собой целочисленный тип со знаком, используемый для представления разницы между указателями. Гарантируется, что он действителен только для указателей одного и того же типа; вычитание указателей, состоящих из разных типов, определяется реализацией.

Интерфейс к свойствам основных типов [ править ]

Информация о фактических свойствах, таких как размер, основных арифметических типов предоставляется через макроконстанты в двух заголовках: <limits.h>заголовок ( climitsзаголовок в C ++) определяет макросы для целочисленных типов, а <float.h>заголовок ( cfloatзаголовок в C ++) определяет макросы для типов с плавающей запятой. . Фактические значения зависят от реализации.

Свойства целочисленных типов [ править ]

  • CHAR_BIT - размер типа char в битах (не менее 8 бит)
  • SCHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN(C99) - минимально возможное значение подписанных целочисленных типов: подписан полукокс, подписанных короткий, подписанные межды, подписанные долго, подписанные долго долго
  • SCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX(C99) - максимально возможное значение подписанных целочисленных типов: подписан полукокс, подписанных короткий, подписанные межды, подписанные долго, подписанные долго долго
  • UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX(С99) - максимально возможное значение целых беззнаковых типов: беззнаковых символов, без знака Короче говоря, без знака Int, неподписанные долго, без знака долго долго
  • CHAR_MIN - минимально возможное значение char
  • CHAR_MAX - максимально возможное значение char
  • MB_LEN_MAX - максимальное количество байтов в многобайтовом символе

Свойства типов с плавающей запятой [ править ]

  • FLT_MIN, DBL_MIN, LDBL_MIN- минимальное нормализованы положительное значение с плавающей точкой, двойной, двойной длиной соответственно
  • FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN(С11) - минимальное значение положительного поплавка, двойной, двойная длиной соответственно
  • FLT_MAX, DBL_MAX, LDBL_MAX- максимальное конечное значение поплавка, двойной, длинный двойной, соответственно ,
  • FLT_ROUNDS - режим округления для операций с плавающей запятой
  • FLT_EVAL_METHOD (C99) - метод оценки выражений, включающих различные типы с плавающей запятой
  • FLT_RADIX - основание экспоненты в типах с плавающей запятой
  • FLT_DIG, DBL_DIG, LDBL_DIG- число десятичных цифр , которые могут быть представлены без потери точности при обращении, двойной, длинный двойной, соответственно ,
  • FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON- разница между 1,0 и следующим представимым значением поплавка, двойной, длинным двойной, соответственно ,
  • FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG- число FLT_RADIX-BASE цифр с плавающей точкой мантиссы для типов с плавающей точкой, двойной, длинный двойной, соответственно ,
  • FLT_MIN_EXP, DBL_MIN_EXP, LDBL_MIN_EXP- минимальное отрицательное целое число такое , что FLT_RADIXповышается до мощности на единицу меньше числа является нормализованной с плавающей точкой, двойной, длинный двойной, соответственно ,
  • FLT_MIN_10_EXP, DBL_MIN_10_EXP, LDBL_MIN_10_EXP- минимальное отрицательное целое число , такое , что 10 в этой силы является нормализованной с плавающей точкой, двойной, длинный двойной, соответственно ,
  • FLT_MAX_EXP, DBL_MAX_EXP, LDBL_MAX_EXP- максимальное положительное целое число , такое , что FLT_RADIXповышают до мощности на единицу меньше числа является нормализованной с плавающей точкой, двойной, длинный двойной, соответственно ,
  • FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP- максимальное положительное целое число , такое , что 10 в этой силы является нормализованной с плавающей точкой, двойной, длинный двойной, соответственно ,
  • DECIMAL_DIG(C99) - минимальное количество десятичных цифр, при котором любое число самого широкого поддерживаемого типа с плавающей запятой может быть представлено в десятичном виде с точностью до DECIMAL_DIGцифр и считано в исходном типе с плавающей запятой без изменения его значения. DECIMAL_DIGне менее 10.

Целочисленные типы фиксированной ширины [ править ]

Стандарт C99 включает определения нескольких новых целочисленных типов для повышения переносимости программ. [2] Уже доступных базовых целочисленных типов было сочтено недостаточным, поскольку их фактические размеры определяются реализацией и могут различаться в разных системах. Новые типы особенно полезны во встроенных средах, где оборудование обычно поддерживает только несколько типов, и эта поддержка варьируется в зависимости от среды. Все новые типы определены в <inttypes.h>заголовке ( cinttypesзаголовок в C ++), а также доступны в <stdint.h>заголовке ( cstdintзаголовок в C ++). Типы можно сгруппировать в следующие категории:

  • Целочисленные типы точной ширины, которые гарантированно имеют одинаковое количество бит n во всех реализациях. Включается только в том случае, если это доступно в реализации.
  • Целочисленные типы с наименьшей шириной, которые гарантированно будут наименьшим типом, доступным в реализации, который имеет как минимум указанное количество n битов. Гарантированно указывается не менее N = 8,16,32,64.
  • Самые быстрые целочисленные типы, которые гарантированно будут самыми быстрыми целочисленными типами, доступными в реализации, которые имеют как минимум заданное количество n битов. Гарантированно указывается не менее N = 8,16,32,64.
  • Целочисленные типы указателей, которые гарантированно могут содержать указатель. Включается только в том случае, если это доступно в реализации.
  • Целочисленные типы максимальной ширины, которые гарантированно будут наибольшим целочисленным типом в реализации.

В следующей таблице приведены типы и интерфейс для получения сведений о реализации ( n означает количество битов):


Спецификаторы формата printf и scanf [ править ]

<inttypes.h>Заголовка ( cinttypesв C ++) обеспечивает функции , которые повышают функциональность типов , определенных в <stdint.h>заголовке. Он определяет макросы для Printf форматной строки и формата зсапЕ строки спецификаторов , соответствующих типов , определенных в <stdint.h>и несколько функций для работы с intmax_tи uintmax_tтипами. Этот заголовок был добавлен в C99 .

Строка формата printf

Макросы в формате . Здесь {fmt} определяет форматирование вывода и может быть одним из (десятичного), (шестнадцатеричного), (восьмеричного), (беззнакового) и (целого). {тип} определяет тип аргумента и является одним из , , , , , где соответствует числу битов в аргументе.PRI{fmt}{type}dxouinFASTnLEASTnPTRMAXn

Строка формата scanf

Макросы в формате . Здесь {fmt} определяет форматирование вывода и может быть одним из (десятичного), (шестнадцатеричного), (восьмеричного), (беззнакового) и (целого). {тип} определяет тип аргумента и является одним из , , , , , где соответствует числу битов в аргументе.SCN{fmt}{type}dxouinFASTnLEASTnPTRMAXn

Функции

Дополнительные типы с плавающей запятой [ править ]

Подобно целочисленным типам фиксированной ширины, ISO / IEC TS 18661 определяет типы с плавающей запятой для обмена IEEE 754 и расширенные форматы в двоичном и десятичном формате:

  • _FloatN для двоичных форматов обмена;
  • _DecimalN для десятичных форматов обмена;
  • _FloatNx для двоичных расширенных форматов;
  • _DecimalNx для расширенных десятичных форматов.

Структуры [ править ]

Структуры объединяют хранилище нескольких элементов данных потенциально разных типов данных в один блок памяти, на который ссылается одна переменная. В следующем примере объявляется тип данных, struct birthdayсодержащий имя и день рождения человека. За определением структуры следует объявление переменной, Johnкоторая выделяет необходимое хранилище.

структура  день рождения  { имя символа  [ 20 ]; int день ; int месяц ; int год ; };   struct  birthday  John ;

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

Структура, содержащая указатель на структуру собственного типа, обычно используется для построения связанных структур данных :

struct  node  { int  val ; struct  node  * next ; };

Массивы [ править ]

Для каждого типа T, кроме типов void и function, существуют типы «массив Nэлементов типа T» . Массив - это набор значений одного типа, непрерывно хранящихся в памяти. Массив размера Nиндексируется целыми числами от 0до включительно N−1. Вот краткий пример:

int  cat [ 10 ];  // массив из 10 элементов, каждый типа int

Массивы можно инициализировать с помощью составного инициализатора, но не назначать. Массивы передаются функциям путем передачи указателя на первый элемент. Многомерные массивы определяются как «массив массивов…» , и все, кроме самого внешнего измерения, должны иметь размер, постоянный во время компиляции:

int  a [ 10 ] [ 8 ];  // массив из 10 элементов, каждый из которых имеет тип 'массив из 8 элементов int'

Указатели [ править ]

Каждому типу данных Tсоответствует указатель наT тип . Указатель представляет собой тип данных , который содержит адрес места хранения переменной определенного типа. Они объявляются с помощью *декларатора типа asterisk ( ), следующего за базовым типом хранилища и перед именем переменной. Пробелы до или после звездочки не обязательны.

char  * квадрат ; длинный  * круг ; int  * oval ;

Указатели также могут быть объявлены для типов данных указателей, таким образом создавая несколько косвенных указателей, таких как char ** и int *** , включая указатели на типы массивов. Последние менее распространены, чем массив указателей, и их синтаксис может сбивать с толку:

char  * pc [ 10 ];  // массив из 10 элементов 'указателя на char' char  ( * pa ) [ 10 ];  // указатель на массив из 10 элементов char

Для элемента pcтребуется десять блоков памяти размером с указательchar (обычно 40 или 80 байтов на обычных платформах), но элемент paпредставляет собой только один указатель (размер 4 или 8 байтов), а данные, на которые он ссылается, представляют собой массив из десяти байтов. ( ).sizeof *pa == 10

Союзы [ править ]

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

объединение  { int  я ; float  f ; struct  { unsigned  int  u ; двойной  d ; }  s ; }  u ;

Общий размер u- это размер, u.sкоторый является суммой размеров u.s.uи, u.s.dпоскольку sон больше, чем оба iи f. При назначении чему-либо u.iнекоторые части u.fмогут быть сохранены, если они u.iменьше, чем u.f.

Чтение из члена объединения - это не то же самое, что приведение, поскольку значение члена не конвертируется, а просто читается.

Указатели функций [ править ]

Указатели функций позволяют ссылаться на функции с определенной сигнатурой. Например, чтобы сохранить absв переменной адрес стандартной функции my_int_f:

int  ( * my_int_f ) ( int )  =  & abs ; // оператор & можно опустить, но ясно, что здесь используется "адрес" абс

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

Квалификаторы типа [ править ]

Вышеупомянутые типы могут быть дополнительно охарактеризованы квалификаторами типа , что дает квалифицированный тип . По состоянию на 2014 год и C11 в стандарте C есть четыре квалификатора типа: const( C89 ), volatile( C89 ), restrict( C99 ) и _Atomic( C11 ) - последний имеет частное имя, чтобы избежать конфликтов с именами пользователей, [8] но тем более atomicможно использовать обычное имя , если <stdatomic.h>включен заголовок. Из них, constбезусловно, самый известный и наиболее используемый, он появляется в стандартной библиотеке и встречается при любом значительном использовании языка C, который должен удовлетворятьconst-правильность . Другие квалификаторы используются для низкоуровневого программирования и, хотя и широко используются там, редко используются типичными программистами. [ необходима цитата ]

См. Также [ править ]

  • Синтаксис C
  • Неинициализированная переменная
  • Целое число (информатика)

Ссылки [ править ]

  1. ^ Барр, Майкл (2 декабря 2007 г.). «Переносимые целые числа фиксированной ширины на языке C» . Проверено 18 января +2016 .
  2. ^ a b Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 255, § 7.18 Целочисленные типы <stdint.h> .
  3. ^ a b c d e f g h i j Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 22, § 5.2.4.2.1 Размеры целочисленных типов <limits.h> .
  4. ^ Обоснование международного стандарта - Языки программирования - Версия C 5.10 (PDF) . п. 25, § 5.2.4.2.1 Размеры целочисленных типов <limits.h> .
  5. ^ a b Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 37, § 6.2.6.1 Представления типов - Общие .
  6. ^ "64-битные модели программирования: почему LP64?" . Открытая группа . Проверено 9 ноября 2011 года .
  7. ^ ISO / IEC 9899: 1999 спецификация, TC3 (PDF) . п. 67, § 6.5 Выражения .
  8. ^ C11: Новый стандарт C , Томас Слива