Типы данных C - C data types
Стандартная библиотека C |
---|
Общие темы |
Разные заголовки |
В языке программирования С , типы данных представляют собой семантику и характеристики хранения элементов данных. Они выражаются в синтаксисе языка в форме объявлений для ячеек памяти или переменных . Типы данных также определяют типы операций или методы обработки элементов данных.
Язык C предоставляет основные арифметические типы, такие как целочисленные и действительные числа , а также синтаксис для построения массивов и составных типов. Заголовки для стандартной библиотеки C , которые будут использоваться с помощью директив include , содержат определения поддерживаемых типов, которые имеют дополнительные свойства, такие как предоставление хранилища точного размера, независимо от языковой реализации на конкретных аппаратных платформах.
Основные типы
Основные типы
Язык C предоставляет четыре основных арифметических спецификатора типа char , int , float и double , а также модификаторы signed , unsigned , short и long . В следующей таблице перечислены допустимые комбинации при указании большого набора объявлений, зависящих от размера хранилища.
Тип | Объяснение | Минимальный размер (бит) | Спецификатор формата |
---|---|---|---|
char |
Наименьшая адресуемая единица машины, которая может содержать базовый набор символов. Это целочисленный тип. Фактический тип может быть подписанным или беззнаковым. Он содержит биты CHAR_BIT. | 8 |
%c
|
signed char |
Того же размера, что и char , но с гарантированной подписью. Может содержать как минимум диапазон [-127, +127]. | 8 |
%c (или %hhi для числового вывода)
|
unsigned char |
Имеет тот же размер, что и char , но гарантированно без знака. Содержит как минимум диапазон [0, 255]. | 8 |
%c (или %hhu для числового вывода)
|
short short int signed short signed short int
|
Короткий знаковый целочисленный тип. Может содержать как минимум диапазон [-32,767, +32,767]. | 16 |
%hi или %hd
|
unsigned short unsigned short int
|
Короткий беззнаковый целочисленный тип. Содержит как минимум диапазон [0, 65 535]. | 16 |
%hu
|
int signed signed int
|
Базовый целочисленный тип со знаком. Может содержать как минимум диапазон [-32,767, +32,767]. | 16 |
%i или %d
|
unsigned unsigned int
|
Базовый беззнаковый целочисленный тип. Содержит как минимум диапазон [0, 65 535]. | 16 |
%u
|
long long int signed long signed long int
|
Длинный знаковый целочисленный тип. Способен содержать как минимум диапазон [−2 147 483 647, +2 147 483 647]. | 32 |
%li или %ld
|
unsigned long unsigned long int
|
Длинный беззнаковый целочисленный тип. Может содержать по крайней мере диапазон [0, 4 294 967 295]. | 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]. Указан начиная с версии стандарта C99 . | 64 |
%lli или %lld
|
unsigned long long unsigned long long int
|
Длинный длинный беззнаковый целочисленный тип. Содержит как минимум диапазон [0, +18,446,744,073,709,551,615]. Указан начиная с версии стандарта C99 . | 64 |
%llu
|
float |
Реальный тип с плавающей запятой, обычно называемый типом с плавающей запятой одинарной точности. Фактические свойства не указаны (кроме минимальных ограничений); однако в большинстве систем это двоичный формат с плавающей запятой одинарной точности IEEE 754 (32 бита). Этот формат требуется дополнительным Приложением F «Арифметика с плавающей запятой МЭК 60559». | Преобразование из текста: | |
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
|
Фактический размер целочисленных типов зависит от реализации. Стандарт требует только соотношения размеров между типами данных и минимального размера для каждого типа данных:
Требования к соотношению заключаются в том, чтобы long long
не было меньше чем long
, что не меньше чем int
, которое не меньше чем short
. Поскольку char
размер всегда является минимально поддерживаемым типом данных, никакие другие типы данных (кроме битовых полей ) не могут быть меньше.
Минимальный размер для char
составляет 8 бит, минимальный размер для short
и int
составляет 16 бит, поскольку long
он составляет 32 бита и long long
должен содержать не менее 64 бит.
Тип int
должен быть целочисленным типом, с которым целевой процессор наиболее эффективно работает. Это обеспечивает большую гибкость: например, все типы могут быть 64-битными. Однако популярны несколько различных схем целочисленной ширины (моделей данных). Поскольку модель данных определяет способ взаимодействия различных программ, в интерфейсе приложения данной операционной системы используется единообразная модель данных.
На практике char
обычно имеет размер 8 бит и short
обычно имеет размер 16 бит (как и их беззнаковые аналоги). Это справедливо для самых разных платформ, таких как SunOS 4 Unix 1990-х годов , Microsoft MS-DOS , современный Linux и Microchip MCC18 для встроенных 8-битных микроконтроллеров PIC . POSIX требует, char
чтобы размер был ровно 8 бит.
Различные правила в стандарте C делают unsigned char
основной тип, используемый для массивов, подходящим для хранения произвольных объектов, не являющихся битовыми полями: отсутствие в нем битов заполнения и представления ловушек, определение представления объекта и возможность наложения псевдонимов.
Фактический размер и поведение типов с плавающей запятой также зависят от реализации. Единственная гарантия - 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). Такое поведение существует, чтобы избежать целочисленных переполнений в неявных сужающих преобразованиях. Например, в следующем коде:
unsigned char b = 256;
if (b) {
/* do something */
}
Переменная b
принимает значение false, если unsigned char
имеет размер 8 бит. Это связано с тем, что значение 256 не соответствует типу данных, в результате чего используются его младшие 8 бит, что приводит к нулевому значению. Однако изменение типа заставляет предыдущий код вести себя нормально:
_Bool b = 256;
if (b) {
/* do something */
}
Тип _Bool также гарантирует, что истинные значения всегда равны друг другу:
_Bool a = 1, b = 2;
if (a == b) {
/* do something */
}
Типы разницы в размере и указателе
Спецификация языка C включает typedef s size_t
и ptrdiff_t
для представления величин, связанных с памятью. Их размер определяется в соответствии с арифметическими возможностями целевого процессора, а не возможностями памяти, такими как доступное адресное пространство. Оба этих типа определены в <stddef.h>
заголовке ( 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
представляет собой целочисленный тип со знаком, используемый для представления разницы между указателями. Гарантируется, что он действителен только для указателей одного и того же типа; вычитание указателей, состоящих из разных типов, определяется реализацией.
Интерфейс к свойствам основных типов
Информация о фактических свойствах, таких как размер, основных арифметических типов предоставляется через макроконстанты в двух заголовках: <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 включает определения нескольких новых целочисленных типов для повышения переносимости программ. Уже доступных базовых целочисленных типов было сочтено недостаточным, поскольку их фактические размеры определяются реализацией и могут различаться в разных системах. Новые типы особенно полезны во встроенных средах, где оборудование обычно поддерживает только несколько типов, и эта поддержка варьируется в зависимости от среды. Все новые типы определены в <inttypes.h>
заголовке ( cinttypes
заголовок в C ++), а также доступны в <stdint.h>
заголовке ( 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
<inttypes.h>
Заголовка ( cinttypes
в C ++) обеспечивает функции , которые повышают функциональность типов , определенных в <stdint.h>
заголовке. Он определяет макросы для Printf форматной строки и формата зсапЕ строки спецификаторов , соответствующих типов , определенных в <stdint.h>
и несколько функций для работы с 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
которая выделяет необходимое хранилище.
struct birthday {
char name[20];
int day;
int month;
int year;
};
struct birthday John;
Схема памяти структуры - это проблема языковой реализации для каждой платформы с некоторыми ограничениями. Адрес памяти первого члена должен совпадать с адресом самой структуры. Структуры могут быть инициализированы или назначены с использованием составных литералов. Функция может напрямую возвращать структуру, хотя во время выполнения это часто неэффективно. Начиная с C99 , структура также может заканчиваться гибким элементом массива .
Структура, содержащая указатель на структуру собственного типа, обычно используется для построения связанных структур данных :
struct node {
int val;
struct node *next;
};
Массивы
Для каждого типа T
, кроме типов void и function, существуют типы «массив N
элементов типа T
» . Массив - это набор значений одного типа, непрерывно хранящихся в памяти. Массив размера N
индексируется целыми числами от 0
до включительно N−1
. Вот краткий пример:
int cat[10]; // array of 10 elements, each of type int
Массивы можно инициализировать с помощью составного инициализатора, но не назначать. Массивы передаются функциям путем передачи указателя на первый элемент. Многомерные массивы определяются как «массив массивов…» , и все, кроме самого внешнего измерения, должны иметь размер, постоянный во время компиляции:
int a[10][8]; // array of 10 elements, each of type 'array of 8 int elements'
Указатели
Каждому типу данных T
соответствует указатель наT
тип . Указатель представляет собой тип данных , который содержит адрес места хранения переменной определенного типа. Они объявляются с помощью *
декларатора типа asterisk ( ), следующего за базовым типом хранилища и перед именем переменной. Пробелы до или после звездочки не обязательны.
char *square;
long *circle;
int *oval;
Указатели также могут быть объявлены для типов данных указателей, создавая таким образом несколько косвенных указателей, таких как char ** и int *** , включая указатели на типы массивов. Последние менее распространены, чем массив указателей, и их синтаксис может сбивать с толку:
char *pc[10]; // array of 10 elements of 'pointer to char'
char (*pa)[10]; // pointer to a 10-element array of char
Для элемента pc
требуется десять блоков памяти размером с указательchar
(обычно 40 или 80 байтов на обычных платформах), но элемент pa
представляет собой только один указатель (размер 4 или 8 байтов), а данные, на которые он ссылается, представляют собой массив из десяти байтов. ( ).
sizeof *pa == 10
Союзы
Тип объединения - это специальная конструкция, которая разрешает доступ к одному и тому же блоку памяти с помощью выбора различных описаний типов. Например, объединение типов данных может быть объявлено, чтобы разрешить чтение одних и тех же данных в виде целого числа, числа с плавающей запятой или любого другого объявленного пользователем типа:
union {
int i;
float f;
struct {
unsigned int u;
double 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;
// the & operator can be omitted, but makes clear that the "address of" abs is used here
Указатели функций вызываются по имени, как и обычные вызовы функций. Указатели функций отделены от указателей и указателей на недействительные .
Квалификаторы типа
Вышеупомянутые типы могут быть дополнительно охарактеризованы квалификаторами типов , в результате чего получается квалифицированный тип . По состоянию на 2014 год и C11 , в стандарте C есть четыре квалификатора типа: const
( C89 ), volatile
( C89 ), restrict
( C99 ) и _Atomic
( C11 ) - последний имеет частное имя, чтобы избежать конфликтов с именами пользователей, но более обычное имя atomic
может использоваться, если <stdatomic.h>
заголовок включен. Из них, const
безусловно, самый известный и наиболее используемый, он появляется в стандартной библиотеке и встречается при любом значительном использовании языка C, который должен удовлетворять константной корректности . Другие квалификаторы используются для низкоуровневого программирования и, хотя и широко используются там, редко используются типичными программистами.