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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Цикл делается через условное ветвление.

    Сначала напишите программу на тупо с, потом замените циклы на условия и goto. Потом каждый if распишите через if/goto:
    if (a) {
    B
    } else {
    C
    }
    
    if (a) goto labelB;
    C
    goto end;
    labelB: B
    end:


    Потом уже это все можно в машинные коды строчка за строчкой перевести.
    Ответ написан
    Комментировать
  • Как исправить ошибку error: linking with `link.exe` failed: exit code: 1120?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Надо линкеру указать dll-ку в которой эта функция определена. В документации не указано, в какой именно библиотеке оно лежит, но можно пропробовать Gdi32.dll или Ddraw.dll. Надо где-то в настройках проекта на вкладке про линкер указать эти dll.
    Ответ написан
    Комментировать
  • Реализация кэша для мульти поточного приложения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам нужна lock-free хеш таблица (гуглите Lock free unordered_map). В стандартной библиотеке таких структур нет. Или просто используйте свои мьютексы при каждом обращении к структуре.
    Ответ написан
    2 комментария
  • Лучше ли использовать enum для цвета нежели struct?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Без разницы. Используйте то, что логичнее смотрится в коде. Разницу в производительности, во-первых, вы получите лишь в очень специфичных случаях (при передаче в функцию enum скорее всего окажется в регистре, а вот структура полезет на стек. В итоге enum окажется быстрее), во-вторых, только если читать вы будете миллионы стркутур. И то, вам должно не повезсти с кешем процессора и префетчером.

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    потому что int cusBal[10]. У вас массив целых чисел, вы его инициализируете константой 35.50. При этом происходит приведение к типу int и часть после точки с запятой теряется.

    Вторая проблема, вы эту int переменную выводите через "%.2f". Так что вам еще очень повезло, что оно вывело вообще что-то похожее на нужное число.

    Об обеих ошибках компилятор вам выдавал предупреждение (если он правильно настроен). Их все надо внимательно прочитать и убедиться, что они все безобидные, а лучше, чтобы их вообще не было.
    Ответ написан
    Комментировать
  • Почему clang выдает такой ассемблерный код?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Что у вас за опции сборки (Это же с++, не смотря на теги же?) Оптимизация-то включена? GCC 14 даже без оптимизаций выдает именно второй код в обоих случаях.

    Похоже, это недочет в компиляторе. Понятно, что тут можно использовать второй вариант без проблем. Но компилятор не смог до этого догадаться по каким-то причинам. Ясно, что для списка инициализации и просто присвоения используются разные куски компилятора. И вот в ветке для списка инициализации эту оптимизацию не прикрутили по каким-то причинам.

    Если вы вставите более полный пример кода на godbolt.org, воспроизведете проблему, и поделитесь ссылкой, то, возможно, я смогу вам более детально ответить.

    Edit:
    Разобрались, что это clang c. Такой код он выдает с -O0. Если же оптимизации включены, то он его оптимизирует. Это не недочет или ошибка. Просто, вот такой у него стандартный код. Он вправе засовывать константы в секцию данных, а не вставлять прям в ассемблерный код.
    Ответ написан
  • Что отвечает за предотвращение нежелательной записи в text секцию?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Память помечена, как read-only.
    Ответ написан
    Комментировать
  • Как вывести минимальный элемент из динамической библиотеки?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    jidomasson, Вот и проблема (код из комментариев к вопросу):

    second_element = ctypes.c_int(A[1])
    begin = ctypes.pointer(second_element)
    
    last_element = ctypes.c_int(A[size - 1])
    end = ctypes.pointer(last_element)


    Тут вы, похоже, созадете новые объекты типа c_int и присваиваете им значения второго и последнего элементов массива. А потом указатели на них передаете в функцию. Функция ожидает указатели на элементы массива, а получает указатели на какие-то 2 никак не связанные между собой переменные. Поэтому она блуждает по левой памяти и просиходит что угодно. Хоть падение, хоть зависание.

    Вам надо брать указатели от A[0] и A[size-1] нарпямую.
    Ответ написан
  • Как избавить от заданных размеров количества строк и столбцов при считывании из файла?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте построчно до конца файла. У вас уже эта проверка есть там, где вы fscanf делаете - вы же проверяете, что оно вернуло? А столбцов у вас всегда 3.

    Если проблема с тем, что у вас массив, куда вы читаете, ограниченного размера, то можно, например, завести его достаточно большой длины, с запасом. Как у вас там 101 символ выделен под кажую строку. А еще лучше, если у вас C++, использовать std::vector - ему можно длину динамически менять. Если же это C - то пишите свою собственную логику увеличения массива, через malloc и realloc по мере заполнения.
    Ответ написан
    Комментировать
  • Почему постоянно выводится расстояние 0(Алгоритм Дейкстры для городов)?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Вы выводите d[begin_index], это расстояние до начальной вершины. Естественно там 0 будет. А выводить надо расстояние до конечной. Надо end использовать (и выводить после того, как вы end нашли).
    Ответ написан
    Комментировать
  • Как из массива байтов HEX сделать сделать DEC?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно без перевода в десятичную систему считать. Столбиком, как в начальной школе. Это будет работать даже если ваши числа длиннее 4 байт.
    byte summ[N];  // N >= skoll_len+sprice_len.
    for (int i = 0; i < skoll_len; ++i ) {
      word carry = 0;
      for (int j = 0; j < sprice_len; ++j) {
        carry += summ[i+j] + (word)skoll[i] * sPrice[j];
        summ[i+j] = carry % 256;
        carry /= 256;
      }
      if (carry > 0)
        summ[x_len + y_len - 1] += carry;
    }


    Тут три неочевидных момента. При прибавлении одной строки из умножения столбиком все переносы считаются сразу одним проходом. Во-вторых, там может быть какой-то лишний перенос в конце, но только на одну дополнительную ячейку, потому что x < 256^x_len, y <256^x_len, а значит x*y < 256^(x_len+y_len), значит не будет никакой записи дальше ячейки x_len+y_len-1. И последнее, carry по пути нигде ни разу не переполнится, ибо максимальная сумма там может быть 255*255+255+255 < 256*256.

    P.s. Но если у вас числа уж очень длинные, то гуглите быстрое преобразование фурье + длинное умножение.
    Ответ написан
    3 комментария
  • Есть ли задача на распределенные вычисления, которую легко проверить?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Берете любую NP-complete задачу: https://en.m.wikipedia.org/wiki/List_of_NP-complet...

    Все их сложно решить и легко проверить ответ.
    Ответ написан
    Комментировать
  • Как программно работать с USB веб-камерой в Linux использую C/С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нужны библиотеки. Гуглите v4l2, pipewire.
    Напрямую с драйверами или тем более свой драйвер с USB протоколами вы писать замучаетесь.
    Ответ написан
    2 комментария
  • Почему make file компилятора выдает ошибку, что функция переопределяется?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Похоже на какие-нибудь циклические инклуды.
    У вас в data_process.h случайно не включается data_process.c?
    Так делать не надо.
    Ответ написан
    6 комментариев
  • Скомпилированный в GCC exe файл вылетает досрочно?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Звучит в точности как симптомы Undefined Behavior. На самом деле программа вылетает из-за, например, доступа к неправильным указателям. Но во время отладки звезды выстраиваются так, что это некорректное действие не приводит к падению программы.

    Добавляйте больше отладочного вывода во всех функциях и между всеми важными кусками кода, например на каждой итерации цикла. Выводите разные строки везде, а в циклах еще и переменные цикла вставляйте.
    Выводите в stderr.

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

    Возможно, там где-то выход за границы массива, Попробуйте еще, например, увеличить все выделенные строчки и массивы в коде раз в 10. Если после этого программа отработает, ищите, где у вас ошибка в логике - почему массивов не хватает.
    Ответ написан
    32 комментария
  • Взгляд опытных программмистов, что улучшить и исправить?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    1. #define SPACE ' ' - смысла не несет такая замена. Или какое-то более осмысленное имя, вроде EMPTY_FIELD, или просто в коде используйте ' '. Хотя лучше хорошее имя.

    2. check_field - ужас. Во-первых, проверки на крестики и на нолики идентичны - только сравниваете вы или с 'X' или с 'O'. Ну напишите функцию, которая принимает char и ищет тройку из этих символов. Далее, используйте циклы. 3 строки можно проверить одним и тем же кодом, только индексы сдвигаются на 3 - вот и запустите цикл на 3 итерации. Так же со столбцами. В итоге вместо 8 условий будет только 4.
    Вообще, можно до одного условия в трех вложенных циклах ужать:
    const int dx[4] = {0, 1, 1, 1};
    const int dy[4] = {1, 0, 1, -1};
    for (dir = 0; dir < 4; ++dir) {
      for (int start = 0; start < 9; ++start) {
        int step;
        int x = start % 3;
        int y = start / 3;
        for (step = 0; step < 3; ++step) {
          if (x < 0 || x > 2 || y < 0 || y > 3 || field[x+3*y] != player) break;
          x += dx[dir];
          y += dy[dir];
        }
        if (step == 3) {
          return 1;
        }
      }
    }
    return 0;


    3. print_field тоже делается циклами. Хотя бы по трем строкам.

    4. основной игровой цикл можно делать while (1), ибо по любому из значений check происходит break;
    Ответ написан
    Комментировать
  • VS Code творит лютую дичь при компиляции и отладке?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Это называется "оптимизируюший компилятор". Он может выкинуть какие-то строчки, часть кода переписать и перетасовать. Соптимизировать по своему усмотрению. Поэтому для отладки используют специальные debug сборки. Установите компилятору флаг -O0, чтобы отлкючить оптимизацию.

    В закоменченную фунцию он может заходить, если вы не перекомпилировали перед запуском.
    Ответ написан
    7 комментариев
  • Почему возникает ошибка Fatal error. System.Runtime.InteropServices.SEHException?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что библиотека бросила исключение. В ней какая-то ошибка. Это не проблема сборки или компиляции - это проблема в логике. Что-то вы не то библиотеке передаете. И там, допустим, деление на ноль. Или обращение по нулевому указателю.

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

    Или добавляйте в программу очень многословный отладочный вывод на каждый чих, молитесь, чтобы проблема у пользователя воспроизвелась с логами, и медитируйте на лог и исходный код.

    Судя по сигнатурам функции, возможно вы пустой массив туда передаете вместо чего то осмысленного.
    Ответ написан
    7 комментариев
  • Как сделать ввод через стандартный поток (stdin) и через файл?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Есть такая функция freopen. Можно всегда читать через scanf, read из stdin, но если указано имя файла, то переоткрыть stdin на файл:
    freopen("input.txt", "rb", stdin);
    Ответ написан
  • Как убрать дублирование чисел в бинарном файле на си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    С чего вы взяли, что туда записывается два числа 7?
    Туда записывается одно число размером в 4 байта, которое, если его интерпретировать как строку, выглядит как "7 7 ".

    Вы числа читаете и пишите в бинарном формате. Соответственно, файл input.bin у вас должен в hex редакторе выглядеть "0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x07...", а не то, что у вас.
    Ответ написан