В языке программирования С , типы данных представляют собой семантику и характеристики хранения элементов данных. Они выражаются в синтаксисе языка в форме объявлений для ячеек памяти или переменных . Типы данных также определяют типы операций или методы обработки элементов данных.
Язык C предоставляет основные арифметические типы, такие как целочисленные и действительные числа , а также синтаксис для построения массивов и составных типов. Заголовки для стандартной библиотеки C , которые будут использоваться с помощью директив include , содержат определения поддерживаемых типов, которые имеют дополнительные свойства, такие как предоставление хранилища точного размера, независимо от языковой реализации на конкретных аппаратных платформах. [1] [2]
Основные типы
Основные типы
Язык C предоставляет четыре основных арифметических спецификатора типа char , int , float и double , а также модификаторы signed , unsigned , short и long . В следующей таблице перечислены допустимые комбинации при указании большого набора объявлений, зависящих от размера хранилища.
Тип | Объяснение | Минимальный размер (бит) | Спецификатор формата |
---|---|---|---|
char | Наименьшая адресуемая единица машины, которая может содержать базовый набор символов. Это целочисленный тип. Фактический тип может быть подписанным или беззнаковым. Он содержит биты CHAR_BIT. [3] | 8 | %c |
signed char | Того же размера, что и char , но с гарантированной подписью. Может содержать как минимум диапазон [-127, +127]. [3] [а] | 8 | %c (или %hhi для числового вывода) |
unsigned char | Имеет тот же размер, что и char , но гарантированно без знака. Содержит как минимум диапазон [0, 255]. [5] | 8 | %c (или %hhu для числового вывода) |
short short int signed short signed short int | Короткий знаковый целочисленный тип. Может содержать как минимум диапазон [-32,767, +32,767]. [3] [а] | 16 | %hi или же %hd |
unsigned short unsigned short int | Короткий беззнаковый целочисленный тип. Содержит как минимум диапазон [0, 65 535]. [3] | 16 | %hu |
int signed signed int | Базовый целочисленный тип со знаком. Может содержать как минимум диапазон [-32,767, +32,767]. [3] [а] | 16 | %i или же %d |
unsigned unsigned int | Базовый беззнаковый целочисленный тип. Содержит как минимум диапазон [0, 65 535]. [3] | 16 | %u |
long long int signed long signed long int | Длинный знаковый целочисленный тип. Способен содержать как минимум диапазон [−2 147 483 647, +2 147 483 647]. [3] [а] | 32 | %li или же %ld |
unsigned long unsigned long int | Длинный беззнаковый целочисленный тип. Может содержать по крайней мере диапазон [0, 4 294 967 295]. [3] | 32 | %lu |
long long long long int signed long long signed long long int | Длинный длинный знаковый целочисленный тип. Способен содержать по крайней мере диапазон [-9,223,372,036,854,775,807, +9,223,372,036,854,775,807]. [3] [a] Указано, начиная с версии стандарта C99 . | 64 | %lli или же %lld |
unsigned long long unsigned long long int | Длинный длинный беззнаковый целочисленный тип. Содержит как минимум диапазон [0, +18,446,744,073,709,551,615]. [3] Указано, начиная с версии стандарта C99 . | 64 | %llu |
float | Реальный тип с плавающей запятой, обычно называемый типом с плавающей запятой одинарной точности. Фактические свойства не указаны (кроме минимальных ограничений); однако в большинстве систем это двоичный формат с плавающей запятой одинарной точности IEEE 754 (32 бита). Этот формат требуется дополнительным Приложением F «Арифметика с плавающей запятой МЭК 60559». | Преобразование из текста: [b]
| |
double | Реальный тип с плавающей запятой, обычно называемый типом с плавающей запятой двойной точности. Фактические свойства не указаны (кроме минимальных ограничений); однако в большинстве систем это двоичный формат с плавающей запятой двойной точности IEEE 754 (64 бита). Этот формат требуется дополнительным Приложением F «Арифметика с плавающей запятой МЭК 60559». |
| |
long double | Реальный тип с плавающей запятой, обычно отображаемый в формат чисел с плавающей запятой повышенной точности . Фактические свойства не указаны. Это может быть формат x86 с плавающей запятой повышенной точности (80 бит, но обычно 96 бит или 128 бит в памяти с байтами заполнения ), не-IEEE « double-double » (128 бит), IEEE 754 с плавающей запятой четверной точности -точечный формат (128 бит) или то же, что и двойной. Подробнее читайте в статье о длинном дабл . | %Lf %LF %Lg %LG %Le %LE %La %LA [c] |
- ^ 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-битного знака со знаком .
- ^ Эти строки формата также существуют для форматирования текста, но работают с двойным.
- ^ 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
, определенные в . Они соответствуют типам, используемым для промежуточных результатов выражений с плавающей запятой, когда
FLT_EVAL_METHOD
это 0, 1 или 2. Эти типы могут быть шире, чем long double
.
C99 также добавил сложные типы: float _Complex
, double _Complex
, long double _Complex
.
Логический тип
C99 добавил логический (истина / ложь) тип _Bool
. Кроме того,
заголовок определяется 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 ssize_t
иptrdiff_t
для представления величин, связанных с памятью. Их размер определяется в соответствии с арифметическими возможностями целевого процессора, а не возможностями памяти, такими как доступное адресное пространство. Оба этих типа определены в
заголовке (cstddef
в C ++).
size_t
представляет собой целочисленный тип без знака, используемый для представления размера любого объекта (включая массивы) в конкретной реализации. Оператор sizeof возвращает значение типаsize_t
. Максимальный размерsize_t
предоставляется черезSIZE_MAX
макроконстанту, которая определяется взаголовке (заголовок в C ++). гарантированно будет иметь ширину не менее 16 бит. Кроме того, POSIX включаетцелочисленный тип со знаком той же ширины, что и.<stdint.h>
cstdint
size_t
ssize_t
size_t
ptrdiff_t
представляет собой целочисленный тип со знаком, используемый для представления разницы между указателями. Гарантируется, что он действителен только для указателей одного и того же типа; вычитание указателей, состоящих из разных типов, определяется реализацией.
Интерфейс к свойствам основных типов
Информация о фактических свойствах, таких как размер, основных арифметических типов предоставляется через макроконстанты в двух заголовках:
заголовок ( climits
заголовок в C ++) определяет макросы для целочисленных типов, а
заголовок ( 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
- минимально возможное значение charCHAR_MAX
- максимально возможное значение charMB_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] Уже доступных базовых целочисленных типов было сочтено недостаточным, поскольку их фактические размеры определяются реализацией и могут различаться в разных системах. Новые типы особенно полезны во встроенных средах, где оборудование обычно поддерживает только несколько типов, и эта поддержка варьируется в зависимости от среды. Все новые типы определены в
заголовке ( cinttypes
заголовок в C ++), а также доступны в
заголовке ( cstdint
заголовок в C ++). Типы можно сгруппировать в следующие категории:
- Целочисленные типы точной ширины, которые гарантированно имеют одинаковое количество бит n во всех реализациях. Включается только в том случае, если это доступно в реализации.
- Целочисленные типы с наименьшей шириной, которые гарантированно будут наименьшим типом, доступным в реализации, который имеет как минимум указанное количество n битов. Гарантированно указывается не менее N = 8,16,32,64.
- Самые быстрые целочисленные типы, которые гарантированно будут самыми быстрыми целочисленными типами, доступными в реализации, которые имеют как минимум заданное количество n битов. Гарантированно указывается не менее N = 8,16,32,64.
- Целочисленные типы указателей, которые гарантированно могут содержать указатель. Включается только в том случае, если это доступно в реализации.
- Целочисленные типы максимальной ширины, которые гарантированно будут наибольшим целочисленным типом в реализации.
В следующей таблице приведены типы и интерфейс для получения сведений о реализации ( n означает количество битов):
Типовая категория | Подписанные типы | Беззнаковые типы | ||||
---|---|---|---|---|---|---|
Тип | Минимальное значение | Максимальное значение | Тип | Минимальное значение | Максимальное значение | |
Точная ширина | intn_t | INTn_MIN | INTn_MAX | uintn_t | 0 | UINTn_MAX |
Наименьшая ширина | int_leastn_t | INT_LEASTn_MIN | INT_LEASTn_MAX | uint_leastn_t | 0 | UINT_LEASTn_MAX |
Самый быстрый | int_fastn_t | INT_FASTn_MIN | INT_FASTn_MAX | uint_fastn_t | 0 | UINT_FASTn_MAX |
Указатель | intptr_t | INTPTR_MIN | INTPTR_MAX | uintptr_t | 0 | UINTPTR_MAX |
Максимальная ширина | intmax_t | INTMAX_MIN | INTMAX_MAX | uintmax_t | 0 | UINTMAX_MAX |
Спецификаторы формата printf и scanf
Заголовка ( cinttypes
в C ++) обеспечивает функции , которые повышают функциональность типов , определенных в
заголовке. Он определяет макросы для Printf форматной строки и формата зсапЕ строки спецификаторов , соответствующих типов , определенных в
и несколько функций для работы с intmax_t
и uintmax_t
типами. Этот заголовок был добавлен в C99 .
- Строка формата printf
Макросы в формате . Здесь {fmt} определяет форматирование вывода и может быть одним из (десятичного), (шестнадцатеричного), (восьмеричного), (беззнакового) и (целого). {тип} определяет тип аргумента и является одним из , , , , , где соответствует числу битов в аргументе.PRI{fmt}{type}
d
x
o
u
i
n
FASTn
LEASTn
PTR
MAX
n
- Строка формата scanf
Макросы в формате . Здесь {fmt} определяет форматирование вывода и может быть одним из (десятичного), (шестнадцатеричного), (восьмеричного), (беззнакового) и (целого). {тип} определяет тип аргумента и является одним из , , , , , где соответствует числу битов в аргументе.SCN{fmt}{type}
d
x
o
u
i
n
FASTn
LEASTn
PTR
MAX
n
- Функции
Дополнительные типы с плавающей запятой
Подобно целочисленным типам фиксированной ширины, 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
может использоваться, если
заголовок включен. Из них, const
безусловно, самый известный и наиболее используемый, он появляется в стандартной библиотеке и встречается при любом значительном использовании языка C, который должен удовлетворять константной корректности . Другие квалификаторы используются для низкоуровневого программирования и, хотя и широко используются там, редко используются типичными программистами. [ необходима цитата ]
Смотрите также
- Синтаксис C
- Неинициализированная переменная
- Целое число (информатика)
Рекомендации
- ^ Барр, Майкл (2 декабря 2007 г.). «Переносимые целые числа фиксированной ширины на языке C» . Проверено 18 января +2016 .
- ^ а б Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 255, § 7.18 Целочисленные типы
. - ^ Б с д е е г ч я J Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 22, § 5.2.4.2.1 Размеры целочисленных типов
. - ^ Обоснование международного стандарта - Языки программирования - Версия C 5.10 (PDF) . п. 25, § 5.2.4.2.1 Размеры целочисленных типов
. - ^ а б Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 37, § 6.2.6.1 Представления типов - Общие .
- ^ "64-битные модели программирования: почему именно LP64?" . Открытая группа . Проверено 9 ноября 2011 года .
- ^ Спецификация ISO / IEC 9899: 1999, TC3 (PDF) . п. 67, § 6.5 Выражения .
- ^ C11: Новый стандарт C , Томас Слива