Ответы пользователя по тегу C
  • Как устроен 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() вместо массива вы передаете целое число.
    Ответ написан
  • Как считать из файла двоичные числа и перевести их в десятичные?

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

    Если файл записан на машине с одной и той же архитектурой, то при таком подходе проблем не будет.
    Если же архитектуры (процессоры) разные, то может вмешаться порядок байт (big/little endian). Это нужно учитывать.
    Так же, если вы читаете файл в котором записаны данные разных типов (например какая-то структура), то может возникнуть проблема с выравниванием полей в структуре. https://stackoverflow.com/questions/4306186/struct...
    Думаю, что к вашей текущей задаче эти нюансы не относятся. Но знать, что двоичная чтение/запись это несколько сложнее аналогичных операций с текстом стоит.
    Ответ написан
  • Как правильней сделать это на си?

    @res2001
    Developer, ex-admin
    Правильно пишут. Вас не смущает два void* в callback?
    У вас функция принимает 2 параметра на что угодно, хреновая идея. Тут и будут ошибаться.
    На сколько я могу судить data - это пользовательские данные, тут void* без вариантов, но можно обозвать например userdata и описать, что userdata в калбэке и в init - это одно и то же и библиотека больше никак не использует этот указатель.
    На мой взгляд event вполне можно описать какой-то заранее определенной структурой. Или хотя бы у этой структуры должен быть единый заголовок (включающий тип события и возможно что-то еще общее для всех событий). Посмотрите, например, на адресные структуры в сокетах: struct sockaddr, struct sockadd_in, struc sockaddr_in6. Это не самая удачная реализация, на мой взгляд, но достаточно распространенная. Гораздо лучше реализованы объекты в питоне (имею ввиду исходный код самого питона на Си), принцип тот же, но реализация более понятна.
    callback может принимать указатель на заголовок структуры, затем его можно будет преобразовать в структуру для конкретного типа события. Хорошо бы для этого предусмотреть в реализации набор макросов.
    Общий посыл таков: нужно как можно реже использовать void*, можно его использовать только тогда когда без этого ну вообще никак не обойтись (а если обойтись, то это будет ну очень "дорого"). К сожалению в Си время от времени приходится использовать void*. В т.ч. для решения этой проблемы в плюсах придумали шаблоны.

    Я так и не понял, что означает type.
    По моему идентифицировать издателей/подписчиков лучше всего по имени. И пусть имя они сами себе выбирают.

    Где набор функций для добавления/удаления подписчиков?
    Ответ написан
  • Как передать массив списков в функцию Си (С++)?

    @res2001
    Developer, ex-admin
    int searchByHash(Stack* hashTable, int element)
    Ответ написан
    Комментировать
  • Зачем определению(definition) объявлять(to declares), если есть определение(definition), которое определяет(to defines)?

    @res2001
    Developer, ex-admin
    int val;
    Является одновременно и определением и объявлением.
    В данном случае происходит реальное выделение памяти под переменную.

    Объявление это
    extern int val;
    Оно говорит компилятору, что где-то есть переменная val типа int. В этом случае компилятор уже знает какие операции допустимо использовать с этой переменной, но память под переменную не выделяет. Реальный адрес переменной подставит линковщик, когда будет собирать исполняемый файл из нескольких единиц трансляции.
    Если в одной единице трансляции вы используете объявление переменной, то где-то (в другой единице трансляции или в этой же) вы должны обязательно сделать определение. Иначе линковщик не найдя определения выдаст undefined reference.
    Если же определять переменную в каждой единице трансляции, то линковщик выругается на redefinition symbol, т.е. несколько символов с одним именем (переопределение существующего символа).
    Если вам все таки нужны символы с одним именем в разных единицах трансляции, то вы должны объявлять их static. В этом случае будет использоваться локальная для данной единицы трансляции переменная с данным именем.

    С функциями все аналогично.
    Ответ написан