Программы
Функции и типы в первом приближении

Функции и типы в первом приближении

Назад, к "первой утилите".

0 программистов ругал сердитый шeф,

Потом уволил одного, и стало их FF.

– Юрий Нестеренко, "0A программистов"

Сейчас мы немного рассмотрим теорию, чтобы заполнить пространство под вопросом о false – будет много букв – сложнее случайно увидеть "ответ".

Но эта теория тут не просто так: наша функция main – хоть и необычная, но функция. Опять же, мы объявили саму функцию main как функцию, возвращающую int – тип данных. Очень хитрый тип данных.

Немного о функциях

Итак, в общем виде функцию можно описать следующим шаблоном:

<возвращаемый тип> <имя функции>(<тип1> <арг1>, <тип1> <арг2>, ...) {
    <тело функции>
}

Функция имеет свою локальную область видимости – переменные, определённые внутри неё недоступны снаружи. По факту они создаются на стеке и после выхода из функции стек откатится к состоянию до попадания в функцию – данные станут недоступны (разве что не найдётся какой-то обходной путь – хак).

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

Возврат значений производится, как и во многих языках с помошью return.

Стоит заметить, что в отличии от всяких Go и Python, мы не можем вернуть сразу несколько значений. Это ограничение, естественно, можно обойти, но оно же во многом определило, как создаются API многих функций. Так, на будущее.

Что такое int?

Вернёмся к нашему "хитрому" типу данных. Типы данных во многих существующих языках – набор функций и ограничений на хранимую в переменной информацию. В Си же это размер байт, выделенных на переменную (этакое ограничение) + его представление (удобство, "синтаксический сахар" для работы с байтами).

В чём же хитрость?

Начнём с того, что int – знаковое целое – то есть туда можно положить целое число: хоть отрицательное, хоть положительное. Но не очень большое.

Размер int зависит то платформы. Посмотреть размер типа или переменной можно функцией sizeof:

    int main() {
        return sizeof(int);
    }

Собираем:

    clang int_size.c -o ./int_size

Запускаем:

falseecho $?
    4

– видим, что в нашем случае int занимает 4 байта.

А что, если мы туда положим что-то большее?

    int main(void) {
        int num = 0xffffffff;
        return num + 12;
    }

Переполнение:

echo $?
    11

На самом деле 0xffffffff – не самый большой int, самый большой – 0x7FFFFFFF из-за устройства представления байтов знаковым целым числом. В диапозоне [8000000, 0xffffffff] - отрицательные числа.

То есть первый бит – бит знака. Так что, если вы выйдите за самое большое число int, вы внезапно получите самое маленькое число... Вот такой он, хитрый int!

Однако, 0xffffffff прекрасно справляется с демонстрацией переполнения 0xffffffff + 12 = 11.

Ответ на загадку

Так что, если взять 0xffffffff и прибавить к нему 1... И вернуть это... В общем, это явно не было нулём, но стало! Более того: код возврата вообще ограничен беззнаковым байтом, так что каждое число, кратное 256 – также окажется истиной! И да, это уже вопросы к самому коду.

Также может быть вам интересно:

Первая реальная утилита

Вы когда-нибудь писали код командной строки? А из чего она состоит? А поковыряемся чутка!

Читать »

Почему мы начали не с "Hello World"?

Часто начинают именно с "Hello world", но для нас это не подходит

Читать »
Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

Современные сайты редко ограничиваются только текстом и вёрсткой. Часто в заметках красуются фотографии, а рядом с описанием товаров - их изображения.

Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

Во время работы программы часто нужно сохранять некоторые важные записи о процессе выполнения команды. В Python есть довольно мощный модуль для работы с логами - давайте разберёмся с тем, как его использовать.

Фото Шаблон разработки ПО — Model View Controller (MVC)

Шаблон разработки ПО — Model View Controller (MVC)

MVC - один из самых распространённых архитектурных шаблонов разработки. Часто используется в различных фреймворках. В том числе и в Django.

Фото Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если одни и те же данные нужны в разных местах, лучше сделать свой контекст-процессор.

Фото Пример своей консольной команды в Django проекте

Пример своей консольной команды в Django проекте

Если вы работали с Django проектом, то, скорее всего, запускали команды из консоли (manage.py). В Django есть простой способ писать свои команды для управления проектом.

Фото Разграничение прав доступа на Django сайте

Разграничение прав доступа на Django сайте

Почти на любом веб-сайте необходимо разделять пользователей на группы и предоставлять им разные возможности. В Django есть довольно серьёзная система прав доступа для пользователей - давайте её рассмотрим!

Фото Пользователи и их создание в Django - своя регистрация на сайте

Пользователи и их создание в Django - своя регистрация на сайте

Если вашим сайтом должны активно пользоваться несколько человек, то полезно их различать, а значит - надо уметь создавать пользователей, либо предоставлять возможность регистрации Django пользователей.