Ответы пользователя по тегу C
  • Почему в массив размером N можно положить больше чем N элементов?

    @res2001
    Developer, ex-admin
    В malloc при передаче в качестве аргумента нуля возвращаемое значение не определено (implementation-defined). Так что фиг знает что там вам вернул маллок. Но раз программа не падает, то, возможно, он вернул какой-то указатель на стек, а в стеке у вас есть ~8МБ - развлекайтесь.
    В общем не нужно так делать. На другом компиляторе (или на том же, но другой версии) поведение может быть совсем другим.
    Ответ написан
    Комментировать
  • Как кидать исключения при работе с try catch?

    @res2001
    Developer, ex-admin
    Сишные функции не вызывают исключений. В Си их просто нет. Поэтому помещать их в try/catch нет смысла - проверяйте возвращаемые значения по старинке. Если хотите, можете написать обертки для стандартных функций, генерирующие исключения в случае ошибки. А еще лучше использовать std::fstream - вы же пишите на С++, так и пользуйтесь плюсовой стандартной библиотекой, а не Сишной.
    void foo() {
        int *smth;
        try {
            smth = new int[100];
            if (5 < 4) {
                std::runtime_error("Беда");
            }
        } catch (std::runtime_error &e) {
            e.what();
        }
        delete[] smth;
    }

    new генерирует std::bad_alloc, если произойдет исключение - память не выделилась и ничего удалять не надо.
    Ответ написан
    2 комментария
  • Как удалить элемент массива?

    @res2001
    Developer, ex-admin
    Прежде всего я не понимаю, как выбить этот элемент из массива

    В вопросе уже есть ответ на вашу непонятку:
    для чего выполнить сдвиг влево.

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

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

    У вас есть 2 вариант.
    1. Простой - выделить массив в main, передать его в getMas. Из getMas уже можете ничего не возвращать, только заполняете там массив.
    2. Выделяете динамический массив в getMas с помощью malloc. В main не забудьте освободить память, выделенную для массива. Это плохой вариант, т.к. память выделяется на одном уровне программы, а освобождается на другом. Но в вашей простой задаче можно пока на это не обращать внимания.
    Ответ написан
    Комментировать
  • Как устроен list() в Python?

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

    PS: Ваши выводы, основанные на структуре питоновского списка, верны.
    Для студента 1 курса очень не плохо!
    Ответ написан
    Комментировать
  • Почему приведение (int) pow ( variable1, variable2 ) отличается от (int) pow ( constant1, constant2 )?

    @res2001
    Developer, ex-admin
    В последнем случае сыграла, видимо, какая-то оптимизация компилятора и реального вызова pow не было.
    Вообще 99 получается в результате преобразования плавающей точки в int.
    Ответ написан
    Комментировать
  • Не знаю с чего начать писать код?

    @res2001
    Developer, ex-admin
    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
       printf("Hello world!\n");
       return 0;
    }


    Если серьезно, то сначала нужно поставить задачу. Сделать декомпозицию. Продумать методы достижения цели.
    А там уже и до кода не далеко.
    Ответ написан
    2 комментария
  • Как называется книга для с и с++?

    @res2001
    Developer, ex-admin
    Еще есть хорошая книга Дейтелов "Как программировать на Си". Там то же самое начало Си, дальше С++. Книжка годная.
    Ответ написан
    Комментировать
  • Как добавить мнимую единицу на языке Си?

    @res2001
    Developer, ex-admin
    В стандарте уже есть комплексные числа:
    https://en.cppreference.com/w/c/language/arithmeti...
    Почему их не используете?

    Правда не все компиляторы их полноценно поддерживают.
    Примерно год назад пытался подружить с микросовтовским компилятором код со стандартными комплексными числами, нормально собирающийся gcc. Не удалось, пришлось делать свои костыли, но в целом это было не трудно.
    Ответ написан
    Комментировать
  • Как получить доступ к оболочке в программе на C на строке system("/bin/bash"); если запускать программу из sh-скрипта?

    @res2001
    Developer, ex-admin
    system() не предоставляет подобного функционала.

    Необходимо перед запуском процесса создать набор пайпов, форкнуть процесс, в дочернем заменить на пайпы stdin и stdout, затем уже стартовать процесс с помощью одного из вариантов exec.

    Если обратная связь не нужна (т.е. не нужно читать, то что пишет дочерний процесс), то можно делать по упрощенной схеме через popen/pclose.

    На эту тему в гугле и в литературе масса информации, просто правильно задайте вопрос. Искать нужно что-то типа "перенаправление stdin stdout"

    PS: запуск из sh скрипта или на прямую значения не имеет.
    Ответ написан
    Комментировать
  • Удаляется первый символ строки. Как пофикить?

    @res2001
    Developer, ex-admin
    У вас не правильно объявляется массив messge и line. Нужно так:
    char message[255]
    Первый символ у вас видимо съедает getchar(). С какой целью вы их втыкаете везде?
    Ответ написан
    1 комментарий
  • На чем лучше писать на языке Си?

    @res2001
    Developer, ex-admin
    IDE включает в себя в том числе и текстовый редактор, заточенный именно под создание кода.

    В винде MSVS не плох, но имейте ввиду, что компилятор по умолчанию (микрософтовский cl) официально не поддерживает стандарты Си. Возможно поддерживает ANSI C, но тут я не в курсе, т.к. он не актуален. Какие-то вещи из свежих стандартов работают, другие нет, некоторые работают, но не совсем так как в стандарте.
    gcc, clang - поддерживают стандарты.
    Я использую qtcreator. Его можно использовать даже если в проекте не применяется Qt и нет С++.
    Раньше использовал eclipse, но он написан на Java, соответственно тормоза в самый не подходящий момент, изрядно подбешивал этим.

    Тут еще важен момент, какую систему сборки использовать. Если используете MSVS + cl, то система сборки будет msbuild ну и там особо заморачиваться не нужно - конфигурируете проект в студии и все применяется как надо, по сути вы и не видите систему сборки, но она есть, как суслики.
    Так же MSVS поддерживает и другие компиляторы и системы сборки, например cmake, но тут уже придется изучать язык управления системой сборки и писать свои сборочные скрипты.
    В qtcreator по умолчанию используется qmake, так же умеет из коробки cmake. То же нужно писать сборочные скрипты.
    Eclipse - тут можно без системы сборки, через свойства проекта все делать. Eclipse сам все соберет. Но местами довольно запутано, хотя быстро привыкаешь. Кроме того в конце концов вам понадобится собрать проект без IDE (например у заказчика), вот тут вам и понадобится система сборки, которой вы не обзавелись в Eclipse и придется как-то выходить из положения. Я писал makefile в этом случае, мне казалось это самым простым вариантом. Сейчас я так не думаю - проще сразу делать проект используя какую-то систему сборки. В том числе и по этому отказался от Eclipse.
    Ответ написан
    Комментировать
  • Как установить порядок компиляции файлов в Atmel Studio?

    @res2001
    Developer, ex-admin
    Непосредственно к Atmel Studio это не относится. Это особенность работы С/С++ компиляторов.

    Будто бы компилятор сперва отдельно от всего, игнорируя что написано в main.c, отдельно компилирует led_display.c

    В корень зрите. Каждый файл исходных кодов в Си и С++ компилируется отдельно от других. Это называется единицей трансляции.
    Объединяются объектные файлы только на этапе линковки. В процессе сборки исполняемого файла компиляция исходников и линковка объектных файлов разделены.

    Макросы, которые должны быть общими для всех исходников помещайте в отдельные хедеры и включайте эти хедеры в соответствующие файлы исходных кодов.
    Как вариант макросы можно задавать глобально опцией компиляции для всех файлов в проекте. Можно через makefile или опциями в проекте в IDE.
    В вашем случае можно просто этот макрос поместить в led_display.h.
    Ответ написан
  • Как проверять на нестрогое неравенство вещественные числа?

    @res2001
    Developer, ex-admin
    Много букв, не осилил.
    Но для вашей задачи просто переведите float в double и забудьте об этой проблеме.
    Другой вариант - пересчитывать дельту в число с фиксированной точностью, в целое грубо говоря.

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

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

    https://www.boost.org/doc/libs/1_64_0/libs/math/do...
    https://rsdn.org/forum/cpp/2640596.1
    https://habr.com/ru/post/112953/
    https://randomascii.wordpress.com/2012/02/25/compa...
    Ответ написан
    Комментировать
  • Как мне правильно соединить три строки и сделать системный вызов?

    @res2001
    Developer, ex-admin
    Когда делаете memcpy указатель на result надо смещать на размер предыдущей скопированной строки. Сейчас вы просто копируете следующую строку, затирая предыдущее копирование.
    memcpy(result + strlen(part1), filenames, strlen(filenames));

    strcat должен нормально отработать, он делает по сути то же самое.
    При копировании строк лучше использовать strcpy (или strncpy), она копирует и завершающий 0. memcpy предназначена для копирования памяти произвольного содержимого.
    Ответ написан
  • Правильно ли реализован lock-free битовый массив?

    @res2001
    Developer, ex-admin
    Какого-то специфического lock-free алгоритма у вас в коде нет.
    Достоточно для чтеня/записи использовать атомик операции и оно будет нормально работать, без гонки данных.
    Ответ написан
    Комментировать
  • Какую использовать среду разработки C под Windows?

    @res2001
    Developer, ex-admin
    Под винду лучше всего MSVS и микросовтовский компилятор, но, как верно заметил Дмитрий Золотарев, у микрософтовского компилятора проблемы с поддержкой современных стандартов. Точнее Микросовт в принципе не заявлял о поддержке стандартов Си (может быть ANSI C, но я не уверен).
    В принципе, если вы пишите исключительно под винду, то на это можно не обращать внимания - поддержки нет только для каких-то вещей, которые микрософт считает не нужным поддерживать, например VLA, многопоточность. Большая часть Сишного кода вполне нормально собирается микросовтовским компилятором.
    Так же можно использовать IDE qtcreator. Компилятором к нему может быть тот же микросовтоский из состава MSVS или mingw. В этом случае я бы все таки так же использовал компилятор от микрософта, т.к. он дает более компактный и быстрый код, имхо. Микрософтовский компиялтор, кстати, можно поставить отдельно, без студии, называется Microsoft Build Tools ищите на сайте микрософта.
    Ответ написан
    Комментировать
  • Почему не работает strcpy?

    @res2001
    Developer, ex-admin
    На будущее - все подобные ошибки решаются гуглением по тексту ошибки.
    В данном случае вам нужно включить заголовочный файл стандартной библиотеки string.h
    Ответ написан
    2 комментария
  • Как передать сткроку, которая заканичвается на: !x в качестве аргумента командной строки?

    @res2001
    Developer, ex-admin
    Попробуйте в одинарных кавычках передавать, а не в двойных.
    Чем вас не устраивают стандартные функции работы со строками?
    Ответ написан
    7 комментариев
  • Почему массив malloc не наполняется?

    @res2001
    Developer, ex-admin
    1.rand() генерирует только положительные числа: https://en.cppreference.com/w/c/numeric/random/rand
    2.Даже если бы с п.1 было бы все нормально, то после того как выделена память для mas_otr ее нужно обнулить, т.к. malloc никакой инициализации памяти не производит и там будет содержаться мусор. А вы заполняете mas_otr только выборочно. Так что итоговый результат очевидно то же будет не тем, что вы ожидаете.
    3.нужно в правильных местах в вывести переносы строк, а то сейчас у вас все будет лепиться в одну строку.
    4.В sort() вместо массива вы передаете целое число.
    Ответ написан