Типы данных в C: полное руководство по целочисленным, вещественным и производным типам
Классификация типов
Система типов C делится на 4 основные категории:
| Категория | Описание | Примеры |
|---|---|---|
| Базовые (арифметические) | Целые и вещественные числа | int, float, double, char |
| Перечислимые (enum) | Именованные целочисленные константы | enum Color {RED, GREEN} |
| Void | Отсутствие типа | void (функции без возврата, указатели) |
| Производные | Составные типы | Указатели, массивы, структуры, объединения, функции |
Целочисленные типы
Размеры и диапазоны зависят от реализации (минимумы гарантирует стандарт). Типичные значения для 64-битных систем (LP64):
| Тип | Размер (байты) | Диапазон (знаковый) | Диапазон (беззнаковый) | Формат printf/scanf |
|---|---|---|---|---|
char / signed char | 1 | -128 … 127 | 0 … 255 | %hhd / %hhu |
unsigned char | 1 | — | 0 … 255 | %hhu |
short / signed short | 2 | -32 768 … 32 767 | 0 … 65 535 | %hd / %hu |
unsigned short | 2 | — | 0 … 65 535 | %hu |
int / signed int | 4 | -2 147 483 648 … 2 147 483 647 | 0 … 4 294 967 295 | %d / %u |
unsigned int | 4 | — | 0 … 4 294 967 295 | %u |
long / signed long | 8 (Linux/macOS), 4 (Windows 64) | ±9.22e18 / ±2.14e9 | 0 … 1.84e19 / 4.29e9 | %ld / %lu |
unsigned long | 8 / 4 | — | 0 … 1.84e19 / 4.29e9 | %lu |
long long | 8 | ±9.22e18 | 0 … 1.84e19 | %lld / %llu |
unsigned long long | 8 | — | 0 … 1.84e19 | %llu |
Точные размеры: <stdint.h> (C99)
Используйте эти типы для переносимого кода:
int8_t, uint8_t— ровно 8 битint16_t, uint16_t— ровно 16 битint32_t, uint32_t— ровно 32 битаint64_t, uint64_t— ровно 64 битаintptr_t, uintptr_t— размер указателяsize_t— размер объекта (результатsizeof)ptrdiff_t— разница указателейintmax_t, uintmax_t— максимальные поддерживаемые
Макросы лимитов в <limits.h> и <stdint.h>: INT_MAX, UINT32_MAX, INT64_MIN и т.д.
Оператор sizeof
sizeof(int) // размер типа в байтах (size_t)
sizeof variable // размер переменной (без скобок для выражений)
sizeof(expression) // скобки обязательны для типов
sizeof — оператор компилятора, вычисляется на этапе компиляции (кроме VLA).
Вещественные типы
| Тип | Размер | Диапазон (прибл.) | Точность (значимых цифр) | Формат |
|---|---|---|---|---|
float | 4 байта | ±1.2e-38 … ±3.4e+38 | ~6-7 (23 бита мантиссы) | %f, %e, %g |
double | 8 байт | ±2.3e-308 … ±1.7e+308 | ~15-16 (52 бита) | %lf, %e, %g |
long double | 10/12/16 байт | ±3.4e-4932 … ±1.1e+4932 (x86 80-бит) | ~19-33 (64+ бита) | %Lf, %Le, %Lg |
Константы: 3.14 (double), 3.14f (float), 3.14L (long double). Экспоненциальная форма: 1.5e-3, 2E10.
Макросы в <float.h>: FLT_DIG (6), DBL_DIG (15), LDBL_DIG, FLT_MAX, DBL_MIN и др.
Тип void
Обозначает «нет типа». Используется в трёх случаях:
- Функция не возвращает значение:
void printHello(void); - Функция не принимает параметров:
int getRandom(void);(в C++ просто()). - Указатель на неопределённый тип:
void *ptr;— «указатель на что-то». Используется вmalloc,memcpy, колбэках. Требует приведения к конкретному типу при разыменовании.
Символьный тип char
Важно: char — это целочисленный тип (1 байт). Знаковый или беззнаковый — зависит от реализации. Для текста используйте char, для байтов — uint8_t / int8_t.
Кодировки: ASCII (0-127), UTF-8 (многобайтовые последовательности в char[]), широкие символы wchar_t (<wchar.h>), UTF-16/32 — char16_t, char32_t (C11).
Квалификаторы типов
const— только для чтения (read-only).const int x = 5;volatile— значение может измениться внешне (железо, прерывания, другой поток). Отключает оптимизации компилятора.restrict(C99) — указатель — единственный способ доступа к объекту (оптимизация алиасинга)._Atomic(C11) — атомарный доступ.
Пример: определение размеров на платформе
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <stdint.h>
int main(void) {
printf("=== Целочисленные ===\n");
printf("char: %zu байт, %d ... %d\n", sizeof(char), CHAR_MIN, CHAR_MAX);
printf("short: %zu байт, %d ... %d\n", sizeof(short), SHRT_MIN, SHRT_MAX);
printf("int: %zu байт, %d ... %d\n", sizeof(int), INT_MIN, INT_MAX);
printf("long: %zu байт, %ld ... %ld\n", sizeof(long), LONG_MIN, LONG_MAX);
printf("long long: %zu байт, %lld ... %lld\n", sizeof(long long), LLONG_MIN, LLONG_MAX);
printf("int32_t: %zu байт\n", sizeof(int32_t));
printf("intptr_t: %zu байт\n", sizeof(intptr_t));
printf("size_t: %zu байт\n", sizeof(size_t));
printf("\n=== Вещественные ===\n");
printf("float: %zu байт, %e ... %e, точность %d\n", sizeof(float), FLT_MIN, FLT_MAX, FLT_DIG);
printf("double: %zu байт, %e ... %e, точность %d\n", sizeof(double), DBL_MIN, DBL_MAX, DBL_DIG);
printf("long double: %zu байт, %Le ... %Le, точность %d\n", sizeof(long double), LDBL_MIN, LDBL_MAX, LDBL_DIG);
printf("\nУказатель: %zu байт\n", sizeof(void*));
return 0;
}
Язык C
- Понимание электрических коммутаторов: типы, функции и применения
- Мастерство C# переменных и примитивных типов данных: полное руководство
- Понимание типов данных C++: основы, модификаторы и лучшие практики
- Типы данных в C: int, float, char и другие — полное руководство
- Освоение типов данных в Python: практическое руководство
- Примитивные типы данных в Java: полное руководство с примерами
- Переменные, типы данных и константы в C — практическое руководство
- 5 моделей центров обработки данных: дизайн, кейсы и примеры
- Восемь ключевых моделей облачных вычислений 2021 года
- 8 распространённых типов утечек данных — реальные примеры и последствия