Типы данных C

редактировать

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

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

Содержание
  • 1 Базовые типы
    • 1.1 Основные типы
    • 1.2 Логический тип
    • 1.3 Типы разности размеров и указателей
    • 1.4 Интерфейс к свойствам базовых типов
      • 1.4.1 Свойства целочисленных типов
      • 1.4.2 Свойства типов с плавающей запятой
  • 2 Целочисленные типы фиксированной ширины
    • 2.1 Спецификаторы формата Printf и scanf
  • 3 Дополнительные типы с плавающей запятой
  • 4 структуры
  • 5 массивов
  • 6 указателей
  • 7 объединений
  • 8 указателей функций
  • 9 квалификаторов типов
  • 10 См. Также
  • 11 Примечания
  • 12 Ссылки
Basic типы

Основные типы

Язык 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».Преобразование из текста:
  • %f%F
  • %g%G
  • %e%E
  • %a%A
doubleДействительный тип с плавающей запятой, обычно называемый типом с плавающей запятой двойной точности. Фактические свойства не указаны (за исключением минимальных ограничений); однако в большинстве систем это двоичный формат с плавающей запятой двойной точности IEEE 754 (64 бита). Этот формат требуется дополнительным Приложением F «Арифметика с плавающей запятой МЭК 60559».
  • %lf%lF
  • %lg%lG
  • %le%lE
  • %la% lA
long doubleДействительный тип с плавающей запятой, обычно отображаемый в формат чисел с плавающей запятой расширенной точности. Фактические свойства не указаны. Это может быть либо формат x86 с плавающей запятой с расширенной точностью (80 бит, но обычно 96 бит, либо 128 бит в памяти с байтами заполнения ), либо не-IEEE "double-double "(128 бит), IEEE 754, формат с плавающей запятой четверной точности (128 бит) или то же самое, что и double. Подробнее см. в статье о длинном двойном.%Lf%LF. %Lg%LG. %Le%LE. %La% LA

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

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

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

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

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

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

Фактический размер и поведение типов с плавающей запятой также зависят от реализации. Единственная гарантия состоит в том, что 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 добавлено логическое значение (true / false) введите _Bool. Кроме того, заголовок определяет boolкак удобный псевдоним для этого типа, а также предоставляет макросы для trueи false. _Boolфункционирует аналогично обычному целочисленному типу, за одним исключением: любые присвоения _Bool, отличные от 0 (false), сохраняются как 1 (true). Такое поведение существует, чтобы избежать целочисленных переполнений в неявных сужающих преобразованиях. Например, в следующем коде:

unsigned char 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 size_tи ptrdiff_tдля представления величин, связанных с памятью. Их размер определяется в соответствии с арифметическими возможностями целевого процессора, а не возможностями памяти, такими как доступное адресное пространство. Оба этих типа определены в заголовке (cstddefв C ++).

size_t- это целочисленный тип без знака, используемый для представления размера любого объекта (включая массивы) в конкретной реализации. Оператор sizeof возвращает значение типа size_t. Максимальный размер size_tпредоставляется через SIZE_MAX, макроконстанту, которая определена в заголовке (cstdintзаголовок в C ++). size_tгарантированно будет иметь ширину не менее 16 бит. Кроме того, POSIX включает ssize_t, который представляет собой целочисленный тип со знаком той же ширины, что и size_t.

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

Интерфейс к свойствам базовых типов

Информация о фактических свойствах, таких как размер, основных арифметических типов, предоставляется через макроконстанты в двух заголовках: заголовок ( climitsheader в C ++) определяет макросы для целочисленных типов, а заголовок (cfloatheader в C ++) определяет макросы для типов с плавающей запятой. Фактические значения зависят от реализации.

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

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

