2. Глава 2: Переменные и арифметика

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

2.1. Типы данных

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

  • intцелое число. Используется для хранения целых чисел без дробной части (например, 5, -100, 0). Размер int может варьироваться в зависимости от архитектуры системы (обычно 2 или 4 байта).

  • floatчисло с плавающей точкой (одинарной точности). Предназначен для хранения дробных чисел (например, 3.14, -0.5, 123.456). Имеет меньшую точность по сравнению с double и обычно занимает 4 байта.

  • doubleчисло с плавающей точкой (двойной точности). Также используется для дробных чисел, но с гораздо большей точностью и диапазоном значений, чем float. Обычно занимает 8 байт. Это тип по умолчанию для дробных чисел в C, если не указано иное.

  • charодин символ. Хранит один символ (например, „A“, „z“, „5“, „!“). На самом деле, char хранит целочисленное значение, соответствующее коду символа в таблице ASCII (или другой кодировке). Обычно занимает 1 байт.

  • unsigned int, long, short и другие модификаторы. Это модификаторы, которые уточняют размер и диапазон значений базовых типов:
    • ``short``: Уменьшает диапазон значений для int, занимая меньше памяти (обычно 2 байта). Например, short int.

    • ``long``: Увеличивает диапазон значений для int и double. Например, long int (обычно 4 или 8 байт) и long double (обычно 10 или 16 байт).

    • ``unsigned``: Применяется к целочисленным типам (int, char, short, long) и означает, что переменная может хранить только неотрицательные значения (но при этом её максимальное положительное значение удваивается). Например, unsigned int.

### Важность выбора типа данных

Выбор правильного типа данных важен по двум причинам:

  1. Эффективность использования памяти: Использование меньших типов данных, когда это уместно, может сэкономить память, что особенно важно в программах, работающих с большими объёмами данных или на встроенных системах с ограниченными ресурсами.

  2. Точность и диапазон значений: Неправильный выбор может привести к потере точности (например, при использовании float вместо double для финансовых расчётов) или переполнению (когда значение выходит за пределы допустимого диапазона для данного типа).

Пример объявления переменных:

int a = 5;         // Объявление целого числа 'a' и инициализация его значением 5
float b = 3.14;    // Объявление числа с плавающей точкой 'b' и инициализация 3.14
char c = 'A';      // Объявление символьной переменной 'c' и инициализация символом 'A'
double d = 123.456789; // Объявление числа двойной точности 'd'
unsigned int count = 100; // Объявление беззнакового целого числа 'count'

2.2. Арифметические операции

Язык C поддерживает стандартные арифметические операторы:

Оператор

Назначение

Пример и пояснение

+

сложение

5 + 3 будет 8

-

вычитание

10 - 4 будет 6

*

умножение

2 * 7 будет 14

/

деление

10 / 33 (целочисленно) 10.0 / 3.03.333...

%

остаток от деления

10 % 31 (10 делим на 3, остаток 1)

Важно: оператор % (модуль или остаток от деления) работает только с целыми числами (int, short, long, char и их unsigned версии). Попытка использовать его с float или double приведёт к ошибке компиляции.

### Приоритет операций

Как и в обычной математике, в C существует порядок выполнения арифметических операций:

  1. Умножение (*), деление (/), остаток от деления (%).

  2. Сложение (+), вычитание (-).

Операции с одинаковым приоритетом выполняются слева направо. Для изменения порядка выполнения можно использовать круглые скобки ``()``.

Пример: int result = 5 + 3 * 2; // result будет 11 (3 * 2 = 6, затем 5 + 6 = 11) int result_2 = (5 + 3) * 2; // result_2 будет 16 (5 + 3 = 8, затем 8 * 2 = 16)

2.3. Пример программы

Создадим программу math_demo.c, в которой объявим переменные, выполним операции и выведем результат на экран. Этот пример демонстрирует, как разные типы данных влияют на результат деления.

#include <stdio.h> // Подключаем стандартную библиотеку ввода/вывода, необходимую для printf

int main() { // Главная функция, с которой начинается выполнение программы
    // Объявление и инициализация целочисленных переменных
    int a = 10, b = 3;
    // Объявление и инициализация переменных с плавающей точкой
    float x = 10.0, y = 3.0;

    // Выполнение и вывод результатов целочисленных операций
    printf("a + b = %d\n", a + b); // %d - спецификатор формата для вывода целых чисел
    printf("a - b = %d\n", a - b);
    printf("a * b = %d\n", a * b);
    printf("a / b = %d\n", a / b); // Целочисленное деление: 10 / 3 = 3 (дробная часть отбрасывается)
    printf("a %% b = %d\n", a % b); // %% используется для вывода символа % в printf

    // Выполнение и вывод результата деления с плавающей точкой
    printf("x / y = %.2f\n", x / y); // %.2f - спецификатор для float, выводит 2 знака после запятой

    return 0; // Возвращаем 0, сигнализируя об успешном завершении программы
}

2.4. Компиляция и запуск

После того как вы создали файл math_demo.c, вам нужно его скомпилировать и запустить.

  1. Сохраните файл: Убедитесь, что вы сохранили код в файл с именем math_demo.c.

  2. Компиляция: Откройте терминал или командную строку и перейдите в каталог, где сохранён файл. Затем выполните команду:

    gcc math_demo.c -o math_demo
    
    • gcc: это название компилятора (GNU C Compiler), который преобразует ваш исходный код на C в исполняемый файл.

    • math_demo.c: это имя вашего исходного файла.

    • -o math_demo: это опция, которая указывает компилятору создать выходной исполняемый файл с именем math_demo. Без этой опции исполняемый файл по умолчанию будет называться a.out (на Linux/macOS) или a.exe (на Windows).

  3. Запуск: После успешной компиляции вы можете запустить программу, выполнив:

    ./math_demo
    
    • ./: указывает операционной системе искать исполняемый файл в текущем каталоге.

Вывод будет таким:

a + b = 13
a - b = 7
a * b = 30
a / b = 3
a % b = 1
x / y = 3.33

2.5. Заметки

  • При делении целых чисел (``int / int``), результат всегда является целым числом. Дробная часть просто отбрасывается (происходит усечение, а не округление). Например, 7 / 2 даст 3, а не 3.5.

  • Чтобы получить точный результат деления, используйте ``float`` или ``double`` для хотя бы одного из операндов. Если один из операндов является типом с плавающей точкой, C автоматически преобразует другой операнд к этому типу перед выполнением деления. Это называется неявным приведением типов.
    • Пример: (float)a / b или a / y. В первом случае a временно преобразуется во float.

  • Переполнение (Overflow): Будьте внимательны к переполнению. Если результат арифметической операции превышает максимальное значение, которое может хранить данный тип данных, это приведёт к непредсказуемому или некорректному поведению. Например, сложение двух больших int может дать отрицательное число, если результат превышает INT_MAX.

### Дополнительные комментарии

  • Инициализация переменных: Хорошей практикой является всегда инициализировать переменные при их объявлении, чтобы избежать неопределённых значений (так называемого «мусора» в памяти). Если вы не инициализируете переменную, она будет содержать случайное значение, которое было в этом участке памяти до того, как переменная была объявлена.

  • Константы: Для значений, которые не должны меняться в течение выполнения программы, можно использовать ключевое слово const. Например: const float PI = 3.14159;.

  • Вывод форматированных данных (``printf``): Функция printf очень мощная. Спецификаторы формата (%d, %.2f, %c) указывают, как интерпретировать и выводить переменные. \n используется для перехода на новую строку.