Лекция 4: Система типов в языке Си
В мужчине днем должно быть всё светлое, а ночью - тёмное. Даже пиво.
Введение
В языках программирования любой кусочек данных (переменной, константы, аргумента функции) имеет тип. Тип данных определяет множество возможных значений и операций над ними.
Понятия типов данных
В языке C выделяются 5 базовых типов:
char
— символьный, 1 байт;int
— целый, размер зависит от системы (зачастую равен машинному слову);float
— вещественный, 32 бита (3.4e-38 до 3.4e+38);double
— вещественный двойной точности, 64 бита (1.7e-308 до 1.7e+308);void
— не имеющий значения.
Модификаторы типов
Базовые типы могут быть модифицированы с помощью ключевых слов signed
, unsigned
, short
, long
:
signed
: хранит положительные и отрицательные значения.unsigned
: только положительные значения.short
: уменьшает размер переменной (зачастую до 2 байт).long
: увеличивает размер переменной (до 4 или 8 байт).
Модификатор | Размер (биты) | Диапазон значений |
---|---|---|
signed char | 8 | −128 до 127 |
unsigned char | 8 | 0 до 255 |
short | 16 | −32768 до 32767 |
unsigned short | 16 | 0 до 65535 |
int | либо 16, либо 32 | Зависит от архитектуры |
unsigned int | либо 16, либо 32 | Зависит от архитектуры |
long | 32 | −2147483648 до 2147483647 |
unsigned long | 32 | 0 до 4294967295 |
#include <stdio.h>
int main() {
signed int signedInt = -32768;
printf("Signed int: %d\n", signedInt);
unsigned int unsignedInt = 65535;
printf("Unsigned int: %u\n", unsignedInt);
short int shortInt = 32767;
printf("Short int: %d\n", shortInt);
unsigned short int unsignedShortInt = 65535;
printf("Unsigned short int: %u\n", unsignedShortInt);
long int longInt = 2147483647;
printf("Long int: %ld\n", longInt);
unsigned long int unsignedLongInt = 4294967295;
printf("Unsigned long int: %lu\n", unsignedLongInt);
return 0;
}
Переменные и константы
Переменная — именованная область памяти, которая хранит значение, которое можно изменять.
Константа — значение, которое не может быть изменено в ходе программы.
Примеры констант:
- Вещественные:
123.456
,5.61e-4
; - Целые и длинные целые:
361327L
; - Шестнадцатеричные:
0x5F
; - Символьные:
'a'
.
#include <stdio.h>
int main() {
int x = 10;
double y = 3.14;
const double PI = 3.14159;
const int MAX_VALUE = 100;
x += 5;
printf("x = %d\n", x);
printf("y = %f\n", y);
printf("PI = %f\n", PI);
printf("MAX_VALUE = %d\n", MAX_VALUE);
return 0;
}
Преобразование типов
В языке C действуют правила автоматического преобразования типов в случае операций с разными типами данных. Если операнды имеют разные типы, то:
- Если один из операндов —
long double
, то остальные преобразуются кlong double
. - Если один из операндов —
double
, то остальные преобразуются кdouble
. - Если один из операндов —
float
, то остальные преобразуются кfloat
. - Если один из операндов —
unsigned long
, то остальные преобразуются кunsigned long
. - Если один из операндов —
long
, то остальные преобразуются кlong
. - Если один из операндов —
unsigned
, то остальные преобразуются кunsigned
. - В противном случае все операнды преобразуются к
int
.
#include <stdio.h>
int main() {
int a = 30000;
float b;
b = (float) a * 12;
printf("Значение a: %d\n", a);
printf("Значение b: %.2f\n", b);
return 0;
}
Составные типы и указатели
Массивы
Массив — это коллекция элементов одного типа, например:
int a[10];
Структуры
Структура — это набор переменных, обычно разных типов:
struct Person {
char name[50];
int age;
};
Объединения
Объединение похоже на структуру, но может содержать только одно значение в любой момент времени:
union Data {
int intValue;
float floatValue;
};
Указатели
Указатели хранят адреса переменных. Например:
int *ptr;
ptr = &a;
Массивы и указатели
Про массивы и указатели подробно будет рассказываться в последующих лекциях.
Оператор typedef
Оператор typedef
позволяет создавать псевдонимы для существующих типов данных, что упрощает написание и чтение кода.
typedef struct {
char name[50];
int age;
} Person;
Логический тип и комплексные числа
Логический тип
- В стандарте C89 логический тип представлен
int
(0 — false, не 0 — true). - В стандарте C99 введён тип
_Bool
, для которого можно использоватьstdbool.h
и типыbool
,true
,false
.
#include <stdbool.h>
bool isTrue = true;
bool isFalse = false;
Комплексные числа
Комплексные числа введены в стандарте C99:
#include <complex.h>
double complex z1 = 1.0 + 2.0 * I;
Абстракция и иерархия типов
Абстракция
Абстракция позволяет скрывать сложные детали и представлять данные на высоком уровне, упрощая работу с ними. Например, используя структуры, мы можем объединить связанные переменные в один логический объект.
typedef struct {
char title[100];
int day;
} Event;
Иерархия типов
Иерархия типов помогает организовать сложные структуры данных и облегчает повторное использование кода.
Системы типизации
- Статическая типизация: типы переменных и функций устанавливаются на этапе компиляции (C, C++, Java).
- Динамическая типизация: типы определяются во время выполнения программы (Python, JavaScript).
- Сильная типизация: язык не позволяет смешивать различные типы в выражениях (Java, Python).
- Слабая типизация: язык выполняет неявные преобразования между типами (C, JavaScript).
- Явная типизация: типы указываются явно при объявлении переменных.
- Неявная типизация: компилятор или интерпретатор сам выводит типы.
Заключение
Система типов языка C — это основа, которая помогает организовать данные и предотвратить ошибки в программе. Понимание типов данных, их модификаторов и преобразований позволяет создавать эффективные и надёжные программы.