Ответы пользователя по тегу C
  • Как сэмулировать нажатие клавишы Пробел на Arduino?

    @Mercury13
    Программист на «си с крестами» и не только
    Странно: если ардуина — USB-клавиатура, то она передаёт именно нажатие физической клавиши «пробел».
    Впрочем, у вас тут стоит пробел в кавычках " ". Скорее всего, именно в этом ошибка: при плохой проверке типов, присущей Си, в функцию (которая требует char) будет передан адрес строки «пробел».

    Надо Keyboard.press(' '); или Keyboard.write(' ');. В одиночных кавычках. То есть целое число.

    Кроме того, Keyboard.press только нажимает на кнопку, и разбирай, как эту кнопку «отпустить». По крайней мере, моя «лисичка» требует именно ОТПУСКАНИЯ пробела. Как вариант — тот же Keyboard.write, который жмёт и отпускает.
    Ответ написан
    1 комментарий
  • Если в языке есть циклы и условия это потому, что процессор всё это непосредственно поддерживает?

    @Mercury13
    Программист на «си с крестами» и не только
    Циклы и условия — это для того, чтобы язык был полным по Тьюрингу (т.е. был — на бесконечной памяти, разумеется — эквивалентен машине Тьюринга). На языке процессора циклы и условия выглядят совсем не так (там, по сути, куча GOTO и IF GOTO), но машинный код тоже полон по Тьюрингу.

    Впрочем, есть вещи, которые поддерживаются языком именно потому, что процессор их поддерживает. Обычно хватает поддержки на уровне библиотек: атомарные операции, аппаратное шифрование… Но есть и вещи, вошедшие в собственно язык. Вот несколько штук.
    • Нуль-терминированные строки, насколько мне известно, включили в Си потому, что на том PDP это было быстро.
    • Большинство языков, деля с остатком отрицательные числа, говорят, что округление идёт к нулю (знак остатка = знаку делимого) — потому что так работает большинство процессоров.
    • Модель памяти Java говорит: нет невесть откуда взявшихся значений (другими словами, если мы считали 1234 — значит, до этого кто-то его туда записал), за исключением не-volatile long и double. На 16-битный процессор многопоточную Яву ставить бессмысленно, а 32-битный — это уже дело.

    Вызовы функций — с ними всё наоборот. Как только выяснилось, что это хорошая штука, для них сделали аппаратную поддержку. А так — для вызова функций (в удобоваримом для компилятора виде, с хорошо стандартизованными соглашениями вызова) хватает косвенной адресации и пары лишних регистров.
    Ответ написан
    Комментировать
  • Почему в битовых сдвигах остаётся минус?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Двоичное представление −7 будет немного другое: 256−7 = 249 = 1111.1001
    2. В знаковом типе используется т.н. арифметический сдвиг вправо: на освободившееся место приходит не 0, а копия верхнего бита (простой и арифметический сдвиг влево идентичны). Возьми вместо −7 что-нибудь начинающееся на 10 в двоичной системе — например, 0x8000.FFFF — и объясни, что выходит.
    Ответ написан
    Комментировать
  • Как реализовать изменение размера файла на Си?

    @Mercury13
    Программист на «си с крестами» и не только
    Чтобы увеличить файл, надо дописать в конец.
    Libc — fopen(..., "wa");
    WinApi — CreateFile с нужными правами, затем SetFilePointer в конец и дописывай на здоровье.

    Чтобы уменьшить файл
    В Libc этого нет, есть функции POSIX truncate/ftruncate, в Win32 — _chsize.
    WinApi — SetEndOfFile.
    Ответ написан
    Комментировать
  • Как лечить char warning overflow при считывании с файла?

    @Mercury13
    Программист на «си с крестами» и не только
    fin.getline(pRun->sBooks.chBook, 99, static_cast<char>('»'));


    Всё у вас правильно. А в Си char почему-то (обычно) знаковый.
    Ответ написан
  • Как правильно обновлять элемент EDITTEXT?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Для переноса строк использовать символ 13 (\r).

    2. ES_AUTOVSCROLL Automatically scrolls text up one page when the user presses the ENTER key on the last line.
    Так что не это тебе нужно, нужно просто ставить курсор в конец (исходники Delphi дают сообщение EM_SETSEL).

    3. Я не знаю, как ты управляешь памятью, но будь с этим предельно осторожен.

    4. strcat будет медленным, когда данных будет много, подумай про имитацию ввода (сообщение EM_REPLACESEL).
    Ответ написан
    1 комментарий
  • Как найти минимальное количество перестановок?

    @Mercury13
    Программист на «си с крестами» и не только
    Рассмотрим порядок чёт-нечет-чёт-нечет…
    Считаем, сколько чётных не на своих местах (=a).
    И сколько нечётных не на своих местах (=b).
    Если a≠b, у нас нет N чётных и N нечётных — выводим «неверный набор данных».
    А если равны, то для порядка чёт-нечет нужны a замен. Для противоположного — N-a.
    Вот и получается ответ min(a, N−a).
    Ответ написан
    7 комментариев
  • Как создать custom массив, где каждому элементу выдано N-байт?

    @Mercury13
    Программист на «си с крестами» и не только
    1. В какой стек? В стек вызовов так не скопируешь (насколько я знаю, в некоторых реализациях Си есть функция alloca, выделяющая память на стеке до return), а в самодельный стек — тут ничего не сказано про стековую структуру, ёмкость и указатель на верхушку. В куче вы выделяете память, в куче…
    2. Посмотри функцию calloc. В Си в такой ситуёвине принято именно указывать количество байт на один элемент.
    3. Sizeof, чтобы ты знал, вычисляется при компиляции.
    Ответ написан
    Комментировать
  • Как инициализировать строку PCHAR в с++?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Что принимает система: PCHAR или PCHAR*?
    2. Если версии Delphi достаточно новые, PCHAR — это, скорее всего, wchar_t* и надо просто передавать «широкую» строчку L"usb3000".
    3. Постарайся, чтобы reinterpret_cast не было; это признак того, что ты делаешь что-то неверно. Единственное, где он в подобных API допустим — это в callback’ах для передачи замыкания (информации о том, какая подпрограмма и при каких обстоятельствах запустила функцию, вызвавшую callback). P.S. Надумал и второе назначение reinterpret_cast — функция, которая может принимать данные разных типов (вроде SendMessage из Win32).
    Ответ написан
    Комментировать
  • В чем разница int mas[], int mas[0], int mas[100]?

    @Mercury13
    Программист на «си с крестами» и не только
    int mas[] используется в трёх местах.

    1. Когда размер определяется инициализатором: int mas[] = { 1, 2, 3, 4, 5 };
    2. Чтобы задать параметр вида «массив неопределённой длины»: double vecLen(double a[], int size) {}
    Си не может жёстко задавать размер массива в параметре, чтобы больший или меньший не подходил; даже если напишешь напишешь double vecLen(double a[3]) {}, всё равно другой массив подойдёт. Си++ задаёт так: double vecLen(double (&a)[3]) {})
    3. Подсказал jcmvbkbc, реально мало на что нужно: extern int a[].

    int mas[0] создаёт массив нулевой длины, надобности в котором, понятное дело, никакой. Зато этот код используется, чтобы накладывать структуру данных, которая заканчивается массивом неизвестной длины, на какой-то буфер в памяти — как указатель: тут массив (C++ не проверяет выход за границу).

    struct Packet {
      unsigned short length;
      unsigned char data[0];
    }
    
    void processPacket(void* data, unsigned length)
    {
       // Простите уж, что перешёл на C++
       const Packet& packet = *reinterpret_cast<Packet*>(data);
       if (length != sizeof(Packet) + packet.length)
         throw std::logic_error("Packet size mismatch");
       for (unsigned i = 0; i < packet.length; ++i) {}
    }
    Ответ написан
    8 комментариев
  • Возможно ли создать "универсальный" драйвер для исполнения произвольного кода в Ring0?

    @Mercury13
    Программист на «си с крестами» и не только
    Это к Sony или StarForce. И те, и другие делали заSHITу и прокалывались на подобном.
    Ответ написан