Классификация и применение: типы данных в языке программирования Си
Переменные в C классифицируются по объему памяти и допустимым значениям. Типы данных в языке программирования Си охватывают целочисленные, вещественные, производные конструкции и спецификации стандартов C99 и C11.
Оглавление
Базовые примитивы
Фундамент системы типов составляют примитивы, которые делятся на целочисленные и вещественные. Их размер и диапазон значений зависят от архитектуры компилятора и операционной системы.
Целочисленные типы
Используются для хранения счетчиков, индексов и целых величин. Поддерживают модификаторы signed (по умолчанию для int, short, long) и unsigned (только положительные значения и ноль).
| Тип | Размер (байты) | Диапазон значений |
|---|---|---|
char | 1 | -128 … 127 (signed) или 0 … 255 (unsigned) |
short | 2 | -32 768 … 32 767 |
int | 4 (обычно) | -2 147 483 648 … 2 147 483 647 |
long | 4 или 8 | Зависит от платформы (см. примечание) |
long long | 8 | ±9 223 372 036 854 775 807 |
Важно: Размер типа long не фиксирован стандартом жестко. В среде Windows он обычно занимает 4 байта, тогда как в Linux и macOS (на 64-битных системах) — 8 байт. Для гарантированного размера используйте типы фиксированной длины.
Вещественные типы (с плавающей точкой)
Применяются для научных расчетов и работы с дробными числами.
float: одинарная точность, 4 байта. Диапазон примерно от ±3.4E-38 до 3.4E+38.double: двойная точность, 8 байт. Диапазон от ±1.7E-308 до 1.7E+308.long double: повышенная точность, занимает 10 байт (80 бит) или более. Диапазон до ±1.1E+4932.
Специальный тип
void: тип без значения. Указывает на то, что функция не возвращает результат, или используется для создания универсальных указателей (void *).
Логический тип и стандарт C99
До стандарта C99 в языке отсутствовал встроенный булев тип, и разработчики использовали int (где 0 — ложь, любое другое число — истина).
_Bool: встроенный логический тип, способный хранить только 0 или 1.<stdbool.h>: заголовочный файл, который вводит псевдонимboolи макросыtrue(1) иfalse(0) для удобства чтения кода.
Производные конструкции
Позволяют создавать сложные структуры данных на основе базовых типов.
- Массивы: упорядоченные коллекции элементов одного типа, расположенные в памяти последовательно.
int numbers[10]; // массив из 10 целых чисел
```
2. **Указатели**: переменные, которые хранят адреса ячеек памяти, а не сами значения.
```c
int *ptr; // указатель на переменную типа int
```
3. **Структуры (`struct`)**: объединяют разнородные данные под одним именем.
```c
struct Person {
char name[50];
int age;
};
```
4. **Объединения (`union`)**: позволяют разным переменным разделять одну и ту же область памяти (в один момент времени активно только одно поле).
5. **Перечисления (`enum`)**: набор именованных целочисленных констант.
```c
enum Color { RED, GREEN, BLUE };
```
## Фиксированная длина и квалификаторы
Для обеспечения переносимости кода между разными архитектурами стандарт C99 ввел типы с гарантированным размером, а C11 расширил возможности многопоточности.
### Типы фиксированной длины (`<stdint.h>`)
Используются, когда критически важен точный размер переменной в битах:
* `int8_t`, `int16_t`, `int32_t`, `int64_t` — знаковые целые.
* `uint8_t`, `uint16_t`, `uint32_t`, `uint64_t` — беззнаковые целые.
* `intptr_t`, `uintptr_t` — типы, гарантированно способные хранить указатель.
### Квалификаторы типов
Модифицируют свойства переменных:
* **`const`**: запрещает изменение значения после инициализации.
* **`volatile`**: указывает компилятору, что значение может меняться извне (аппаратные регистры, прерывания), запрещая оптимизацию чтения.
* **`restrict`** (C99): применяется к указателям, гарантируя, что только этот указатель используется для доступа к объекту.
* **`_Atomic`** (C11): обеспечивает атомарные операции для многопоточных приложений.
## Размеры, суффиксы и вывод
### Оператор `sizeof`
Позволяет узнать размер типа или переменной в байтах непосредственно во время компиляции или выполнения.
```c
printf("Размер int: %lu\n", sizeof(int));
Литералы и суффиксы
Чтобы компилятор правильно определил тип константы, используются суффиксы:
Uилиu—unsigned(например,100U).Lилиl—long(например,100L).LLилиll—long long.Fилиf—float(без суффикса дробные числа воспринимаются какdouble).
Спецификаторы формата printf
Для корректного вывода различных типов в консоль требуются специфические плейсхолдеры:
%d— дляint.%ld— дляlong.%lld— дляlong long.%f— дляfloatиdouble.%c— дляchar.