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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    У вас переменная s локальная в main(), а вы ее в A() используете.

    Сделайте A() возвращающей среднее (и это должен быть не int а float). Заведите переменную для суммы внутри A. А функция PrintS() должна будет принимать это среднее для печати. А то и вообще удалите PrintS - функция для одной операции вывода несет мало смысла.
    Ответ написан
    Комментировать
  • Как разложить число на множители(си)?

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


    Приведите ваш код, который не останавливается. По идее, достаточно в него вставить return после нахождения первой пары множителей.
    Ответ написан
  • Не компилируется код?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    У вас операция присвоения лежит вне функции. Компилятор ждет там декларации переменных, функций, типов, вот это вот все, а у вас там операция. Перенесите присвоение в main().

    Если вы хотите структуру инициализировать, то можно пользоваться списком инициализации:
    struct {
            int debug;
    } config = {1};
    Ответ написан
    Комментировать
  • Как найти полусумму 32-битных знаковых чисел?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Прочитать бинарно не можете? Есть функция read.

    Читайте ей по 4 байта 2 раза в char buf[4].

    little-endian означает, что сначала идут самые минимальные байты. Т.е. buf[0] - это младшие 8 бит числа, buf[3] - старшие. Для собирания числа воедино смотрите на операцию сдвига. (int)buf[3] << 24 | (int)buf[2] << 16 поставит на место 2 старших байта (младшие додумайте сами).

    Тип 64-х битных чисел - long long. Вам в условии посоветовали им пользоваться.

    Сложить 2 числа сами сможете?

    Бинарный вывод делается, внезапно функцией write.

    Ну, еще входной и выходной файлы, возможно, открыть придется, через функцию fopen.
    Ответ написан
    3 комментария
  • Как сортировать массив с рандомными значениями?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    for(d=0; d < n; d++)
      x[i] = rand();
     printf("%d", x[i]);


    Цикл по d а присваивание в x[i]. Еще скобок нет, printf выполнится только один раз после цикла.

    Еще вы не выводите массив после сортировки, как вы вообще собираетесь понимать, что ваша программа работает?

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

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

    Попробуйте после free присвоить msg_buf = NULL.
    Ответ написан
    Комментировать
  • Как портировать линуксовое консольное приложение под Windows?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно попробовать какой-нибуть mingw поставить. Получается какбы линуксовая оболочка в винде. Можно компилить в ней исходники, получающийся exe-шник автоматом получит транслирование системных вызовов. Нет гарантии, что любой код заведется, но шансы есть.

    Т.е. виндовые исходники вы не получите, но есть вариант скомпилить эти линуксовые исходники в exe-шник, который, возможно, потребует установки mingw на машину, где приложение будет работать.

    Edit, возможно mingw тут не поможет и нужен cygwin. Еще был какой-то msys. Но я не уверен.

    На худой конец, под 10 виндой есть WSL.
    Ответ написан
    8 комментариев
  • У меня калькулятор выводит целое число почему?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    y = c / d;

    Вы делите целое число на целое. В языке С в этом случае происходит деление нацело. Чтобы в результате был float, вам надо один из операндов перобразовать во float/double. Можно или явно это написать, или просто прибавить 0.0:

    y = (c + 0.0) / d;
    Ответ написан
    2 комментария
  • Как задать матрицу X[5][7] на С?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Два цикла вложенных в друг друга. Внешний по строкам, 5 итераций. Вложенный по столбцам, 7 итераций. Внутри считывание одного числа с клавиатуры, но читаете не в какую-то переменную а в x[i][j].
    Ответ написан
    Комментировать
  • Как переместить данные по адресу?

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

    1) Если функция рекурсивная, то пусть она возвращает новую голову списка. Если текущий элемент удалять не надо, то перепишите next на результат вызова от этого next и возвращайте текущую запись. Если удалять надо, то отчистите память и возвращайте next.

    2) Если функция работает циклом, что предпочтительнее, то вы можете просто помнить предыдущий элемент списка. Двигайте 2 указателя параллельно.
    prev = cur;
    cur = cur->next;
    Ответ написан
  • Как вывести парные числа в си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Отсортируйте массив. Используйте стандартную функцию qsort.

    Потом пройдитесь по массиву. Выводите текущее число, если оно равно предыдущему и не равно следующему, или идет последним:
    if (a[i] == a[i-1] && (i+1== n || a[i+1] != a[i])

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

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

    Можно писать так:
    if ((i > 0 && a[i-1][j] > a[i][j]) || (i < n-1 &&  a[i+1][j] > a[i][j])) {
      // текущий элемент меньше хотя бы одного соседа в том же столбце.
    }

    еще можно так:
    if ((i == 0 || a[i-1][j] > a[i][j]) && (i == n-1 ||  a[i+1][j] > a[i][j])) {
      // текущий элемент меньше всех соседей в том же столбце.
    }



    Комбинируя условия на циклы через || и && можно составить любое нужное вам условие, которое смотрит только на существующих соседей. Но тут важен порядок операций. В C++ (да и почти везде, на самом деле) условия выполняются слева направо и прекращают выполнение, как только результат становится известен. Вот, в первом примере сначала идет проверка на i>0 а потом обращение к массиву через логическое И. Поэтому, если программа будет обрабатывать первый элемент в строке уже на первом условии она заметит, что все условие обязательно false, ведь там стоит &&. И условие с обращением к массиву не будет произведено никогда.
    Ответ написан
    Комментировать
  • Как реализовать калькулятор со скобками на си(через обратную польскую запись)?

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

    Если же от вас требуется что-то более самостоятельное, то делайте так - найдите в строке операцию с наименьшим приоритетом (ту, которая будет выполнена последней). Рекурсивно выведите обратную польскую запись для левой и правой половины, потом выводите/выполняйте операцию.

    Чтобы найти операцию - проходитесь по строке, считая сколько сейчас открыто скобок. Запомните позицию самого правого встреченного "+"/"-" и "*"/"/". Если ничего не нашли - значит можно откусить внешнюю пару скобок (если скобок нет, то вся строка - число). Иначе, если есть + или - - это та самая последняя операция. Если таковой нет - то будет * или / - берите ее.

    Это работает за квадрат в отличии от алгоритма по ссылке, но зато пишется элементарно.
    Ответ написан
    2 комментария
  • Как найти максимум среди всех локальных минимумов заданной матрицы?

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

    Фактически, тут 2 вложенные задачи: 1) Проверить, является ли значение локальным минимумом 2) Найти максимум в матрице (возможно игнорируя какие-то клетки).

    Советую решить задачи раздельно с помощью функций.

    Для первой задачи напишите функцию.

    bool IsLocalMinumum(int a[][m], int n, int m, int i, int j);


    Функция должна перебрать 4 варианта (прибавить/вычесть 1 из первого или второго индекса) и для каждого проверить: 1) сосед есть, т.е. не вышел за границу, 2) значение соседа меньше текущего. Если оба условия выполнились для какого-то направления - вы нашли "плохого" соседа. Текущая клетка не может быть минимумом. Сразу же возвращайте false. В конце функции всегда возвращайте true.

    Вторая задача - тривиальна совсем. Можете выбрать максимум из просто одномерного массива? Теперь вместо одного цикла по массиву делайте 2 вложенных по матрице. Потом допишите туда условие, вызывающее вашу IsLocalMinimum. Если вершине не минимум - просто делайте пропускайте клетку. Буквально if (!IsLocalMinimum(a, n, m, i, j)) continue;
    Ответ написан
    Комментировать
  • Как считывать несколько переменных в языке C?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Я правильно понимаю, что пользователь вводит от 1 до 3 чисел в строке и ожидает, что программа эти числа обработает и выведет результат? Иными, словами, программа реагирует на клавишу enter?

    Можно читать символы по одному через getch(), пока не прочитаете '\n'. По пути нужно парсить числа. Если символ цифра - то умножйте текущее число на 10 и прибавляйте цифру (помните, что (int)'0' != 0. Но символы цифры, слава богу, идут подряд в алфавите). Если прочитали пробел - переходите к следующему числу. Или, чтобы обрабатывать всякие много пробелов, лишние символы и другие проблемы ввода - лучше прочитать сразу же всю строку через fgets() и потом в ней уже парсить числа.
    Ответ написан
  • Как создать программу перевода из 8-ричной СС в 10-ричную?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Как вам уже написали - надо складывать цифры, умноженные на степени 8.

    Это один цикл, с последней цифры до первой: Прибавляйте к ответу текущую цифру, умноженную на текущую степень и потом домножайте текущую степень на 8.
    Ответ написан
    Комментировать
  • Как исправить ошибку invalid controlling predicate?

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

    Вам надо сделать так:
    const int num_iterations=1000000;
    const double h = (b-a)/num_iterations/2.0
    x = a;
    #pragma  omp  parallel  for  reduction (+:S)
    for (int i = 0; i < maxi; i++)
    {
        S = S + 1*(x/(x+1));
        x = x + h;
        S = S + 4*(x/(x+1));
        x = x + h;
        S = S + 1*(x/(x+1));
    }


    Удобнее, если зафиксировать сначала количество итераций, а не шаг h (шаг отсюда вычисляется). Потому что если отрезок нацело не делиться на h, то надо как-то это обрабатывать и вообще, а можно ли так считать?

    Я добавил reduction (+:S) в инструкцию openMP, потому что вам надо подсчитать общую сумму же. Без этого каждый поток что-то насуммирует отдельно. Шарить S между потоками сложно - может быть data race.
    Ответ написан
    Комментировать
  • Как правильно создать массив строк?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Как вам уже сказали, вы не выделяете массив нужного размера. Можно вместо int a[1][1] делать int a[100][100], например, если вам известно, что массив не будет больше 100 строк и столбцов. Но, по хорошему, это надо обработать и, если пользователь ввел row == 101, то надо завершиться, сообщив пользователю о слишком большой размерности.
    Ответ написан
    Комментировать
  • Как исправить странные ошибки Си-кода?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Куча не иницализированных локальных переменных. Эти переменные не обнуляются в языке Си. Там какой-то мусор. Может быть и 0, но это как повезет.
    number - вы там присваиваете rotor[number] что-то, а чему оно равно? i в цикле, как Rsa97 сказал.

    И вообще, вы с алгоритмом перемудрили. Вы случайно генерируете число, пока не найдете новое число в массиве.
    Есть более элегантное решение:
    Заполните массив числами от 0 до 74 подряд. Потом перемешайте его, как написанно в вики. Или можно совместить изначальное заполнение и перемешивание. Буквально, вся функция filling становится:
    void filling(int rotor[], int randvalue)
    {
      srand(randvalue);
      for(int i = 0; i < 75; ++i) {
        int j  = rand() % (i+1);
        rotor[i] = rotor[j];
        rotor[j] = i;
      }
    }
    Ответ написан
    Комментировать