Свойства типов с плавающей запятой

  • FLT_MIN, DBL_MIN, LDBL_MIN- минимальное нормализованное положительное значение float, double, long double соответственно
  • FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN(C11) - минимальное положительное значение float, double, long double соответственно
  • FLT_MAX, DBL_MAX, LDBL_MAX- максимальное конечное значение of float, double, long double, соответственно
  • FLT_ROUNDS- режим округления для операций с плавающей запятой
  • FLT_EVAL_METHOD(C99) - метод вычисления выражений с участием различных типов с плавающей запятой
  • FLT_RADIX- основание экспоненты в типах с плавающей запятой
  • FLT_DIG, DBL_DIG, LDBL_DIG- количество десятичных цифр, которые могут быть представлены без потери точности с помощью числа с плавающей запятой, double, long double, соответственно
  • FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON- разница между 1.0 и следующим представимым значением float, double, long double, соответственно
  • FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG- количество FLT_RADIXцифр в значении с плавающей запятой для типов float, double, long double, соответственно
  • 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 в этой степени является нормализованным числом с плавающей запятой, двойным, длинным двойным, соответственно
  • DECI MAL_DIG(C99) - минимальное количество десятичных цифр, такое, что любое число самого широкого поддерживаемого типа с плавающей запятой может быть представлено в десятичном виде с точностью DECIMAL_DIGцифр и считано в исходном формате с плавающей запятой. тип точки без изменения его значения. DECIMAL_DIGне менее 10.
Целочисленные типы фиксированной ширины

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

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

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

Категория типаТипы со знакомТипы без знака
ТипМинимальное значениеМаксимальное значениеТипМинимальное значениеМаксимальное значение
Точная ширинаintn_tINTn_MININTn_MAXuintn_t0UINTn_MAX
Наименьшая ширинаint_leastn_tINT_LEASTn_MININT_LEASTn_MAXuint_leastn_t0UINT_LEASTn_MAX
Fastestint_fastn_tINT_FAST_23n_MIN_MIN_FAST5INT_FAST_23n_MIN 210>Указательintptr_tINTPTR_MININTPTR_MAXuintptr_t0UINTPTR_MAX
Максимальная ширинаintmax_tINTMAX_MININTMAX_MAXUINT_MAXUINT185>Спецификаторы форматов Printf и scanf

(cinttypesв C ++) предоставляет функции, расширяющие функциональность типов, определенных в заголовке . Он определяет макросы для спецификаторов строки формата printf и строки формата scanf, соответствующих типам, определенным в , а также несколько функций для работы с intmax_tи uintmax_tтипы. Этот заголовок был добавлен в C99.

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

Макросы имеют формат PRI {fmt} {type}. Здесь {fmt} определяет форматирование вывода и принимает одно из следующих значений: d(десятичное), x(шестнадцатеричное), o(восьмеричное), u(без знака) и i(целое число). {type} определяет тип аргумента и является одним из n, FASTn, LEASTn, PTR, MAX, где nсоответствует количеству бит в аргументе.

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

Макросы имеют формат SCN {fmt} {type}. Здесь {fmt} определяет форматирование вывода и принимает одно из следующих значений: d(десятичное), x(шестнадцатеричное), o(восьмеричное), u(без знака) и i(целое число). {type} определяет тип аргумента и является одним из n, FASTn, LEASTn, PTR, MAX, где nсоответствует количеству бит в аргументе.

Функции
Дополнительные типы с плавающей запятой

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

  • _Float Nдля двоичных форматов обмена;
  • _Decimal Nдля десятичных форматов обмена;
  • _Float Nxдля двоичных расширенных форматов;
  • _Decimal Nxдля расширенных десятичных форматов.
Структуры

Структуры объединяют хранилище нескольких элементов данных потенциально разных типов данных в один блок памяти, на который ссылается одна переменная. В следующем примере объявляется тип данных 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. указатель - это тип данных, который содержит адрес места хранения переменной определенного типа. Они объявляются с помощью декларатора типа звездочка (*), следующего за базовым типом хранения и предшествующего имени переменной. Пробелы до или после звездочки не обязательны.

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

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

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

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

Объединения

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

union {int i; float f; struct {unsigned int u; двойной d; } s; } u;

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

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

Указатели функций

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

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

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

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

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

См. Также
Викибук Программирование на C имеет страницу тема: Программирование на C
Примечания
Ссылки
Последняя правка сделана 2021-05-13 12:45:13
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru