Задать вопрос
  • Почему не компилируется код на С (gcc)?

    @Mercury13
    Программист на «си с крестами» и не только
    Я бы пенял на ложную тревогу антивируса.

    Кроме того, программа неверна. В ней card_name используется раньше, чем заполняется чем-то стóящим.
    Ответ написан
  • Почему при попытке запустить оконное приложение через cmd с помощью java ничего не происходит?

    @Mercury13
    Программист на «си с крестами» и не только
    Извините, где точка входа? Где main(String[])? Где запуск оконного цикла AWT?

    Ну и оконные программы надо пускать программой java, если хотите видеть консоль, и javaw — если не хотите.
    Ответ написан
    3 комментария
  • Как писать тест-кейсы к функциям?

    @Mercury13
    Программист на «си с крестами» и не только
    Без того, что она делает, мы никак не можем написать нужные сценарии.

    Например, тестируем функцию abs(x) — чтобы проверить её работоспособность, достаточно подать на вход что-то положительное, что-то отрицательное и ноль.
    Например, abs(2) = 2, abs(−3) = 3, abs(0) = 0.

    Для вашего примера надо проверить B = true и B = false — а остальное шут его знает.
    Ответ написан
    1 комментарий
  • Особености функций malloc/calloc/new?

    @Mercury13
    Программист на «си с крестами» и не только
    UPD2. Что значит «очищают данные»?

    а) Очищают данные = освобождают память. Сделать функцию, которая выделяет память в локальную переменную (и эта переменная, была бы уничтожена мусорщиком Java, вместе с выделенным массивом).

    1. Выяснить, сколько памяти свободно.
    2. Вызвать функцию.
    3. Выяснить ещё раз, сколько памяти свободно.
    4. Подождать пару секунд («мусорщик» точно сработал бы).
    5. Выяснить третий раз, сколько памяти свободно.
    Поскольку в C++ мусорщика нет, должно быть 1 > 3 = 5.

    Узнать кол-во памяти — дело непортабельное, на Windows и Linux свои функции, см. stackoverflow.com/questions/2513505/how-to-get-ava...

    UPD1. На Windows лучше использовать GetProcessMemoryInfo. В таком случае надо смотреть, сколько памяти программа съедает, и тогда 1 < 3 = 5. Поскольку внутренний менеджер памяти на своём уровне «закрысивает» немного памяти, лучше выделять много памяти, порядка мегабайта.

    б) Очищают данные = забивают их нулями (наверно, всё-таки это). Выделить буфер подлиннее (или кучу буферов по одному int) и убедиться, что там не нули. Желательно компилировать программу на разных настройках — например, в Debug программа может забивать данные нулями или чем-то вроде DEADBEEF, а в Release — выдавать мусор.
    Ответ написан
  • Для чего нужен вот такой переходник?

    @Mercury13
    Программист на «си с крестами» и не только
    Вероятно, чтобы из кабеля USB-A → Micro-USB и этого переходника сделать кабель OTG. Так теоретически должно работать со всеми устройствами, которые не являются USB-хостами (флэшками, фотоаппаратами…).
    Пишут также, что используется инженерами в испытании и прототипировании схем.
    Ответ написан
    1 комментарий
  • Приведение signed int к unsigned int?

    @Mercury13
    Программист на «си с крестами» и не только
    Видимо, связано с авариями переполнения. Представьте себе такую штуку: −128 + 255 = 127. Если в процессоре будут аппаратные аварии переполнения, это самое переполнение и произойдёт: −128 − 1 = ???. Беззнаковый тип аварий переполнения не вызывает.

    UPD. Так и есть. В Си знаковое переполнение — UB: такое переполнение может разделить с остатком, вызвать аварию или упереться в границы. В GCC есть ключи -ftrapv и -fwrapv — что делать при таком пререполнении.
    Беззнаковое — обязательно деление с остатком.

    UPD2. Стандарты Си и LIA несколько противоречат друг другу, и можно предположить, что знаковое переполнение зависит от реализации. Это не UB — можно сделать хороший код, полагающийся на такое поведение. Но если x86 так поступает, то не обязательно, что так поступают все.
    Ответ написан
  • Как востановить бинарное дерево?

    @Mercury13
    Программист на «си с крестами» и не только
    Если одним префиксным/инфиксным/постфиксным — то, разумеется, нет. А если двумя — дело уже интереснее (при условии, разумеется, что все узлы разные).
    Ну, например, как восстановить дерево, которое было пройдено сначала префиксно, потом постфиксно (самый сложный и интересный случай). Признаюсь сразу: полное восстановление невозможно, ведь ситуации «без левых сыновей» и «без правых сыновей» различить нельзя.

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

    Пример: у нас дерево.
         a
      b    c
    d  e   f

    Префиксный обход abdecf, постфиксный debfca. Корень a, левый сын b, он в постфиксном обходе на третьей позиции. Рекурсивно запускаем алгоритм на парах bde/deb и cf/fc.
    Ответ написан
    Комментировать
  • Какие шрифты можно ставить на фоллбеки?

    @Mercury13
    Программист на «си с крестами» и не только
    Таких универсальных шрифтов нет. В Windows свой комплект, в Mac свой, в Linux свой. А в Ведроиде — у Хрома и Лисички разные шрифты.

    Любая цепочка должна кончаться шрифтами serif, sans-serif или monospace — это стандартные шрифты браузера. Браузер их применит, если не найдёт других. Ну и, разумеется, нежелательны serif/monospace на малых кеглях (есть риск, что будут плохо смотреться).

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

    Идеал — сделать страницу так, чтобы на «чужом» шрифте она нормально читалась.
    Ответ написан
    5 комментариев
  • Что означает char **s на языке Си?

    @Mercury13
    Программист на «си с крестами» и не только
    Указатель на указатель.

    Используется…
    1. Для многомерных массивов (в Си нечасто — ведь есть настоящие многомерные массивы; обычно в структурах посложнее, чем тупой массив M×N). Вот у меня есть самодельный (неполный) аналог std::deque (динамический массив, состоящий из кусочков и никогда ничего не перемещающий). Там внутри std::vector<T*>, который служит массивом массивов. А у вектора внутри — T**.
    2. Для массивов (1-е измерение) строк (2-е измерение).
    3. Для передачи указателя по указателю (см. описание функции strtod).
    4. (Крайне редко) И просто как указатель на указатель

    Как инициализировать?
    1.
    char row0[] = { 'A', 'B' };
    char row1[] = { 'C', 'D' };
    char* arr1[] = { row0, row1 };
    char** data1 = arr;
    
    2. 
    char* arr2[] = { "AB", "CD" };
    char** data2 = arr2;
    
    3. 
    char* errptr;
    int r = strtod("10", &errptr);
    return (*errptr != '\0') ? ERROR : r;
    
    4.
    char* data = "Data";
    char** pData = &data;
    Ответ написан
    2 комментария
  • Как в C++ распределяется память?

    @Mercury13
    Программист на «си с крестами» и не только
    Это называется фрагментация памяти. Некоторые «мусорщики» (как в Java или C#) способны сдвинуть объекты и получить большой непрерывный отрезок.
    Менеджер памяти C++ дефрагментировать память не способен и выдаст нехватку памяти.
    В любом случае, массив — что в Java, что в C++ — будет занимать непрерывный отрезок памяти.

    Чтобы совмещать мусорные языки с системными интерфейсами, есть способы пометить структуру как неперемещаемую. Но это уже на стыке виртуальной машины Java/C# и системного кода, который пишется на Си(++).
    Ответ написан
    9 комментариев
  • Что написано в строке указатель или ссылка?

    @Mercury13
    Программист на «си с крестами» и не только
    Одно из двух.

    а) Либо так называемый reinterpret_cast или type pun — берётся кусок памяти serv_addr неизвестного типа и рассматривается как совсем другой тип, sockaddr_in. Корректность такого «взять кусок памяти и рассмотреть как другой тип» остаётся за программистом, возможны тонкие ошибки кроссплатформенности.

    б) (в данном примере, скорее всего, нет, но тоже бывает) Либо так называемый const_cast — переменную, отмеченную как const, мы рассматриваем как неконстантную того же типа. Опять-таки, корректность такого преобразования остаётся за программистом: если переменная окажется в неизменяемой памяти, а мы её решим изменить, будет нехорошо.

    То и другое — либо сильно обобщённый код оперирует указателями «на что угодно», либо какая-то разглючка, либо плохая архитектура, либо последствия того, что где-то приходится опускаться на самый низкий уровень (обработка сообщений Windows, плагинная система).

    Подобное преобразование типа выполнено в стиле Си (взять указатель на переменную и преобразовать в другой тип-указатель).

    Кстати, в коде ещё одна ошибка кроссплатфроменности — константа -1 только для Linux. Портабельно — макрос SOCKET_ERROR.

    UPD. Это именно что reinterpret в сильно обобщённом (и сильно системном) коде. Функция connect принимает указатель на кусок памяти, который состоит из двухбайтового названия протокола и сетевого адреса произвольной длины (тип sockaddr). Тип sockaddr_in — это как будет эта выглядеть эта память для адресов IPv4 (протокол AF_INET). Одна и та же функция connect может подключаться по IPv4, IPv6, Apple Talk, Bluetooth и куче других протоколов, ныне известных разве что историкам. Другой протокол, другое AF_, другие sockaddr. Так что берём версию для IPv4 (sockaddr_in), заполняем её и передаём в connect, преобразовав в «более общий» тип sockaddr. Опознав, что имеем дело с IPv4, функция connect снова проинтерпретирует эту память как sockaddr_in.
    Ответ написан
    3 комментария
  • Почему не сохраняет и не выводит последнее введенное число?

    @Mercury13
    Программист на «си с крестами» и не только
    Код while (cin >> val) подразумевает, что мы ждём конца консоли.
    Если консоль перенаправлена из файла — ну, с этим всё понятно.
    А если нужно сделать конец в настоящей консоли, нажмите Ctrl+Z.

    Код высчитывает количество введённых подряд одинаковых чисел; если мы вводим другое или заканчиваем поток — он выводит, сколько их было.
    Ответ написан
    Комментировать
  • Как вставить значение переменной после % в printf()?

    @Mercury13
    Программист на «си с крестами» и не только
    printf("%*d", nDigits, value);

    А-а-а, уже было в комментариях!..
    Ответ написан
    Комментировать
  • Qmake not using precompiled headers?

    @Mercury13
    Программист на «си с крестами» и не только
    По документации Qt, нельзя.

    Зато можно исключить Си++ из предкомпиляции простым методом.

    // Add C includes here
    
    #if defined __cplusplus
    // Add C++ includes here
    #include <stdlib>
    #include <iostream>
    #include <vector>
    #include <QApplication> // Qt includes
    #include <QPushButton>
    #include <QLabel>
    #include "thirdparty/include/libmain.h"
    #include "my_stable_class.h"
    ...
    #endif


    doc.qt.io/qt-5/qmake-precompiledheaders.html

    Самому так пригодилось (правда, на MinGW, а не на MSVC).
    Ответ написан
    1 комментарий
  • Консольное программа delphi?

    @Mercury13
    Программист на «си с крестами» и не только
    Для этого служат, извините, циклы. Самый простой способ — бесконечный цикл с break внутри
    repeat
      ваш код
      if [что-то там] then break;
      ваш код
    until false;
    Ответ написан
    Комментировать
  • Free Pascal ANSI или Unicode?

    @Mercury13
    Программист на «си с крестами» и не только
    Плавали, знаем. Долго видел на BCB6, а потом преобразовывал ANSI → UTF-16.
    1. Раз у нас UTF-16, придётся усложнить работу с путями и прочим (например, сокращение строк). Раньше символ был один char, стало — один-два WideChar.
    2. Где у нас низкоуровневые строки — придётся корректировать объёмы памяти. На всех языках, кроме Си и Си++, такого обычно мало: на Си нет своих строк, а в Си++ автодеструкторы.
    3. Где у нас сериализация — придётся перекодировать. В ANSI адресуемая единица (байт) совпадает с символом текста, в Юникоде уже нет.
    Ответ написан
    3 комментария
  • Как реализовать наследование статического поля/метода, если это возможно?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое. Объясни, для себя и для меня, что собой представляет объект Command?

    Моё видение — разделить объекты Command (введённая пользователем и разобранная строка) и Program (программа, реализующая команду). Также я нарисовал — хочешь, используй, хочешь, нет — объект Console (консоль ввода-вывода) и System (окружение программы вроде текущего каталога, переменных окружения, файловой системы).

    Я тут работаю со значениями и указателями, в терминах C++03, но, возможно, вас заинтересуют умные указатели C++11.

    std::string commandLine = console.getSomeCommandLine();
    Command command;
    std::string error;
    if (!command.parse(commandLine, error)) {
      console.err().writeln(error);
      return;
    }
    Program* program = system.findProgram(command.programName);
    if (!program) {
      console.err().writeln("Bad command or file name");
      return;
    }
    Console redirectedConsole = console.redirectStreams(command);
    program->exec(redirectedConsole, system, command.getArguments());


    Второе. Возвращай ссылки, это быстрее.
    const std::vector<std::string>& getArguments() const;
    const std::vector<std::string>& getOptions() const;
    Ответ написан
  • Почему не работает libcurl?

    @Mercury13
    Программист на «си с крестами» и не только
    Как ни странно, нужна версия libcurl с поддержкой HTTPS.
    Большинству таких версий в нагрузку нужны два файла OpenSSL — libeay32.dll, ssleay32.dll.
    Ответ написан
    Комментировать
  • Ошибка C++ Builder XE Unable to open file 'ODBCPROVIDER150.OBJ'. Кто-нибудь поможет?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Этого файла не будет, он скрыт в файле с расширением lib. Найдём его. Если нет — значит, библиотека не была скомпилирована под Builder.
    2. Tools → Options → C++ Options → Paths and Directories → Library Path.
    Ответ написан
    Комментировать