Ответы пользователя по тегу C
  • Что делают данные две функции в этом куске кода?

    15432
    @15432
    Системный программист ^_^
    Получение значения и установка конкретного бита в массиве данных

    Тож самое что
    return arr[n]
    и
    arr[n] = 1,
    Но с побитовым доступом вместо побайтового, для экономии места
    Ответ написан
    Комментировать
  • Как считать два байта числа?

    15432
    @15432
    Системный программист ^_^
    для 32-битных что-то типа такого. надо считать байты и развернуть их (вы же на x86 программу делаете? он little endian).
    unsigned int ReadBig32(FILE * in_file)
    {
        unsigned char temp[4];
        fread(temp, 1, 4, in_file);
        unsigned int result = temp[3] | (temp[2] << 8) | (temp[1] << 16) | (temp[0] << 24);
        return result;
    }
    Ответ написан
    Комментировать
  • Каким образом задать динамический массив символов (строку) если не известен изначальный размер вводимой строки?

    15432
    @15432
    Системный программист ^_^
    Только выделять динамически через malloc и считывать частями, перевыделяя память по достижении лимита.
    Ответ написан
    Комментировать
  • Сколько памяти занимает int в C?

    15432
    @15432
    Системный программист ^_^
    1. Чтоб узнать адресацию, напечатайте sizeof(void*) или любого другого указателя. Может оказаться, что программа действительно скомпилирована в х86
    2. Все норм у вас, 4 байта на int, 1 байт на char. Каждая "ячейка" в 1 байт, а не в 4
    Ответ написан
    4 комментария
  • Работа с потоками в СИ. Как скопировать информацию в файл?

    15432
    @15432
    Системный программист ^_^
    1) открывайте не-текстовые файлы через "rb" и "wb" соответственно
    2) для записи устанавливайте size в 1, а count в sizeof(...), так вы точно узнаете сколько байт записалось в возвращаемом значении
    3) если вы собираетесь не только писать, но и читать, открывайте файл не по "wb", а по "w+b"
    4) везде проверяйте возвращаемое значение, чтобы убедиться, что функция отработала. У вас наверняка последние fread зафейлились
    5) зачем читать/писать в медленные файлы? Работайте с данными прямо в памяти. new/malloc и вперед
    Ответ написан
    4 комментария
  • По какому принципу работает fscanf()/Cи?

    15432
    @15432
    Системный программист ^_^
    Место ниоткуда не появляется, вы должны выделить его самостоятельно. В вашем примере место как раз не выделено, поэтому строкой из файла перезапишутся ячейки, выделенные под локальные переменные, [возможно] возникнет повреждение стека и падение программы. Попробуйте проделать то же самое, но с более длинной строкой, чем "cat"
    Ответ написан
    Комментировать
  • Как задать значения для диапазона битов в переменной?

    15432
    @15432
    Системный программист ^_^
    Установить 15 бит в 1:
    var |= (1 << 14);
    Установить 15 бит в 0:
    var &= ~(1ul << 14);

    Установить как вы просили:
    var= 0x000100100fe80010ul | 0xfffffffff00ffffful;
    Ответ написан
  • Как происходит преобразование из fixed-point числа в floating-point?

    15432
    @15432
    Системный программист ^_^
    Конкретно в вашем примере происходит вот что:
    1) переменной "а" присваивается значение 1736704
    2) переменная "а" переводится в float, получается значение 1736704.0
    3) производится деление чисел с плавающей точкой- 1736704.0 на 65536.0
    4) результат деления (26.5) записывается в переменную "b"

    Настоящее преобразование чисел, о котором вы и спрашиваете, происходит только на шаге 2. В архитектуре x86 оно происходит с использованием специальных ассемблерных команд и floating-point сопроцессора. То есть быстро и автоматически. В более простых архитектурах это может быть реализовано программно (всего лишь вычислить экспоненту и мантиссу)
    https://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D...
    Ответ написан
    Комментировать
  • Как обезопасить функцию от прерывания?

    15432
    @15432
    Системный программист ^_^
    Для таких целей вводятся дополнительные обертки над disable_irq и enable_irq, которые вычисляют "глубину" запрета прерываний. По факту просто есть глобальный счетчик, который увеличивается при каждом вызове ext_disable_irq и уменьшается при ext_enable_irq. Настоящее включение прерываний происходит в самом конце ext_enable_irq и только если счетчик в этот момент равен нулю
    Ответ написан
    5 комментариев
  • Как узнать какие функции доступны в dll?

    15432
    @15432
    Системный программист ^_^
    Открываю IDA и смотрю что за функции торчат наружу, какие параметры принимают и что делают))
    Ответ написан
    8 комментариев
  • Как работает эта программа, определяющая порядок байтов в компьютере?

    15432
    @15432
    Системный программист ^_^
    Создаётся переменная типа unsigned short int, которая почти во всех современных компиляторах имеет размер 2 байта. Затем ей присваивается значение 1. В случае архитектуры Little Endian, единица запишется в младший байт переменной, а в случае Big Endian - в старший байт. Дальше именно это и проверяется - конструкция *((unsigned char *) &x) получает значение младшего байта переменной. Если там оказался ноль, значит архитектура Big Endian.

    Код, делающий то же самое, но проверяющий старший байт:
    #include <stdio.h>
    unsigned short x = 1; /* 0x0001 */
    int main(void)
    {
      printf("%s\n", *((unsigned char *) &x + 1) == 0 ? "little-endian" : "big-endian");
      return 0;
    }
    Ответ написан
    Комментировать
  • Почему не создают компьютеры с машинным языком на C/C++?

    15432
    @15432
    Системный программист ^_^
    Процессор это тупая железяка из транзисторов. Ну ладно, не настолько тупая, в современных x86 процессорах машинные коды на лету транслируются в еще более низкий уровень встроенным микрокодом. Но все все равно предположим, что это тупая железяка типа Intel 8086. Как происходит выполнение программы - процессор считывает очередной байт кода и смотрит, что же он такое считал. По значению байта, он определяет, что это за команда (сложение, вычитание) и сколько ещё нужно считать байт конкретно этого машинного слова (а они в x86 могут быть разной длины). Все это происходит на уровне железа, то есть нечто вроде "пятый бит 0, третий бит 1, ага! Это команда сложения двух восьмибитных регистров, надо переключить линию данных на арифметико-логическое устройство и считать туда еще два байта на шину данных. То есть операции очень и очень простые, на уровне бит, сигналов и чтения данных, никакого анализа кода и уж тем более никаких имен переменных. Вы же предлагаете на аппаратном уровне парсить сишный код, в котором при последовательном чтении иногда невозможно определить, что делать в данный момент!! А процессор в это время будет простаивать и считывать из памяти кучу ненужного текста.
    Я вообще не представляю, как на уровне железа и транзисторов можно сделать синтаксический и лексический анализ сишного файла. Разве что сделать настоящий электронный мозг с миллиардом нейронов. Это уж точно не будет быстро, это вообще работать не будет. Изучите устройство компьютера, как именно работает процессор, научитесь думать на языке ассемблера, и поймёте всю абсурдность вашего предложения.
    Ответ написан
    4 комментария
  • Как проверить ввод на число в С?

    15432
    @15432
    Системный программист ^_^
    что вы подразумеваете под "зацикливается"?
    первый вариант действительно после неправильного ввода начинает бесконечно писать "number", но второй вариант вполне адекватно спрашивает number, пока не получит корректный номер. если вам нужно спросить только один раз, уберите while, а условие var != 1 используйте далее для определения корректности ввода (при вводе число, var будет равен 1)
    Ответ написан
  • Почему нельзя использовать указатель без объявления переменной?

    15432
    @15432
    Системный программист ^_^
    Так создавайте указатель сразу с местом, куда записывать, компилятор такое умеет - массив называется.
    int pvar[1];
    Почти тот же самый указатель, только теперь на стеке было дополнительно выделено место, и он в него указывает. Только изменять место, куда указывает, нельзя.
    Ответ написан
  • Сервер на Си, как и зачем?

    15432
    @15432
    Системный программист ^_^
    На Си легко "выстрелить себе в ногу" и упустить утечки памяти, переполнение буфера, гонки данных в параллельных потоках. Убедился в этом при создании похожего проекта.

    Почитать - если стремитесь к максимальному быстродействию, разберитесь как работать с epoll и неблокирующими сокетами. Для работы по HTTP почитайте спецификацию и какие поля могут быть, как их парсить и обрабатывать, и т.д. Для парсинга пригодятся state-машины (это уже "основы конструирования компиляторов", по теме есть много вузовских учебников). Работа с сокетами напрямую подразумевает некий кастомный протокол - нужно придумать соглашения по формату передаваемых данных (заголовок, пакеты, и т.д.)
    Ответ написан
    Комментировать
  • Обработка разнобитных bmp картинок, в чем конкретная разница?

    15432
    @15432
    Системный программист ^_^
    В случае 24 бит, на каждый пиксель приходится по 3 байта - значения для красного, зелёного и синего цветов.
    Для 16 бит на пиксель приходится уже 2 байта, придётся "выдёргивать" цвета уже побитно (на красный и синий отводится 5 бит данных, на зелёный 6 бит)
    8 бит - один байт на пиксель, либо оттенки серого, либо в заголовке будет таблица соответствий цветов, в которой каждому значению байта соответствует 24-битное значение цвета. Всё это придётся расшифровывать.
    2 и 4 бита аналогично 8 бит, только ещё меньше цветов.
    Помимо всего этого, может присутствовать RLE сжатие, которое придётся распаковывать и запаковывать. Сжатие примитивное, но всё же экономит место.

    P.S. Если вы используете BMP библиотеку, которая любой формат вам превращает в набор значений RGB, заморачиваться и не нужно, либа сделает всё за вас.
    Ответ написан
    3 комментария
  • Как происходит чтение с файловой системы?

    15432
    @15432
    Системный программист ^_^
    В Windows драйвера находятся в ядре. Новый поток не создается, драйвер лишь обрабатывает поступающие запросы на чтение и перебрасывает их другим драйверам, например, usb mass storage или ahci. Которые, в свою очередь, взаимодействуют с хост-контроллерами USB или ATA.
    Сам вызов ReadFile блокирует выполнение программы до завершения операции (но можно и асинхронно)
    Ответ написан
    4 комментария
  • Что означает char **s на языке Си?

    15432
    @15432
    Системный программист ^_^
    char * buffer = NULL;
    char ** bufptr = &buffer;
    some_alloc_function(bufptr);
    If (buffer != NULL)
    printf("alloc success\n");
    Ответ написан
    3 комментария
  • Как разжать JPEG, подредактировать и сжать обратно на той же DQT (таблице квантования), которая была в оригинале?

    15432
    @15432
    Системный программист ^_^
    эта программа пережимает только измененные блоки.
    вряд ли оставляет полностью прежнюю таблцицу, но мало ли..
    www.betterjpeg.com
    Ответ написан
    Комментировать
  • Почему программа выдает не тот результат, который нужен?

    15432
    @15432
    Системный программист ^_^
    Переполнение происходит, scanf читает всю строку до символа перевода строки, но буфер всего 4 байта, и происходит перезапись данных, что за буфером. Видимо дальше хранится имя файла, которое и выводится. Необходимо использовать безопасный scanf (в винде это scanf_s, в линуксе не знаю).
    Ответ написан