Ответы пользователя по тегу Программирование
  • Как найти машинную бесконечность?

    @Mercury13
    Программист на «си с крестами» и не только
    Важный вопрос: есть ли неявная единица и денормализованные числа?
    Считаем, что всё-таки есть, порядок несмещённый, записан дополнительным кодом, денормализованное число записывается 10…00 в порядке. (А то всяко бывает, в нашем родном float порядок смещён на 01…11).
    Тогда максимальное число, которое можно записать, равняется 1,1…1112·22^13−1.
    Ну а бесконечность — примерно 2·22^13−1 = 22^13.
    Wolfram Alpha говорит, что это 1,091·102466.
    Ответ написан
    5 комментариев
  • Почему символ 8, в десятичной системе счисления это 56, а не 8?

    @Mercury13
    Программист на «си с крестами» и не только
    Попробую ответить на вопрос: почему в ASCII цифра «8» это 38 hex = 56 dec.

    Дело в том, что в те времена единственным средством вывода был телетайп. И люди просто кидали в одну кучу понятия «текстовая строка» и «протокол обмена». А значит, требовался немаленький набор управляющих символов. Для удобства программирования управляющим символам лучше всего быть в начале таблицы: в ассемблере это будет «если код >= 32, обработать как символ, иначе сделать прыжок по таблице».

    В одной самодельной кодировке цифры были именно что 0…9, пробел −1, ещё пара управляющих символов −2, −3. Но это уже новодел.
    Ответ написан
    Комментировать
  • Циклы. While, do while, for, чем отличаются?

    @Mercury13
    Программист на «си с крестами» и не только
    While — сначала проверь, потом сделай, и так по кругу.
    Do — сначала сделай, потом проверь, и так по кругу.

    Отличаются они только случаем, когда условие не выполняется: while не пройдёт, а do пройдёт один раз.
    // Пример 1.
    // верно
    while (впереди свободно) шаг;
    // неверно — можно врезаться в препятствие, если нельзя сделать ни шагу
    do шаг while (впереди свободно);
    
    // Пример 2.
    // Неверно — пока у вас в руках нет рубашки, условие цикла некорректно
    while (рубашка грязная) возьми рубашку;
    // верно
    do возьми рубашку; while (рубашка грязная);


    Циклы for, foreach и прочие — это разновидность цикла while (не do!!), сделанная для специального сценария: пройти некий набор объектов.
    Ответ написан
    Комментировать
  • Как называется это понятие?

    @Mercury13
    Программист на «си с крестами» и не только
    Самомодифицирующийся код.
    Ответ написан
    Комментировать
  • Что нужно сделать в этой задаче?

    @Mercury13
    Программист на «си с крестами» и не только
    Если N=20, X=3, Y=5, то наш выход — 8.
    3, 5, 6, 9, 10, 12, 15, 18.

    Лобовое решение — пройти [2, N) и пересчитать нужные числа.

    Идея умного решения. Если X и Y гарантированно простые, то эти самые числа повторяются с шагом X·Y.
    3, 5, 6, 9, 10, 12, 15
    18, 20, 21, 24, 25, 27, 30
    А дальше думайте сами.
    Ответ написан
    Комментировать
  • Нужно ли программисту изобретать велосипед?

    @Mercury13
    Программист на «си с крестами» и не только
    Представьте себе, у меня в одной коммерческой программе есть велосипед и чужая библиотека, занимающиеся одним и тем же, доступом к XLSX.

    В одном месте пользователи иногда скармливают программе огромный XLSX размером мегабайт этак в 20, что соответствует ≈100M памяти, если развернуть в структуры данных, >130M — если сериализовать в XML, и добрых полгига — если этот XML разобрать рекордной библиотекой, а ведь в той XLSX-библиотеке, которую мы купили, ничего рекордного не было. На x86 не хватало памяти ни на что, на x64 тормозило адски. В общем, сделал потоковый разбор XML с пространствами имён «из коробки» и предельно простой разбор XLSX без стилей, без картинок и диаграмм, без сохранения — этот XLSX грузило ≈3 с, из которых <0,5 — раззиповка, ≈1,1 — разбор XML, остальное — собственно разбор XLSX. Для сравнения: Excel грузил 10 секунд, LOo до 6-й линейки вообще не мог загрузить такой файл. Расход памяти — исключительно та сотня, что идёт на структуры данных; расходы памяти на раззиповку и разбор пренебрежимо малы.

    В другом месте таких проблем нет, и я даже не пытался перевести этот момент на свою библиотеку.

    К слову о велосипедах: они тоже глючат, и один японец обнаруживал не одну и не две ошибки, связанных с этим разбором специальных японских XLSX.

    В общем, с велосипедами надо быть осторожным, и причины сделать велосипед в производственном коде — это…
    • Производительность. Пример выше.
    • Функциональность. Хочется написать своё сохранение в XLSX, потому что нужны заметки, которых, кажется, не поддерживает ни одна библиотека.
    • Глючьё. Допустим, я отказался от встроенного в Qt диалога открытия файла, потому что он прикрывал одну важную функцию WinXP+: сохранял, какой каталог был текущим.
    Ответ написан
    Комментировать
  • Что такое "программирование сокетов"?

    @Mercury13
    Программист на «си с крестами» и не только
    Сокет — это абстракция, принятая в Unix и перешедшая в Windows, представляющая собой сетевое соединение.
    https://ru.wikipedia.org/wiki/Сокеты_Беркли
    Ответ написан
    Комментировать
  • Как происходит визуализация интерфейса декстопных приложений?

    @Mercury13
    Программист на «си с крестами» и не только
    УРОВЕНЬ 1. ПРОГРАММНОЕ РИСОВАНИЕ. В экстремальном случае — программист сам рисует элементы управления, как на Canvas’е. Его опустим. Так, например, поступают в разработке игр, когда элементов мало, и они должны быть предельно стилизованы. Но и в таком случае лучше делать библиотеку объектов.

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

    УРОВЕНЬ 2. ОБЪЕКТНАЯ БИБЛИОТЕКА. Часто ОС и/или система программирования имеют свою библиотеку элементов управления. В таком случае получается что-то типа.
    program HomeMadeForm;
    
    uses
      Vcl.Forms, Vcl.StdCtrls;
    
    {$R *.res}
    
    var
      fm : TForm;
      bt : TButton;
    
    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
    
      fm := TForm.Create(nil);
      fm.Width := 400;
      fm.Height := 200;
      fm.Caption := 'Test';
    
      bt := TButton.Create(fm);
      bt.Parent := fm;
      bt.Caption := 'Go!';
      bt.Left := 150;
      bt.Top := 80;
    
      fm.ShowModal;
      fm.Free;
    end.


    УРОВЕНЬ 3. ВИЗУАЛЬНОЕ РИСОВАНИЕ. Наконец, существуют механизмы рисования форм: Qt Widgets, Qt Quick, VCL, WxWidgets, Windows Forms… В таком случае программист просто рисует форму, а про механизмы конструирования-позиционирования не думает. Создал форму, на неё поставил кнопку, к кнопке приделал событие OnClick — и вот уже при нажатии кнопки вызывается событие.
    5b006b57a3c2f727637474.png

    Существуют и HTML-подобные механизмы. Например, элементы HTML есть в Apache Cordova, обеих разновидностях Qt. Используют их, потому как удобно, но механизмы разбора HTML довольно сложны и потому не везде есть.
    Ответ написан
    Комментировать
  • Почему точность вычислений в float нарушается для чисел определённой степени двойки?

    @Mercury13
    Программист на «си с крестами» и не только
    Связано, вероятно, с особенностями перевода дробных чисел в текст. Я попробовал повторить на Си++, ничего интересного не вышло. Зато методы перевода дробного в текст G++ и GRISU дают несколько разные результаты.
    Ответ написан
    Комментировать
  • Почему большинство файлов содержат шестнадцатеричный код?

    @Mercury13
    Программист на «си с крестами» и не только
    Так исторически сложилось, что единица памяти и ввода-вывода — байт, который равняется восьми битам. Байт, как известно, кодирует цифры 0…255 — хватает, чтобы закодировать английский алфавит, национальный алфавит (например, русский или грузинский) и ещё кучу символов.

    Вот программист смотрит на простыню байтов. Что нужно ему делать?
    1. Преобразовывать единичный байт в число.
    2. Преобразовывать много байтов в число, как в уме, так и механизированно.
    3. Выделять из байта отдельные биты.
    4. Преобразовывать единичный байт в символ.
    5. Преобразовывать несколько байтов в многобайтовый символ.

    Задача 5 решается, если есть 4 и 2 (к тому же, когда появлялись байтовые дампы, она вообще не стояла, Юникод появился ≈1990).
    Задача 4 решается, если все байты вывести в виде символов, с одним маленьким изменением: каждому символу, даже управляющему, придумать графический вид. Символ №0 не имеет традиционного вида, но часто ему придумывают что-то типа точки, №1 и 2 — смайлики, №3…6 — карточные масти…
    Задача 3 слишком редка, чтобы оптимизировать дамп именно под неё, к тому же двоичный код громоздок. Однако вместо двоичного кода можно применить восьмеричный или шестнадцатеричный, программист быстро научится выделять из восьмеричных/шестнадцатеричных цифр биты.
    Для задачи 1 лучше всего писать просто цифры 0…255.
    Для задачи 2 катит любая система счисления.

    Таким образом, у нас остались два варианта.
    • Каждый байт писать в десятичной системе 000…255.
    • Каждый байт писать в шестнадцатеричной системе 00…FF (как раз получается две цифры).
    По опыту, задача 1 для чисел больше 15 крайне редка. Зато для задач 2 и 3 шестнадцатеричный вид намного удобнее десятичного.
    Вот так и сложился традиционный вид дампа файлов. Слева — шестнадцатеричный вид, справа — символы однобайтовой кодировки.
    Ответ написан
    Комментировать
  • Какой вариант применения исключений лучше?

    @Mercury13
    Программист на «си с крестами» и не только
    Декларируемые исключения Java — это плохо. Однако эти декларируемые исключения позволяют осознать, что есть три типа аварий.

    1. Среда исполнения чувствует себя плохо, исполнение программы под угрозой (сработала самопроверка в какой-то части программы, не подконтрольной программисту). Например, срабатывание какого-то встроенного детектора, определяющего запись в чужую память. Выпадают где угодно. Их на практике не приходится ни выбрасывать, ни ловить.

    2. Нарушена логика программы (сработала самопроверка, зависящая от программиста). Неверный аргумент, выход за границу массива. Выпадают где угодно. Их часто выбрасывают и крайне редко ловят.

    3. Нестабильная часть программного окружения чувствует себя плохо. Файл не найден, нет связи. Выпадают в определённых точках. Часто выбрасывают и часто ловят. В Java только их требуется декларировать.

    Таким образом, ваш холивар относится к вопросу: выбрасывать ли исключение, если случилась авария 3-го типа? Я лично замечал подобные вопросы только в одном языке — Си++. Думаю, это связано с двумя вещами. 1) Большие издержки, связанными с определёнными методиками обработки исключений. 2) Довольно невнятное поведение Си++ при выпадении исключения из конструктора.

    Если же отойти от недостатка конкретного языка — даже по поводу обычного HTTP 404 есть «путь Indy» и «путь cURL» — выбросить исключение и сообщить о ненайденном документе другими методами. За первое и за второе можно найти кучу аргументов.
    Ответ написан
    Комментировать
  • Задача "Бинарные числа"?

    @Mercury13
    Программист на «си с крестами» и не только
    (n > 0) and (n and (n - 1) = 0)
    Раз у вас паскаль, первый AND логический, второй битовый.
    Второе условие — стандартный программистский приём, срезающий последний единичный бит.

    UPD2. Да, ты меня слегка перехитрил с алгоритмом, но, нем не менее…
    1. Если число <= 0 — без единой итерации пишет YES, что неверно.
    2. Если у вас условие сложное — лучше разделить программу на проверку условия (подпрограмму или переменную типа boolean) и реакцию на это условие.
    3. Стандартная ошибка начинающих: допустим, не сработало условие N mod 2 = 1. Зачем писать N mod 2 = 0, если есть else?
    Ответ написан
  • Как выделяется память в классах?

    @Mercury13
    Программист на «си с крестами» и не только
    Examp ex = new Examp ();
    Неверный код, надо Examp* ex = new Examp;

    В случае статического определения (Examp ex2;) — в той памяти, где обычно располагаются объекты. То есть:
    • Если это поле объекта — то в теле объекта, которое может быть где угодно (куча, сегмент данных, стек).
    • Если static/глобальный — то в сегменте данных.
    • Если локальный — в стеке. Конкретно тут локальная переменная, и она будет в стеке.

    В случае динамического определения (Examp* ex = new Examp;) — в «куче».
    В этом примере, кроме операции new, которая заводит объект в куче, видим ещё и указатель, который располагается «там, где обычно» — в теле объекта, сегменте данных или стеке.
    Ответ написан
    Комментировать
  • Существует ли одноричная система счисления?

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

    Существуют и другие, как-то унарная, фибоначчиева, римские цифры…
    Ответ написан
    Комментировать
  • Чем отличается анализ бинарного кода от статического и какие у него преимущества?

    @Mercury13
    Программист на «си с крестами» и не только
    Это разные вещи.

    Статический анализ кода — это проверка исходного текста на распространённые ошибки без попыток запуска. Чем ближе код к стандартным возможностям языка и библиотеки, без лишних обёрток, тем статический анализ кода успешнее. На Хабре по-чёрному пиарится один из инструментов САК — PVS-Studio. Язык программирования D рассчитывает на специальные аннотации, позволяющие проанализировать код на подобные стандартные ошибки ещё при компиляции (но настоящего статического анализа это не заменяет).

    Анализ бинарного кода — это выяснение с использованием дизассемблеров, отладчиков и виртуальных машин, что делает скомпилированная программа. Как частность — есть ли в ней подозрение на зловреда. Этим занимаются как хакеры (вручную), так и антивирусы (автоматически). Антивирусы, анализирующие бинарный код, позволяют сказать: «по базе чисто, но эта программа подозрительная».
    Ответ написан
    3 комментария
  • Какие есть книги про связь высшей математики и программирования?

    @Mercury13
    Программист на «си с крестами» и не только
    Дональд Кнут. «Конкретная математика»
    Теория графов, алгебра логики — любая книга
    Ответ написан
  • Не понимаю почему не работает for правильно?

    @Mercury13
    Программист на «си с крестами» и не только
    arr — исходные строки.
    arr2 — сортированные.
    Исходные строки, скорее всего, не будут совпадать ни с одной из сортированных — потому arr2[i]==sarr[j] во втором фрагменте, скорее всего, не выполнится.
    Я бы поступил таким образом. Сделал бы индексированный список сортированных строк и порядковый массив исходных. Поиск сортированной строки в индексированном списке. Если не обнаружена — сортированную в индексированный, исходную в порядковый.

    Что в JS будет индексированным списком — просто не знаю. Вероятно, можно обойтись массивом, присвоив sortedList[arr2[i]] = 1. Вот только как найти то, есть ли?

    UPD. Можно также воспользоваться хранилищем «ключ-значение»: ключом будет сортированная строка, значением — исходная. iamevg_ так и поступил. Единственная засада (которая хороша или плоха, в зависимости от задачи) — портит порядок строк.
    Ответ написан
    1 комментарий
  • Как сделать и вывести срез строки(String) C/C++?

    @Mercury13
    Программист на «си с крестами» и не только
    1.
    std::cout << text.substr(начало, длина) << std::endl;

    Поскольку перед нами учебный текст, дальше не буду подсказывать. Методом тыка выясни, что будет началом и что длиной.

    2. Ничего, что, если строка не оканчивается точкой, последнее «недопредложение» выведено не будет? Может быть, так и верно, но если задача — разделить текст по tab’ам или запятым, надо после цикла выкинуть то, что осталось.
    Ответ написан
    Комментировать
  • Где располагаются переменные в данном случае (стэк, куча)?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы совершенно правы. Это массив из одного элемента, и при таком расположении он будет в стеке. Со всеми его полями: alloc, size и mp_d. При выходе из функции есть шансы, что он будет затёрт, и так действовать нельзя.

    Кто затрёт? Да кто угодно. Хоть драйвер, пожелавший воспользоваться твоим стеком. Хоть последующий вызов какой-нибудь функции.

    С другой стороны, на то и помечена структура __mpz_struct двумя подчерками, чтобы её не использовали.
    __mpz_struct* foo()
    {
        mpz_t var;
        return (__mpz_struct *)var;
    // C:\TestApps\RetLocal\main.cpp|15|warning: address of local variable 'var' returned [-Wreturn-local-addr]|
    }


    А так работает: всё в куче. Только не забывайте очищать через delete[].
    __mpz_struct* bar()
    {
        __mpz_struct* var = new mpz_t;
        return var;
    }
    Ответ написан
    2 комментария
  • При компиляции VC++, Opencv 3.2 проекта не работает exe на другой системе, требует opencv_world330.dll что делать?

    @Mercury13
    Программист на «си с крестами» и не только
    Краш, вероятно, связан с другой вещью. Компилятор-то новенький, и на ту машину не успели подвезти его среду исполнения. Выясни, какие файлы нужны: MSVCR140.DLL, MSVCP140.DLL или MFC140U.DLL.
    (при условии, что сам OpenCV также скомпилирован C++2017; если нет — также нужны и файлы другого компилятора.)

    Если так и не удастся отыскать — найди программу Dependency Walker и точно найди, чего ей не хватает.
    Ответ написан
    6 комментариев