Задать вопрос
Ответы пользователя по тегу C
  • Почему программа на языке C не выполняется?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Оно не компилируется. Нажмите показать ошибки, там будут детали.

    Просто догадки:
    У вас опечатка - функция mian вместо main.
    Потом, в конце функции должно стоять return 0;
    Ответ написан
    4 комментария
  • Как умно распараллелить вложенный цикл OpenMP?

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

    Внутри можно циклы по i объединить все в один.

    Ну и параллельте цикл по i через pragma omp for.
    Ответ написан
  • Как вызвать появление меню в splitbutton?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если стоит visual studio, там есть утилита spy++. Она мониторит виндовые сообщения, приходящие выбранному окну.

    Запустите ваше приложение, натравите на него spy++, ткните в кнопку, чтобы появилось меню, и смотрите, какие сообщения и с какими параметрами приходят. Потом повторите их же в коде через postMessage.
    Ответ написан
    Комментировать
  • Как сделать рекурсивную функцию, которая находит сумму нечетных элементов динамического массива на C?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Ошибка в том, что вы проверяете на четность сами элементы, а не их индексы. Вы суммируете нечетные числа. Если надо каждое второе число брать, то проверяйте на четность n.
    Ответ написан
  • Как можно передать структуру в printf, а к переменным её обращаться из шаблона?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Во встроенный printf вы это не добавите никак. Придется писать собственную обертку и там парсить строку формата.
    Так, чтобы это работало со всеми структурами, у которых есть член int a - нужны шаблоны, да. Гуглите variadic template, но это мрак и ужас. В любом случае это будет весьма громоздкий и непонятный код.

    Но раз уж у вас C++, то вы вместо printf используйте cout. Переопределите operator<< для ostream и вашей структуры и выводите через cout << *s1.

    Да, тут не получится в каждом конкретном месте вызова менять формат вывода, он будет одинаков везде - но так ли вам это нужно, чтобы городить костыли с printf?
    Ответ написан
    Комментировать
  • Пишет что повредил кучу? Чего?

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

    Чтобы исправить, надо аккуратно посмотреть за каждым указателем, где просиходит malloc, где указатель используется, какого размера там память и нет ли выхода за границы массива.
    Ответ написан
    Комментировать
  • Как можно отрефакторить эти циклы?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Я так понял, вы там перебираете 8 соседей клетки на замкнутом поле (после последней строки идет первая, перед певрой идет последняя и так же для столбцов). Вам поможет опреация взятия остатка от деления (она же деление по модулю).

    Можно так:
    for (int dx = -1; dx <= 1; ++dx) {
      for (int dy = -1; dy <= 1; ++dy) {
        if (dx == 0 && dy == 0) continue;
        int nx = (i + dx + height) % height;
        int ny = (j + dy + SIZE) % SIZE;
        neighbours += proc_states[iter][nx * SIZE + ny];
      }  
    }


    Или можно завести
    const int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
    const int dy[8] = { 1, 1, 0, -1, -1, -1, 0, 1};
    ...
    for (int k = 0; k < 8; ++k) {
      int nx = i + dx[k];
      int ny = j + dy[k];
      ...
    }


    Можно не заводить временные переменные и ужать код до двух строк.

    В конструкции (i + dx + SIZE) % SIZE есть лишний +SIZE, ибо -1 % SIZE == -1 и чтобы для 0 предыдущее значение было SIZE-1 надо прибавить лишний SIZE под модулем.
    Ответ написан
    Комментировать
  • Как реализовать с помошью оператора ,побитовую операцию NAND?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    NAND это Не И. Операция Не, примененная к операции И. Вот берете и применяете операции И а потом Не и получаете NAND. Обе нужные операции вы вопросе уже перечислили.
    Ответ написан
    Комментировать
  • ++i быстрее чем i++?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Теоретически, ++i быстрее. Практически - нет, потому что компиляторы могут и то и другое соптимизировать в одни и те же ассемблерные инструкции в большинстве случаев. Исключение, если инкримент используется в выражении. Но тогда они не взаимозаменяемы. Еще может быть случай, если i какого-то странного типа и инкрименты перегружены и криво написаны. Или если оптимизация отключена при компиляции. Или у вас доисторический компилятор.
    Ответ написан
    Комментировать
  • Как ускорить чтение строк из файла?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Может, ручной разбор будет быстрее. Читайте весь файл в большой буфер. Трехсимвольные строки - это пусть будут тупо char* на начало строк в этом буфере. Там пробелы замените на '\0' только. Вот вы уже сэкономили на разборе строк и выделении под них памяти. Числа руками разобрать придется правда (умножение на 10 + следующий символ - '0').

    Еще, вместо чтения файла какой-нибудь mmap может быть быстрее.

    Потом это можно еще и распараллелить каким-нибудь OpenMP, например. Разбейте буфер на примерно равные части, чуть подвигайте границы, чтоб они на переводы строк приходились и каждый кусок разбирайте отдельно.
    Ответ написан
  • Почему возникает malloc(): corrupted top size?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Вот тут: (long long int*) calloc(len_s1, sizeof(int)); вы выделяете массив int на len_s1 элементов, а потом работаете с ним, как с массивом long long той же длины. Но long long занимает больше байт! Поэтому вы выделяете меньше памяти, чем используете, а это UB.

    В этом случае программа может даже отработать, если повезет. И любое изиенение в ней может непредсказуемо изменить, как ошибка проявится: упадет ли программа, повиснет или просто не так отработает.
    Ответ написан
    1 комментарий
  • Стоит ли очищать оперативную память от массивов структур в Си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Нет, если это локальная переменная, ничего делать не надо. Она выделяется на стеке и отчищается автоматически по выходу из функции.

    Надо вызывать free только для тех блоков памяти, который вы сами получили через malloc.
    Ответ написан
    Комментировать
  • Как создать массив из типов данных в си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если массив фиксирован, то можно попробовать через variadic macros это сделать. Но это такой ужас получится. Вам же кроме размеров типов что-то еще делать надо с разными типами. Проще завести enum типов данных, массив из этого, и через switch считать размеры для каждого значения enum.

    Edit: был не прав: variadic macro тут не поможет.
    Ответ написан
  • Можно ли передать тип данных как параметр функции?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    В C - нет. В C++ можно воспользоватся шаблонами. Но если вопрос действительно про C, то надо передавать в функцию какой-нибуть enum где все возможные типы перечисленны. Или, как в scanf, передавать идентификатор типа в строке.
    Ответ написан
    6 комментариев
  • Есть ли флаг компиляции gcc, чтобы неявное приведение типов выводилась как ошибка?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    -Wconversion -Warith-conversion
    Ответ написан
    Комментировать
  • Как написать свое регулярное выражение?

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

    Конечный автомат будет и побыстрее работать и памяти меньше требовать.

    upd: ну и, конечно, тут полным перебором рекурсивно можно сделать. Но это будет гораздо медленнее любого из указанных выше методов.
    Ответ написан
    2 комментария
  • Почему scanf считывает значение только первой переменной?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если вам нужен ввод целых чисел, то читайте их в целые переменные через %d. Еще, scanf возвращает количество прочитанных значений. Т.е. сравнивать надо с тройкой, а не единицей.

    Еще одна проблема: возможно, из-за настроек локализации, оно ждет десятичные запятые, а не точки. Попробуйте ввести "1,0 2,0 3,0" или "1 2 3".

    И вообще весь ваш сценарий - это комбинация ошибок в пером и втором абзаце. Из за точек вместо запятых оно читает только первую переменную сначала, видит, что ввело 1 переменную и завершает цикл. При вооде "1 2 3" оно читает все переменные, но из-за ошибки в проверке (вы же хотите, чтобы одна прочиталась) читает опять. При повтороном вводе "1.0 2.0 3.0" оно читает только первую переменную и завершается. При этом в b и c остались значения от прошлого ввода.
    Ответ написан
    2 комментария
  • Почему при передаче имени файла как аргумент функции я не могу его открыть?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Смотрите внимателно на тип параметра в функции. Это char. Один символ, или число от 0 до 255. А вы потом рабоатете с ним, как со строкой (указателем на char). Вы передаете это число от 0 до 255 в strcat, он пытается записать что-то по адресу от 0 до 255 и, ожидаемо, падает.

    Поставьте там звездочку.

    Еще комментарии: ".txt\0". Терминирующий \0 ставить не надо, "" уже его ставит само. 10 символов на filename может не хватить.
    Ответ написан
    3 комментария
  • Почему вначале все работает, а потом нет?

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

    Да и я уж не помню, для не квадратных матриц ранг вообще определен-то?
    Ответ написан
    Комментировать
  • Как найти сумму элементов массива, находящихся на нечётных позициях?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Код выглядит правильно, только массив объявлен на 15 элементов, а цикл до 16 идет. И, возможно, надо 0 на 1 в проверке поменять. "Нечетные позиции", по человечески - это первая, третье и т.д. Но им соответствуют четные индексы 0, 2...

    Edit: А еще в коде стоит точка с запятой после for, из-за чего цикл оказывается пустым, а вводится только один элемент (и тот за границей массива):
    for (i=0; i<16; i++); // <----------
    scanf("%d", &A[i]);
    Ответ написан