Задать вопрос
  • А можно ли, создать железный Интернет браузер, который будет полностью изолирован от OS?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Главный вопрос: что, по-вашему, «железный»?
    Если это отдельный процессор с ОС и программой — мы пришли к тому, от чего начинали: раз тут программа для фоннеймановской архитектуры, её так же можно хакнуть и заполучить пароли.
    Как заметил Adamos, чаще браузера обновляется только Флэш, а ведь браузеры пишутся высококлассными спецами. Когда Течнера «ушли» из Оперы, браузер начал загибаться.

    2. Хорошо, делаем реально железный браузер, например на ПЛИС — только стоить он будет сотни-тысячи долларов, непонятно, как объединить фоннеймановскую архитектуру и ПЛИС, и непонятно, как обновлять.

    3. Кроме того, есть концептуальные проблемы веба: XSS, XSRF, подслушивание по сторонним каналам (скажем, цифровой отпечаток путём рисования текста на холсте). Как известно, между безопасностью и танцующими котиками обыватель выберет котиков — вот и начали наворачивать, и в этих наворотах находят всё больше проблем. Чтобы быть безопасным, надо идентифицировать канал, отойти (!) от спецификации и зашумить его.

    Хром (а с ним и Яндекс, и Хроперу, а потом и Рыжая подключилась) стараются делать не отказоустойчивыми, а отказобезопасными: чтобы крайне сложно было довести взлом до реального овладения системой. И для этого они по-чёрному используют механизм, имеющийся в Windows: разделение памяти для процессов. (Потому, кстати, и говорят, что память сжирается со звуком «хром-хром».) В нашем простеньком процессоре, возможно, будет упрощённая ОС без такой защиты памяти.

    Наконец, типичный браузер очень жирный, частично из-за «защитного» программирования, частично из-за сложных спецификаций, частично из-за «злой» оптимизации. Реально хотите в стик впаять гигабайты ОЗУ?

    Откуда вообще берут пароли?
    1. Подслушивают троянской программой. Раз мы их вводим — значит, можно и подслушать. Или мы к нашему браузеру будем подключать и клавиатуру тоже?
    2. Подбирают. Крайне редко и обычно владелец пароля сам себе злобный буратино.
    3. Утекают открытым текстом или с недостаточной силы шифром. Железка бессильна.
    4. Сервер сам сдаёт данные кому надо. Железка бессильна.
    5. Провайдер сам перешифровывает трафик и требует установить самоподписанный сертификат. Железка бессильна.
    6. Выцыганивают. Пользователь сам себе злобный буратино.
    И на далёком-околопоследнем месте взлом браузера.
    Ответ написан
    Комментировать
  • Приложения корректировки форматирования кода?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое. Нужен сильно упрощённый синтаксический анализ, который делит код на директивы препроцессора, лексемы, операторы и комментарии, понимающий вложенность операторных скобок.
    Второе. Все эти лексемы выкидываем в выходной поток, добавляя незначащие символы по всоему усмотрению.
    Третье. Комментарии тоже придётся переформатировать, и с этим отдельный геморрой.
    Для Си — там есть ещё #define. Идеал — развернуть каждый #define, добавив спецсимволы «тут начало #define», «тут конец #define», форматнуть код, передвинуть левый спецсимвол как можно правее по незначащим символам (а правый — как можно левее), а потом опустить всё между спецсимволами, оставив только #define в том виде, как он был.
    Ответ написан
    Комментировать
  • Как сформулировать алгоритм для визуального редактирования запросов?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    С вопросом 3 оказалось всё одновременно просто и сложно. Дырка — это НЕ тождественный TRUE, это нечто нейтральное к операциям до или после (что приоритетнее). Если OR — внешняя операция, AND — приоритетная, TRUE/FALSE — соотв. нейтральный элемент, то…
    A OR (B AND TRUE) OR C = A OR B OR C, то есть AND уходит
    (A AND B) OR (TRUE AND C) = (A AND B) OR C, то есть OR занимает место AND.
    Так что действительно получается наименее приоритетный из () AND () и AND.

    С вопросом 1 так пока и есть.

    С вопросом 2 задача оказалась похожа на алгоритм сортировочной станции. С одной стороны, у нас нет ни скобок, ни префиксных/постфиксных функций, ни правоассоциативных операций.

    С другой — для каждого элемента стека мы держим op, firstIndex и lastIndex (индексы начала/конца операнда).
    Для первого элемента кидаем (⌀, 1, 1). Или (⌀, 0, 0), если индексы с нуля.
    Для второго (AND, 2, 2).
    Когда попадается третий (OR, 3, 3), срабатывает условие, и мы делаем операцию «сброс AND», состоящую из трё1х вещей:
    1. Для первого lastIndex в случае TRUE делаем переход на второе firstIndex.
    2. Где-то записываем: у первого lastIndex переход в случае FALSE будет таким же, как и у второго lastIndex.
    3. Объединяем эти два элемента, присвоив второй lastIndex первому элементу.
    Ну и добавляем наш (OR, 3, 3) в стек — это делается всегда, независимо от того, сколько раз сработало условие сброса.
    Как сбросить OR — думаю, понятно.
    Таким образом, теперь наш стек будет такой: (⌀, 1, 2) (OR, 3, 3).
    Наш план: (+2 −?) (+? −?) …
    Наш список аналогов: (1, 2, FALSE)

    Четвёртый элемент уйдёт в стек, пятый вызовет сразу два сброса.
    Стек (⌀, 1, 4) (OR, 5, 5).
    План: (+2 −?) (+? −3) (+4 −?) (+? −?)…
    Наш список аналогов: (1, 2, FALSE), (3, 4, FALSE), (2, 4, TRUE)

    Когда список кончится, проводим операцию сброса, пока в стеке не останется (⌀, 1, 8), а затем заполним список аналогов с конца.
    Если вопросительный знак всё-таки остался — это будет +TRUE или −FALSE.
    Ответ написан
    Комментировать
  • Variadic template c++?

    @Mercury13
    Программист на «си с крестами» и не только
    Этот шаблон вычисляет при компиляции такое:
    rbv<false, false, true, true>() = 11002.

    И состоит из двух частей.
    1. Для одного параметра у нас напрямую написан шаблон.

    2. Для false, false, true, true — у нас используется второй шаблон: a=false, b=false, d = (true, true).
    И он равняется (rbv<false, true, true> << 1) + false.

    Чтобы вычислить новый rbv, снова работает второй шаблон: a = false, b = true, d = (true).
    И он равняется (rbv<true, true> << 1) + false.

    Для третьего rbv у нас a = true, b = true, d = ().
    Внимание, список d может быть и пусттым. Потому, чтобы не было конфликта с первым шаблоном, второй пишется для двух и более параметров.
    И третье наше значение равняется (rbv<true> << 1) + true.

    Вот тут работает первый шаблон и получается 112.
    Дальше уже можно вычислить все rbv по очереди и получить 11002.
    Ответ написан
    4 комментария
  • Как запросить число через cin в C++ чтобы оно заканчивалось на цифру 5?

    @Mercury13
    Программист на «си с крестами» и не только
    Это невозможно, мэн волен ввести в консоль что угодно.
    Но ваша задача как программиста — каким-то образом не допустить некорректного ввода. То ли вывести ошибку, то ли самостийно округлить, то ли потребовать повторный ввод… Вы уж сами думайте, что требуется именно от вашей программы.
    Условие «кончается на 5» эквивалентно  «не делится на 10, но делится на 5».
    Ответ написан
  • Иконки и лицензия?

    @Mercury13
    Программист на «си с крестами» и не только
    Смотря какие работы, но там CC-BY-ND, то есть производные работы запрещены и нужна ссылка на них.
    Простое преобразование в PNG — НЕ производная работа, но вы, вероятно, не просто в PNG преобразуете…
    Ответ написан
  • Как работает данная программа C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Это обычная учебная программа и я за такой код бил бы по рукам. Нарекания к ней.
    1. Одновременное пользование printf и cout. Впрочем, несмотря на глючность, printf — хорошая штука, я и сам сделал более мощный аналог.
    2. Есть немного случаев, когда допустимы такие названия переменных/функций.
    • для счётчика цикла (i, j, k для переменной, it, jt, kt для итератора, u, v, w для новой фичи Си++11 — того, на что итератор указывает);
    • если мы преобразуем научную статью в код, и переменные так названы в статье.
    3. Даже название Count слишком расплывчатое — лучше что-то вроде nFound.
    UPD2. 4. Я бы переписал функцию P так, что for [0…горизонталь), при бое return false, цикл удался — return true.
    5. В музей говнокода!
    if (i == k)
        return true;
      else if (i != k)
        return false;
      else
        return !true && !false;

    Верно
    return (i==k);

    Программа проходится по 1-й горизонтали и ставит ферзя на каждую клетку. Если поместился — рекурсивно делает то же самое для 2-й горизонтали, если нет — значит, не повезло. Как только расчёт дойдёт до N-й горизонтали — мы нашли расположение ферзей, можно выводить.

    UPD. Ну, допустим, я бы переписал 2-ю функцию так (не меняя порядок параметров).
    void Backtracking(int currX, int &nFound, int boardSize, int queenY[])
    Ответ написан
    5 комментариев
  • Что делает эта строка?

    @Mercury13
    Программист на «си с крестами» и не только
    Связывает визуальные элементы навигации по БД с невизуальным источником данных.
    Устанавливает заголовок формы (у вас кодировка глючит).
    Запускает форму в модальном режиме.
    Ответ написан
    3 комментария
  • Как правильно использовать строки в плюсах?

    @Mercury13
    Программист на «си с крестами» и не только
    • std::string — как правило, если не указано противное.

    • QString, AnsiString/UnicodeString и прочие — в соответствующих фреймворках, обычно очень близко к интерфейсным функциям.

    • char* — практически не используется в реальном коде. В основном для оптимизации, если есть собственное управление памятью. Довелось как-то в собственном разборщике XML (работает в 2,5 раза медленнее рекордсмена, pugixml. Зато даже это в разы быстрее Excel’я, пространства имён «из коробки», расход памяти мизерный и программирование простейшее.)
    Зато по-чёрному используется его const-аналог.

    • const char*. Это может быть одинокий const char* + нуль-терминированная строка, или указатель+длина, или указатель на начало + указатель за конец.
    1. Если ожидается, что в функцию будем передавать строковый литерал.
    void writeEnum(st::Stream& st, int value, const char* names[]) {}
    
    enum class Letter { A, B, C, …, Z, NN };
    const char* natoNames[static_cast<int>(Letter::NN)] = { "alpha", "bravo", "charlie", … };
    writeEnum(someStream, static_cast<int>(Letter::E), natoName);

    2. Если операцию со строкой можно произвести «на месте», не заводя новую память: (trim, как известно,— обрезка пробелов в начале и конце)
    void trim(const char*& beg, const char*& end);

    3. Если структура данных паразитирует на чужих строках, не заводя своей памяти. Особенно если конструкция строк неизвестна (например, при передаче данных из плагина в плагин).
    struct ParasiteString { const char *beg, *end; };

    4. В библиотеках, если они реально настолько компактные, что нет нужды обязательно подключать жирный STL.

    • char[] — только как оптимизация, когда предельная длина строки известна и невелика.
    wchar_t* myFtos(double value, wchar_t* buf, const FloatFormat& format) {}
    
    wchar_t buf[100];
    myFtos(100.500, buf, FloatFormat::NICE);
    Ответ написан
    Комментировать
  • Как упаковать файл в проект и затем извлечь на C++ в Visual Studio?

    @Mercury13
    Программист на «си с крестами» и не только
    Есть три способа хранения картинки в EXE-файле.
    1. Bitmap-ресурсом. Несжатая, большинство библиотек позволяют загрузить её в одну строчку.
    2. Двоичным ресурсом. Сжатие возможно любое, загрузка пишется несколько дольше.
    3. Массивом, const unsigned char picture[] = { };

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

    И наконец: для чего её распаковывать? Реально нужно? (Например, мне однажды нужно было распаковывать картинки, потому что не хотел писать просмотрщик графики и пользовался штатным.)
    Если нужно — то куда-нибудь во временный каталог, который тоже нужно сначала получить.
    Ответ написан
    4 комментария
  • Как создать полностью пустое приложение на С++ в QT Creator?

    @Mercury13
    Программист на «си с крестами» и не только
    Простой способ (говорят, что есть глюки!)
    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        flags: Qt.Window | Qt.FramelessWindowHint   // <<<<<<
    
        Text {
            id: text1
            x: 77
            y: 59
            text: qsTr("Test!!!")
            font.pixelSize: 12
        }
    }


    Сложный описал Александр Таратин, и в нём эти глюки решены.
    Ответ написан
    Комментировать
  • Как настроить принт-сервер?

    @Mercury13
    Программист на «си с крестами» и не только
    Я бы посоветовал установить принтер не через SMB, а через RAW aka JetDirect (порт 9100).
    Надёжнее, но требует от пользователя определённых телодвижений.
    Ответ написан
    Комментировать
  • С++ В чем отличие #include "*" и #include?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое — это include собственного заголовка, то есть искать его в рабочем каталоге, в дополнение к стандартным каталогам компилятора.

    #include <file>
    This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option (see Invocation).

    #include "file"
    This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option.
    Ответ написан
    Комментировать
  • Почему чтение не разрешено?

    @Mercury13
    Программист на «си с крестами» и не только
    Отлично, вы уже запустили какой-то код. Но соглашение вызова так и не выдержали.
    1. Используйте соглашение вызова STDCALL. Тогда функция должна будет сама подчищать за собой. Поскольку в ней нет никаких локальных переменных, и подчистка не потребуется.
    typedef uint32_t WINAPI (*SomeFunc)();
    uint32_t result = (SomeFunc)exec();

    Заодно это позволит увидеть, что функция запустилась. В любом случае возвращаемое значение будет в eax.
    2. В конце нашей функции поставьте RET (опкод CB, если я не ошибаюсь).
    3. Вычислите и впатчите в наш код адрес переменной.

    я думал тут адрес указывается относительно текущего сегмента, как тогда быть?

    Начиная с защищённого режима 386, у нас «плоская память». Сегменты используются только загрузчиками, ВМами и прочей шушерой. Просто вычислите 32-битный адрес и запишите куда надо.
    Ответ написан
    Комментировать
  • Что выполняют эти функции в коде?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Найти «в лоб» НОД и похѣрить его.
    2. Найти «в лоб» НОК и отправить его туда же.
    Повторяю, обе функции крайне неэффективны, а их результат идёт в никуда. Как только управление пересечёт точку с запятой, переменная исчезнет.
    Ответ написан
    Комментировать
  • Из-за чего ошибка чтения?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы компилируете функцию в двоичный код и на месте же вызываете. Так что есть вопросы.
    1. Функции обеспечили правильное соглашение вызова?
    Мне что-то кажется, что при подобной ручной компиляции проще работать с соглашением PASCAL или STDCALL — ну, шут его знает.
    2. VirtualProtect работает с целыми страницами. Так что на куске памяти из сегмента данных (ну или из стека, полного кода не вижу) она в лучшем случае откажет, в худшем ничего не сделает. Проверьте, была ли ошибка.
    3. Первый параметр должен быть source, а не &source.
    Ответ написан
    Комментировать
  • Как исправить ошибку при компиляции файла.c в MinGW?

    @Mercury13
    Программист на «си с крестами» и не только
    Вот и положите этот libmingwex-0.dll в каталог с программой. Всё в порядке, программа скомпилировалась, остаётся пустить.
    Если такое случается при запуске компилятора — что-то с компилятором, и переустановить надо ЕГО.
    (Покопался по интернету, завтра проверю на работе свежие версии MinGW)
    Ответ написан
    Комментировать
  • Как исправить ошибку при чтении файла на с++?

    @Mercury13
    Программист на «си с крестами» и не только
    Велика вероятность, что ошибка в mods[mode]. Четырнадцать значений, записанных как 4+4+3+3 — что-то странное. Вы явно хотели сделать «кубик» из четырёх флагов, от младшего к старшему — W, A (причём работает как простое W, если A без W), B, RW
    Ответ написан
  • Как сравнить точность аналитического алгоритма и его программной реализации?

    @Mercury13
    Программист на «си с крестами» и не только
    Есть вычитание близких чисел? Какие-нибудь циклы вроде СЛАУ больших порядков и решения дифуров? Знакопеременные ряды? Если нет, можно писать, что вклад машинной арифметики в точность алгоритма незначителен.
    А если есть, нужно исследовать, кто и как может многократно усилить ошибки округления.
    Ради эксперимента можно также сравнить результаты во float и double.

    Пример алгоритма, который аналитически устойчив, а вычислительно — нет: e−x «в лоб» при достаточно больших x. Связан он с тем самым вычитанием близких чисел: промежуточные члены ряды могут быть достаточно большие, а в результате выходит 0,0…01.

    UPD. Вот такую книжку нашёл: info.alnam.ru/book_clm.php?id=26
    Ответ написан
    2 комментария