Arithmetic types
(См. также type для обзора системы типов и список утилит, связанных с типами которые предоставляются библиотекой C.)
Логический типОбратите внимание, что преобразование в _Bool (до C23) bool (начиная с C23) работает не так, как преобразование в другие целочисленные типы: ( bool ) 0.5 вычисляется как true , тогда как ( int ) 0.5 вычисляется как 0 . |
(начиная с C99) |
Символьные типы
-
- signed char — тип для представления знакового символа.
- unsigned char — тип для представления беззнакового символа. Также используется для анализа представлений объектов (необработанная память).
- char — тип для представления символа. Эквивалентен либо signed char , либо unsigned char (конкретный выбор зависит от реализации и может управляться ключом командной строки компилятора), но char является отдельным типом, отличным как от signed char , так и от unsigned char .
Обратите внимание, что стандартная библиотека также определяет typedef имена wchar_t , char16_t и char32_t (начиная с C11) для представления широких символов и char8_t для символов UTF-8 (начиная с C23) .
Целочисленные типы
-
- short int (также доступен как short , может использовать ключевое слово signed )
- unsigned short int (также доступен как unsigned short )
- int (также доступен как signed int )
- Это наиболее оптимальный целочисленный тип для платформы, гарантированно занимающий не менее 16 бит. Большинство современных систем используют 32 бита (см. модели данных ниже).
- unsigned int (также доступен как unsigned ), беззнаковый аналог int , реализующий модульную арифметику. Подходит для битовых операций.
- long int (также доступен как long )
- unsigned long int (также доступен как unsigned long )
|
(начиная с C99) |
|
(начиная с C23) |
Примечание: как и со всеми спецификаторами типа, допустим любой порядок: unsigned long long int и long int unsigned long обозначают один и тот же тип.
В следующей таблице приведены все доступные целочисленные типы и их свойства:
| Спецификатор типа | Эквивалентный тип | Ширина в битах по модели данных | ||||
|---|---|---|---|---|---|---|
| Стандарт C | LP32 | ILP32 | LLP64 | LP64 | ||
|
char
|
char |
как минимум
8 |
8 | 8 | 8 | 8 |
|
signed
char
|
signed char | |||||
|
unsigned
char
|
unsigned char | |||||
|
short
|
short int |
как минимум
16 |
16 | 16 | 16 | 16 |
|
short
int
|
||||||
|
signed
short
|
||||||
|
signed
short
int
|
||||||
|
unsigned
short
|
unsigned short int | |||||
|
unsigned
short
int
|
||||||
|
int
|
int |
как минимум
16 |
16 | 32 | 32 | 32 |
|
signed
|
||||||
|
signed
int
|
||||||
|
unsigned
|
unsigned int | |||||
|
unsigned
int
|
||||||
|
long
|
long int |
как минимум
32 |
32 | 32 | 32 | 64 |
|
long
int
|
||||||
|
signed
long
|
||||||
|
signed
long
int
|
||||||
|
unsigned
long
|
unsigned long int | |||||
|
unsigned
long
int
|
||||||
|
long
long
|
long
long
int
(C99) |
как минимум
64 |
64 | 64 | 64 | 64 |
|
long
long
int
|
||||||
|
signed
long
long
|
||||||
|
signed
long
long
int
|
||||||
|
unsigned
long
long
|
unsigned
long
long
int
(C99) |
|||||
|
unsigned
long
long
int
|
||||||
Помимо минимального количества битов, стандарт C гарантирует, что
-
1
==
sizeof
(
char
)
≤sizeof ( short )≤sizeof ( int )≤sizeof ( long )≤sizeof ( long long ) .
Примечание: это допускает крайний случай, когда байты имеют размер 64 бита, все типы (включая char ) имеют ширину 64 бита, и sizeof возвращает 1 для каждого типа.
Примечание: целочисленная арифметика определяется по-разному для знаковых и беззнаковых целочисленных типов. См. арифметические операторы , в частности целочисленные переполнения .
Модели данных
Выбор, сделанный каждой реализацией относительно размеров фундаментальных типов, в совокупности известен как data model . Широкое распространение получили четыре модели данных:
32-битные системы:
-
- LP32 или 2/4/4 ( int — 16-битный, long и указатель — 32-битные)
-
- Win16 API
- ILP32 или 4/4/4 ( int , long и указатель — 32-битные);
-
- Win32 API
- Unix и Unix-подобные системы (Linux, Mac OS X)
64-битные системы:
-
- LLP64 или 4/4/8 ( int и long являются 32-битными, указатель — 64-битный)
-
- Win64 API
- LP64 или 4/8/8 ( int является 32-битным, long и указатель являются 64-битными)
-
- Unix и Unix-подобные системы (Linux, Mac OS X)
Другие модели встречаются очень редко. Например, ILP64 ( 8/8/8 : int , long , и указатель имеют размер 64 бита) встречалась только в некоторых ранних 64-битных Unix-системах (например, Unicos на Cray ).
Обратите внимание, что целочисленные типы точной ширины доступны в <stdint.h> начиная с C99.
Вещественные типы с плавающей точкой
C имеет три или шесть (начиная с C23) типа для представления вещественных значений с плавающей точкой:
-
- float — тип с плавающей точкой одинарной точности. Соответствует формату IEEE-754 binary32 при поддержке.
- double — тип с плавающей точкой двойной точности. Соответствует формату IEEE-754 binary64 при поддержке.
-
long
double
— тип с плавающей точкой расширенной точности. Соответствует
формату IEEE-754
binary128
при поддержке, иначе соответствует
расширенному формату IEEE-754
binary64
при поддержке, иначе соответствует некоторому не-IEEE-754 расширенному формату с плавающей точкой при условии, что его точность выше, чем у
binary64
, а диапазон не меньше, чем у
binary64
, иначе соответствует формату IEEE-754
binary64
.
- binary128 используется в некоторых реализациях HP-UX, SPARC, MIPS, ARM64 и z/OS.
- Наиболее известный расширенный формат IEEE-754 binary64 — это 80-битный формат расширенной точности x87. Он используется во многих реализациях x86 и x86-64 (заметным исключением является MSVC, который реализует long double в том же формате, что и double , т.е. binary64 ).
|
(начиная с C23) |
Типы с плавающей запятой могут поддерживать специальные значения:
- бесконечность (положительная и отрицательная), см. INFINITY
- отрицательный ноль , - 0.0 . Он сравнивается как равный положительному нулю, но имеет значение в некоторых арифметических операциях, например 1.0 / 0.0 == INFINITY , но 1.0 / - 0.0 == - INFINITY )
- не-число (NaN), которое не сравнивается ни с чем (включая само себя). Несколько битовых шаблонов представляют NaN, см. nan , NAN . Обратите внимание, что C не делает специальных различий для сигнальных NaN (определенных IEEE-754) и рассматривает все NaN как тихие.
Вещественные числа с плавающей точкой могут использоваться с
арифметическими операторами
+
-
/
*
и различными математическими функциями из
<math.h>
. Как встроенные операторы, так и библиотечные функции могут вызывать исключения с плавающей точкой и устанавливать
errno
как описано в
math_errhandling
.
Выражения с плавающей точкой могут иметь больший диапазон и точность, чем указано их типами, см. FLT_EVAL_METHOD . Присваивание , return и приведение типа приводят диапазон и точность к значениям, соответствующим объявленному типу.
Выражения с плавающей точкой также могут быть сжаты , то есть вычислены так, как если бы все промежуточные значения имели бесконечный диапазон и точность, см. #pragma STDC FP_CONTRACT .
Некоторые операции над числами с плавающей запятой зависят от состояния окружения для работы с плавающей запятой и изменяют его (в первую очередь, направление округления).
Неявные преобразования определены между вещественными типами с плавающей точкой и целочисленными, комплексными и мнимыми типами.
См. Ограничения типов с плавающей точкой и библиотеку <math.h> для получения дополнительных сведений, ограничений и свойств типов с плавающей точкой.
Комплексные типы с плавающей точкойКомплексные типы с плавающей точкой моделируют математические комплексные числа , то есть числа, которые могут быть записаны как сумма действительного числа и действительного числа, умноженного на мнимую единицу: a + bi Три комплексных типа:
Примечание: как и со всеми спецификаторами типа, допустим любой порядок: long double complex , complex long double , и даже double complex long обозначают один и тот же тип.
Запустить этот код
Вывод: 1/(1.0+2.0i) = 0.2-0.4i
Каждый комплексный тип имеет то же представление объекта и требования выравнивания , что и массив из двух элементов соответствующего вещественного типа ( float для float complex , double для double complex , long double для long double complex ). Первый элемент массива содержит вещественную часть, а второй элемент массива содержит мнимую компоненту.
Комплексные числа могут использоваться с
арифметическими операторами
Инкремент и декремент не определены для комплексных типов. Реляционные операторы не определены для комплексных типов (не существует понятия "меньше чем").
Для поддержки модели комплексной арифметики с одной бесконечностью, C рассматривает любое комплексное значение, содержащее хотя бы одну бесконечную часть, как бесконечность, даже если другая его часть является NaN, гарантирует, что все операторы и функции соблюдают основные свойства бесконечностей и предоставляет cproj для отображения всех бесконечностей в каноническую (см. арифметические операторы для точных правил).
Запустить этот код
#include <complex.h> #include <math.h> #include <stdio.h> int main(void) { double complex z = (1 + 0*I) * (INFINITY + I*INFINITY); // по формуле из учебника получилось бы // (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN // но в C получается комплексная бесконечность printf("%f%+f*i\n", creal(z), cimag(z)); // по формуле из учебника получилось бы // cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN // но в C получается ±∞+i*nan double complex y = cexp(INFINITY + I*NAN); printf("%f%+f*i\n", creal(y), cimag(y)); } Возможный вывод: inf+inf*i inf+nan*i C также обрабатывает множественные бесконечности таким образом, чтобы сохранять направленную информацию там, где это возможно, несмотря на присущие ограничения декартового представления: умножение мнимой единицы на действительную бесконечность дает правильно знаковую мнимую бесконечность: i × ∞ = i∞. Также, i × (∞ – i∞) = ∞ + i∞ указывает на разумный квадрант.
Мнимые типы с плавающей точкойМнимые типы с плавающей запятой моделируют математические мнимые числа , то есть числа, которые могут быть записаны как действительное число, умноженное на мнимую единицу: bi . Три мнимых типа следующие:
Примечание: как и со всеми спецификаторами типа, допустим любой порядок: long double imaginary , imaginary long double , и даже double imaginary long обозначают один и тот же тип.
Запустить этот код
Вывод: 1/(3.0i) = -0.3i
Каждый из трёх мнимых типов имеет то же представление объекта и требование выравнивания , что и его соответствующий вещественный тип ( float для float imaginary , double для double imaginary , long double для long double imaginary ). Примечание: несмотря на то, что мнимые типы являются отдельными и не совместимы с соответствующими им вещественными типами, что запрещает алиасинг.
Мнимые числа могут использоваться с
арифметическими операторами
Инкремент и декремент не определены для мнимых типов.
Мнимые числа позволяют выражать все комплексные числа с использованием естественной записи x + I * y (где I определяется как _Imaginary_I ). Без мнимых типов определенные специальные комплексные значения невозможно создать естественным образом. Например, если I определяется как _Complex_I , то запись 0.0 + I * INFINITY дает NaN в качестве действительной части, и вместо этого необходимо использовать CMPLX ( 0.0 , INFINITY ) . То же относится к числам с отрицательным нулевым мнимым компонентом, которые важны при работе с библиотечными функциями, имеющими разрезы ветвей, такими как csqrt : 1.0 - 0.0 * I дает положительный нулевой мнимый компонент, если I определяется как _Complex_I , а для получения отрицательного нулевого мнимого компонента требуется использование CMPLX или conj . Мнимые типы также упрощают реализации; умножение мнимого числа на комплексное может быть реализовано напрямую с помощью двух умножений, если поддерживаются мнимые типы, вместо четырех умножений и двух сложений. |
(начиная с C99) |
Ключевые слова
- bool , true , false , char , int , short , long , signed , unsigned , float , double .
- _Bool , _BitInt , _Complex , _Imaginary , _Decimal32 , _Decimal64 , _Decimal128 .
Диапазон значений
В следующей таблице приведены справочные данные по пределам распространенных числовых представлений.
До стандарта C23 стандарт C допускал любое представление знаковых целых чисел, и минимальный гарантированный диапазон N-битных знаковых целых чисел был от
-(2
N-1
-1)
до
+2
N-1
-1
(например,
-127
до
127
для 8-битного знакового типа), что соответствует пределам
обратного кода
или
прямого кода
.
Однако все популярные модели данных (включая ILP32, LP32, LP64, LLP64) и почти все компиляторы C используют
дополнительный код
(единственные известные исключения — некоторые компиляторы для UNISYS), и начиная с C23 это единственное представление, разрешённое стандартом, с гарантированным диапазоном от
-2
N-1
до
+2
N-1
-1
(например,
-128
до
127
для 8-битного знакового типа).
| Тип | Размер в битах | Формат | Диапазон значений | |
|---|---|---|---|---|
| Приблизительный | Точный | |||
| символьный | 8 | знаковый | −128 до 127 | |
| беззнаковый | 0 до 255 | |||
| 16 | UTF-16 | 0 до 65535 | ||
| 32 | UTF-32 | 0 до 1114111 ( 0x10ffff ) | ||
| целочисленный | 16 | знаковый | ± 3.27 · 10 4 | −32768 до 32767 |
| беззнаковый | 0 до 6.55 · 10 4 | 0 до 65535 | ||
| 32 | знаковый | ± 2.14 · 10 9 | −2,147,483,648 до 2,147,483,647 | |
| беззнаковый | 0 до 4.29 · 10 9 | 0 до 4,294,967,295 | ||
| 64 | знаковый | ± 9.22 · 10 18 | −9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 | |
| беззнаковый | 0 до 1.84 · 10 19 | 0 до 18,446,744,073,709,551,615 | ||
|
двоичный
с плавающей точкой |
32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
|
|
| 80 [примечание 1] | x86 |
|
|
|
| 128 | IEEE-754 |
|
|
|
|
десятичный
с плавающей точкой |
32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
||
| 128 | IEEE-754 |
|
||
- ↑ Представление объекта обычно занимает 96/128 бит на 32/64-битных платформах соответственно.
Примечание: фактические (в отличие от гарантированных минимальных) диапазоны доступны в заголовочных файлах библиотеки <limits.h> и <float.h> .
Смотрите также
|
Документация C++
для
Фундаментальных типов
|