0Pricing
C Academy · Урок

Ошибки преобразования

Переполнение и усечение

«Ошибки преобразования» — бесплатный урок C Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.

Преобразования могут навредить

Неявные преобразования удобны, но могут привести к переполнению, усечению и неожиданностям со знаками. В этом уроке рассматриваются такие ловушки.

#include <stdio.h>
int main(void) {
    printf("Beware silent conversions\n");
    return 0;
}

Переполнение целого числа

Присваивание значения, слишком большого для целевого целого типа, приводит к зацикливанию значения или потере данных.

#include <stdio.h>
#include <limits.h>
int main(void) {
    int max = INT_MAX;
    printf("INT_MAX = %d\n", max);
    return 0;
}

Усечение при сужении типа

При помещении большого значения в меньший тип сохраняются только младшие биты, что незаметно искажает число.

#include <stdio.h>
int main(void) {
    int big = 300;
    unsigned char small = (unsigned char)big;
    printf("small = %d\n", small);
    return 0;
}

Смешивание знаковых и беззнаковых типов

При смешивании знакового и беззнакового типов знаковое значение преобразуется в беззнаковое, превращая отрицательные числа в огромные положительные.

#include <stdio.h>
int main(void) {
    int a = -1;
    unsigned int b = 1;
    if (a > b)
        printf("surprise: -1 > 1 as unsigned\n");
    return 0;
}

Ловушка со счётчиком цикла

Счётчик цикла типа unsigned, опускающийся ниже нуля, зацикливается на огромном значении, вызывая бесконечный цикл. При обратном счёте используйте знаковые счётчики.

#include <stdio.h>
int main(void) {
    for (int i = 3; i >= 0; i--)
        printf("%d ", i);
    printf("\n");
    return 0;
}

Потеря при преобразовании float в int

Преобразование float в int отбрасывает дробную часть. Если значение выходит за диапазон int, результат не определён.

#include <stdio.h>
int main(void) {
    double d = 3.99;
    int n = (int)d;
    printf("n = %d\n", n);
    return 0;
}

Потеря точности при преобразовании double в float

При сохранении double высокой точности в float цифры отбрасываются, и эта ошибка может накапливаться в длинных вычислениях.

#include <stdio.h>
int main(void) {
    double d = 1.123456789012345;
    float f = (float)d;
    printf("%.7f\n", f);
    return 0;
}

Неожиданности со знаком char

Знаковость типа char определяется реализацией. Используйте unsigned char для байтовых значений, чтобы избежать отрицательных результатов.

#include <stdio.h>
int main(void) {
    unsigned char b = 200;
    printf("b = %d\n", b);
    return 0;
}

Сначала деление, затем преобразование

Целочисленное деление с последующим преобразованием не может восстановить потерянную дробную часть. Выполняйте преобразование до деления.

#include <stdio.h>
int main(void) {
    int a = 7, b = 2;
    double wrong = (double)(a / b);
    double right = (double)a / b;
    printf("%.1f vs %.1f\n", wrong, right);
    return 0;
}

Сравнение диапазонов

Используйте константы из limits.h, чтобы понять диапазон, который может хранить тип, прежде чем считать, что значение поместится.

#include <stdio.h>
#include <limits.h>
int main(void) {
    printf("char range: %d to %d\n", CHAR_MIN, CHAR_MAX);
    return 0;
}

Безопасные преобразования

Проверяйте диапазоны перед сужением типа, при сомнениях предпочитайте более широкие типы и явно указывайте преобразования, чтобы намерение было понятно.

#include <stdio.h>
int main(void) {
    long value = 200;
    if (value >= 0 && value <= 255)
        printf("fits in a byte: %ld\n", value);
    return 0;
}

Быстрая проверка

Проверьте своё понимание проблем преобразований.

Итоги: проблемы преобразований

Вы узнали об опасностях неявных преобразований.

  • Сужение типа может привести к переполнению или усечению
  • Смешивание знаковых и беззнаковых типов меняет результаты сравнений
  • Беззнаковые счётчики зацикливаются при переходе ниже нуля
  • Выполняйте преобразование до деления, чтобы сохранить дробные части
  • Проверяйте диапазоны и явно указывайте преобразования

Часто задаваемые вопросы

Урок «Ошибки преобразования» бесплатный?

Да — полный текст урока «Ошибки преобразования» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.

Чему я научусь в уроке «Ошибки преобразования»?

Переполнение и усечение Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Ошибки преобразования»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Неявные преобразования
  2. Явные приведения
  3. Преобразование целых и вещественных чисел
  4. Ошибки преобразования
← Назад к C Academy