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

    @res2001
    Developer, ex-admin
    2.потеря данных происходит. Пустяк или нет - зависит от задачи. В вашем случае пустяк, в других - нет.
    Все вещественные константы в вашем коде являются double, поэтому все ваши переменные при вычислениях переводятся в double, вычисляется результат как double и переводиться во float для сохранения результата.
    Чтоб убрать сообщение:
    - все переменные сделайте double или
    - ко всем константам добавьте суффикс f, например: 1.f - тогда константы будут float и все вычисления будут происходить над float - потерь не будет, потому что не будет конвертации типов.
    3.fabs - для вещественных чисел, abs - для целых. fabs определяется в math.h, abs - stdlib.h
    4. Обычно в #include для своих хидеров используют кавычки, для системных/библиотечных - <>. Их разница в том, что в "" поиск заголовка начинается с каталога где находится текущий компилируемый файл, потом по всем остальным, известным компилятору местам. Для <> - поиск в текущем каталоге не производится, поэтому ваши собственные заголовки компилятор может не найти (если не указать опцию -I).
    https://en.cppreference.com/w/c/preprocessor/include
    Ответ написан
    Комментировать
  • C++ ошибка при выполнении программы, как ее исправить?

    @res2001
    Developer, ex-admin
    Из-за того что в первом и втором цикле условия разные, у вас выделяется массив строк (a[]) меньшего размера, чем происходит к нему обращений во втором цикле. Отсюда - выход за границы массива и сбой программы.
    Ответ написан
    Комментировать
  • Почему жалуется на преобразование double > float?

    @res2001
    Developer, ex-admin
    double у вас константы в выражении. По умолчанию вещественные константы - double. Поэтому все остальные компоненты выражения преобразовываются в double, а при присваивании необходимо снова преобразовать во float с потерей точности, об этом и сообщает компилятор.
    Чтоб сделать константы float, нужно использовать суффикс 'f': 9.0f. Тогда все выражение будет вычисляться во float.
    Ответ написан
    2 комментария
  • В какой директории хранить файл для считывания из программы?

    @res2001
    Developer, ex-admin
    Передавайте путь к файлу в параметре и кладите куда угодно.
    Ответ написан
    2 комментария
  • Как sizeof вычисляет размер массива?

    @res2001
    Developer, ex-admin
    sizeof - это не функция (хоть и выглядит похоже) - это операция взятия размера.
    sizeof всегда вычисляется на этапе компиляции, т.е. в исполняемом файле вместо вызова sizeof уже будет вычисленная константа.
    Когда компилятор знает размер массива, как в вашем примере, он вернет полный размер массива.
    Но если передать в sizeof произвольный указатель (именно указатель, а не статический массив), он вернет размер указателя.

    Статический массив - это не указатель. Указатель - на этапе выполнения занимает в памяти место для хранения адреса. Статический массив занимает в памяти место для хранения данных массива.
    Поэтому статический массив - это не указатель. Хотя часто компилятор работает с именем статического массива как с указателем.
    Ответ написан
    8 комментариев
  • Как динамически указать длину поля для вывода в printf?

    @res2001
    Developer, ex-admin
    1.Можете просто сформировать правильную Си строку, добавив в конце нулевой символ, тогда printf правильно сработает при спецификаторе формата %s.
    2.Если у вас не строка, а байтовый массив (т.е. нет завершающего нулевого символа), тогда можно следующим образом: printf("%.*s", (int)len, str)
    Ответ написан
    2 комментария
  • Как вывести символ не из ASCII таблицы?

    @res2001
    Developer, ex-admin
    Сменить кодировку консоли на UTF-8 и конвертировать строки перед выводом в UTF-8.
    Ответ написан
    Комментировать
  • Стоит ли переходить на С?

    @res2001
    Developer, ex-admin
    Согласен с предыдущими ораторами, что язык под задачу, а не наоборот.

    Если хочется низкого уровня, то сосредоточьтесь на С++. Сам по себе Си - язык очень компактный и простой. Изучая С++ для понимания внутренних механизмов уделите внимание указателям, адресной арифметике, работе с нативными массивами и строками (не std::valarray и std::string) - то же самое будет и в Си.
    Когда пишешь на Си очень не хватает классов и иногда шаблонов из С++ - толковой альтернативы в Си нет.
    Если когда-то придется участвовать в проекте на Си, то перейти с С++ будет достаточно просто. Адаптироваться к нюансам и привыкнуть к стандартной библиотеке Си можно быстро.
    Все это я к тому, что необходимости отдельно изучать Си нет - освоив на хорошем уровне С++ вы сможете начать писать на Си, когда будет необходимо. Но наоборот - не выйдет.
    Ответ написан
    1 комментарий
  • C - Как в массиве найти наибольшую подпоследовательность полных квадратов?

    @res2001
    Developer, ex-admin
    1. 2 - потому что вы делаете k = 1, когда последовательность кончается. Делайте k = 0 - будет 1.
    И уберите условие - оно совершенно лишнее.
    else
                {
                        k = 0;
                }


    2.На мой взгляд вычислять является ли число полным квадратом таким образом нельзя - как минимум, потому что сравнивать вещественные числа напрямую - плохая идея. Почитайте для затравки, например тут.
    Я бы сделал как-то так:
    double v = sqrt(arrayName[i]);
    double v1 = floor(v);
    if((v - v1) < 0.000001)
    {
    // число- полный квадрат
    }

    Константу 0.000001 - я выбрал наугад, как достаточно маленькую для вашего случая.
    Вообще вопрос сравнения вещественных чисел - отдельная тема, представленный выше подход, лишь один из вариантов, не самый лучший, но в вашем случае работать будет.
    Ответ написан
  • Можете посоветовать IDE под C/C++ как CLion (с возможностью подключения MinGW) под 32 бита (x86)?

    @res2001
    Developer, ex-admin
    Eclipse CDT
    Ответ написан
    Комментировать
  • C - Как объединить две последовательности (массива) в один без повторения чисел?

    @res2001
    Developer, ex-admin
    С помощью конструкции:
    return sizeof(arrayName) / sizeof(arrayName[0]);
    вы не получите размер массива для динамических массивов, это работает только для статических, когда компилятору заранее известен размер массива. Операция sizeof() - исполняется во время компиляции.
    Вы должны вручную считать размер массива c и увеличивать его при realloc.
    Ответ написан
    Комментировать
  • Почему не компилится код на си с подключением к бд?

    @res2001
    Developer, ex-admin
    Видимо нужно подключать заголовки так:
    #include <mysql/mysql.h>
    Пользуйтесь тегами - невозможно читать.
    Ответ написан
    2 комментария
  • Как вывести адрес объекта в си?

    @res2001
    Developer, ex-admin
    #include <inttypes.h>
    printf("%" PRIuPTR, &i);
    Ответ написан
  • Как работает этот printf()?

    @res2001
    Developer, ex-admin
    По умолчанию недостающие символы замещаются пробелами, но можно указать и нули: %06.2f
    Ширина указывает минимальный размер поля, т.е. это не фиксированный размер и он может быть больше, если необходимо.
    www.cplusplus.com/reference/cstdio/printf/?kw=printf
    Ответ написан
    Комментировать
  • Как отключить буферизацию ввода и эхо-вывод (termios.h, stdin)?

    @res2001
    Developer, ex-admin
    На сколько я понял вам нужно перевести терминал в raw режим.
    Для этого нужно выставить кучу флагов в struct termios и вызвать tcsetattr(().
    Вот как это реализовано в libuv:
    struct termios tmp;
          tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
          tmp.c_oflag |= (ONLCR);
          tmp.c_cflag |= (CS8);
          tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
          tmp.c_cc[VMIN] = 1;
          tmp.c_cc[VTIME] = 0;
      tcsetattr(fd, TCSADRAIN, &tmp);

    Код выдран из исходников libuv: src/unix/tty.c -> uv_tty_set_mode().
    Ответ написан
    1 комментарий
  • В чем смысл работы побитово с десятичными цислами?

    @res2001
    Developer, ex-admin
    Используют доступ к битам, обычно, для хранения и проверки некоторого набора флагов. Т.е. каждый бит некоторой переменной является флагом, если бит равен 1 - флаг выставлен, если 0 - сброшен.
    Результат функции getbits можно интерпретировать как логический признак - выставлен определенный флаг или нет. В этом случае вызов getbits можно спрятать за макросами, которые будут подставлять соответствующие параметры в getbits в зависимости от того какой флаг проверяется.
    То же самое можно решить и структурой с битовыми полями, в этом случае компилятор возьмет на себя всю работу с битами. Результат при этом будет примерно тем же, что и в случае ручного манипулирования битами.
    Ответ написан
    Комментировать
  • Си. Как удалить символы стоящие перед знаком *?

    @res2001
    Developer, ex-admin
    Удалить нельзя. Можно только остаток строки после звездочки скопировать/перенести на место звездочки.
    Т.к. память будет перекрываться, то нужно использовать функцию memmove, memcpy в этом плане не безопасна.
    Ответ написан
    6 комментариев
  • Найти самое часто встречающееся слово в тексте. Ввод слов в динамический массив. Как сделать без map?

    @res2001
    Developer, ex-admin
    Используйте хэш-таблицу, например khash из состава klib, там же есть и другие структуры. Библиотека написана на Си.
    Ответ написан
    Комментировать
  • Где ошибка в коде, потерялся символ, и не работает free()?

    @res2001
    Developer, ex-admin
    Крашится на free скорее всего из-за того, что у вас где-то выход за границу массива и вы перезаписываете служебные данные менеджера памяти. Нужно искать выходы за границу массива.

    1.Как минимум ошибка при realloc - вы увеличиваете массив только 1 раз, а что если строка попадется очень длинная и нужно будет еще увеличивать буфер?
    Вам нужно в getlen передавать текущий размер буферов и возвращать из нее новый размер, если был realloc.
    Кроме того нужно определить до какого максимального предела вы готовы увеличивать буфера - память не безграничная (даже виртуальная) и если буфера вырастают за допустимый предел - нужно выдать ошибку и завершить программу.

    2. В del_spacetab лишние условия в if:
    if ((*p1)[i] == ' ' || (*p1)[i] == '\t' && (*p1)[i] != '\n')
    Если я все правильно понимаю, то не равенство с '\n' тут излишне, или может быть не хватает скобок. Обычно, если в логическом выражении нужно использовать и || и &&, то для большей читаемости нужно использовать скобки для точного определения того что вы хотите сказать этим выражением.
    Следующим else if - вы обнуляете счетчик на каждом не пробельном символе ...
    Ну и функция del_spacetab не делает то что вы хотите - она просто возвращает количество "пробельных" символов, потом вы при копировании их не отбрасываете.

    3.В функциях, кроме getline, не нужно передавать двойные указатели на буфера - достаточно простых указателей.
    В getline нужны двойные указатели потому что в случае увеличения размера буфера вы должны через них вернуть указатели на новые буфера. В остальных функциях это не требуется.

    PS: Запустите программу под отладчиком и отслеживайте все изменения состояния (переменных) в ручную.
    Ответ написан
  • Обьясните, что здесь происходит ++ndigi[c-'0']?

    @res2001
    Developer, ex-admin
    Выражение (c-'0') возвращает индекс в массиве nidigi[10].
    В переменной
    char c;
    лежит ASCII код введенного символа (цифры), если из этого кода вычесть ASCII код символа '0', то получите цифру от 0 до 9, что и требуется. Чтоб удостоверится посмотрите таблицу ASCII кодов.
    В массиве nidigi в итоге количество вхождений десятичных цифр во входных данных - гистограмма.
    Ответ написан
    1 комментарий