Перейти к содержанию

Лекция 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 действуют правила автоматического преобразования типов в случае операций с разными типами данных. Если операнды имеют разные типы, то:

  1. Если один из операндов — long double, то остальные преобразуются к long double.
  2. Если один из операндов — double, то остальные преобразуются к double.
  3. Если один из операндов — float, то остальные преобразуются к float.
  4. Если один из операндов — unsigned long, то остальные преобразуются к unsigned long.
  5. Если один из операндов — long, то остальные преобразуются к long.
  6. Если один из операндов — unsigned, то остальные преобразуются к unsigned.
  7. В противном случае все операнды преобразуются к 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 — это основа, которая помогает организовать данные и предотвратить ошибки в программе. Понимание типов данных, их модификаторов и преобразований позволяет создавать эффективные и надёжные программы.


I feel so alone
Gonna end up a big ol' pile of them bones