C с использованием модуля - программирование
Подтвердить что ты не робот

C с использованием модуля

Я наткнулся на интригующий C-код, который печатает A + B, но мне трудно понять его.

Формат ввода:

A B

где A, B - целые числа от 0 до 10 разделенные одним пространством.

Код:

main( n )
{
    gets( &n );
    printf("%d", n % 85 - 43);
}

Это предназначено для короткого кодирования, пожалуйста, не обращайте внимания на предупреждения.

Насколько я понимаю до сих пор:

gets( &n ) сохраняет значения ASCII A, пробела и B в нижних трех байтах n. Например, A = 3 и B = 8 дают n = 0x00382033. Приведенные условия предотвращают переполнение n. Но я не понимаю, как n % 85 - 43 дает A + B

Как вы можете найти эти цифры?

4b9b3361

Ответ 1

С little-endian ints (и предполагая текст ASCII и 8-битные байты, а также все другие предположения, которые требуется коду) и игнорируя все элементы с технически неправильными в современном C в коде, ваш "Что я понимаю" до сих пор "является правильным.

gets(&n) будет хранить значения ASCII A, пробела и B в первые 3 байта n. Он также сохранит нулевой ограничитель в 4-й байт. Сохранение этих значений ASCII в этих байтах n приводит к n принимающему значение B*256*256 + space*256 + A, где B, space и A представляют собой соответствующие значения ASCII.

256 mod 85 равен 1, поэтому по свойствам модульной арифметики,

(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85

Кстати, с четырьмя байтами big-endian ints мы получаем

(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85

поэтому утверждение не имеет значения, если у нас есть 4-байтовый ints. (Большие или меньшие ints могут быть проблемой, например, с 8-байтовыми ints, нам нужно будет беспокоиться о том, что в байтах n который gets, не задано.)

Пробел - ASCII 32, а значение ASCII для символа цифры равно 48 + значению цифры. Определение a и b в качестве числовых значений введенных цифр (а не значений ASCII цифровых символов), мы имеем

(B + space + A) % 85 = (b + 48 + 32 + a + 48) % 85
                     = (a + b + 128) % 85
                     = (a + b + 43) % 85

(B + space + A) % 85 - 43 = (a + b + 43) % 85 - 43
                          = (a + b) % 85
                          = a + b

где последние две эквивалентности полагаются на то, что a и b принимают значения от 0 до 9.