Ответы пользователя по тегу C
  • Определение длины какой угодно строки, без заранее опредленного размера массива?

    @res2001
    Developer, ex-admin
    Выделяете динамически первоначальный размер памяти, читаете в него заданное количество символов (по размеру буфера), если конца строки не было, делаете resize буферу, дочитываете, проверяете конец строки и т.д.
    Можно читать по 1 символу и сразу его проверять на конец строки, но память при этом так же нужно увеличивать при необходимости. Медленнее скорее всего не будет, т.к. стандартная библиотека делает буферизацию по умолчанию, т.е. фактически все равно будет читаться не по 1 байту.
    Ответ написан
    Комментировать
  • Невозможно преобразовать double в void*?

    @res2001
    Developer, ex-admin
    Где функция convert()?
    Про сравнение строк вам уже ответили.
    Но у вас еще в printf полная фигня. Вы ей передаете void* при этом в шаблоне у вас int и double. Нужно делать преобразование и разыменование:
    if (type == "int"){
        printf("%d", *((int*)d));
      } else if (type == "float"){
        printf("%lf", *((double*)d));

    Ну и вместо строк "int, "float", ... лучше использовать какие-либо целочисленные константы - их то можно сравнивать напрямую.
    На Си вашу затею так же красиво как в плюсах не реализовать. Для каждого типа данных нужна своя функция convert с уникальным именем (converti(int), convertd(double), ...).
    В макросе нет возможности автоматически узнать какой тип данных ему передан, поэтому ваш код не откомпилируется.
    Необходимо явно указывать какую функцию для вывода вызывать (или явно указывать какой тип данных в нее передается).
    Например имеем набор функций для вывода соответствующего типа данных:
    void putsi(int);
    void putsd(double);
    void putss(const char *);
    
    #define PUTS(t, val)   puts ## t(val)
    
    int main()
    {
       PUTS(i, 123);
       PUTS(d, 3.14);
       PUTS(s, "hello world!");
      return 0;
    }
    Ответ написан
    Комментировать
  • Как вывести каждый байт значения типа int?

    @res2001
    Developer, ex-admin
    1234 в шестнадцатеричной системе 4D2.
    Младший байт равен D2, в двоичной системе это: 1101 0010
    Как видите старший бит установлен в 1 - значит, если это знаковое число, то оно отрицательное и закодировано дополнительным кодом. Осталось только разложить D2 в дополнительном коде и получите -46 - это результат вам и вывела printf.
    Ответ написан
    Комментировать
  • Почему строка объявленная как указатель на char не изменяется, а как массив char изменяется?

    @res2001
    Developer, ex-admin
    Скорее всего потому что в варианте
    char * str = "hello";
    Сама строка "hello" хранится в памяти "только для чтения", которая выделяется ОС для констант при загрузке программы в память.
    В варианте с массивом память выделяется в стеке, соответственно проблемы с изменением нет.
    Чтоб перейти на указатель - выделите память динамически и скопируйте туда строку. В конце не забудьте память освободить.
    Ответ написан
    3 комментария
  • В каком энкдодинге записывается в .txt?

    @res2001
    Developer, ex-admin
    Что лежит в msg, то и запишется в файл, без какого-либо перекодирования.
    Если нужно по другому - перекодируйте сами. Если нужно сменить кодировку символов, можно использовать библиотеки или встроенные API функции.

    PS: энкдодинг?
    Ответ написан
    3 комментария
  • Быстродействие за счет ногопоточьности в процессорах с помощью pthread, Cи?

    @res2001
    Developer, ex-admin
    Технологий параллельной обработки несколько. Многопоточность одна из них, pthread - POSIX стандарт поддержки многопоточности. В винде есть свой API для работы с потоками. Многопоточность, пожалуй, самый простой вариант распараллелить программу, но есть и свои тараканы.
    Профессор, скорее всего, имел ввиду другой вариант параллельной обработки, без контекста не понять.
    Ответ написан
    Комментировать
  • Почему не работают массивы переменной длины?

    @res2001
    Developer, ex-admin
    Поддержка VLA (и вообще всех новых расширений языка), действительно, зависит от компилятора.
    Например в MSVC, по моему, до сих пор поддержки VLA нет.
    Официально микрософт заявляет о поддержке С90: https://docs.microsoft.com/en-us/cpp/c-language/an...
    Но в компиляторе присутствуют расширения языка (по умолчанию включенные), список расширений можно посмотреть в описании опции компилятора /Zc, и VLA там нет.
    При том, что присутствуют некоторые расширения из С++17.
    Кроме того присутствуют некоторые вещи, которые появились в С99, но их в "расширениях" нет, они уже вошли в компилятор "по умолчанию", например переменное количество аргументов в #define.
    Ответ написан
    2 комментария
  • Почему не выводится кириллица из Си в консоль windows?

    @res2001
    Developer, ex-admin
    Если совсем просто и деревянно, то сохраните исходный код в кодировке cp866 и пересоберите.
    А если по сложному и по правильному, то учите мат.часть. Можно начать отсюда, так же посмотрите мой комментарий под статьей, в очередной раз уже лень все повторять - тут не однократно этот вопрос обсуждался. Вообще это самый распространенный вопрос у русскоязычных начинающих программистов на Си.
    Ответ написан
    3 комментария
  • Как ограничить число исполняемых потоков?

    @res2001
    Developer, ex-admin
    Если поток присоединенный, то в main можно его подождать с помощью thread join, если не присоединенный - выставляйте в потоке перед самым завершением какой-нибудь флаг означающий завершение потока. В main проверяете флаг.
    Но "технологичнее" сделать так, что когда поток выполнил одно задание, он снова полез в очередь и взял оттуда другое задание. Если заданий нет, то пусть ждет. В этом вам помогут примитивы синхронизации типа мьютексов и т.п.
    Ответ написан
    Комментировать
  • Построение графика функции на языке C?

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

    @res2001
    Developer, ex-admin
    Память работает просто - туда можно писать и читать из нее. Еще она плоская и одномерная. Еще она виртуальная, но для прикладного программиста - это не важно, виртуальностью занимается ОС. Нужна она для того чтоб один процесс не видел что делается в другом процессе (например, в MS-DOS не было виртуальной памяти и любая программа могла запросто уронить ОС просто записав что-нибудь не нужное в память занимаемую системой), чтоб каждый процесс имел 4 Гб (для х32 приложений) адресуемой памяти не зависимо от физического наличия этой памяти.
    Кроме самой памяти есть еще регистры процессора, но о них вспоминают только переходя к ассемблеру, т.к. даже Си не умеет ими манипулировать (оно и не нужно на самом деле).
    Процессы и потоки - это сущности ОС предназначенные для параллельного выполнения кода. Реально выполняются потоки, а процесс - это оболочка для объединения нескольких потоков в одном адресном пространстве. В любом процессе есть хотя бы 1 поток.
    Реальную параллельность можно достичь только тогда когда физических ядер процессора >1. Причем, обычно, вы никак не можете регулировать когда у вашего потока ОС отберет процессорное время, а когда снова даст. Это можно делать только выставляя уровень приоритета потока/процесса.
    Поток отличается от процесса тем, что у двух разных процессов разные адресные пространства (виртуальная память в действии) и им для общения нужно использовать какие-либо механизмы межпроцессорного взаимодействия (сокеты, pipe, shared memory, файлы, ...) предоставляемые ОС. Потоки одного процесса работают в одном адресном пространстве, поэтому для взаимодействия им ничего изобретать не нужно, т.к. они просто могут обращаться к одной и той же переменной. Но тут сразу возникает состояние "гонки" и все что с этим связано. Чтоб как-то упорядочить одновременное обращение к участкам памяти или кода нужны мьютексы и т.п. средства. Между тем, в простых случаях, можно запросто обходится и без мьютексов просто грамотно структурировав код и в правильном порядке обращаясь к "общим" участкам памяти. Если это понимать, то писать многопоточные приложения становится не сильно сложно.
    Думаю можно начать с прочтения какой-нибудь толстой книги про теорию построения ОС, например Таненбаума.
    А Си - да полезно, но если вы этим денег не зарабатываете, то скорее всего не нужно.
    WEB, PHP, JS, CSS и т.п. питоны, как правило, далеки от железа и ОС, на которых это все функционирует.
    Ответ написан
    Комментировать
  • Какая проблема при выполнении цикла?

    @res2001
    Developer, ex-admin
    Вот здесь:
    a[dd + 1]
    выход за границы массива на последней итерации цикла.
    Ответ написан
  • Какие дистрибутивы Linux вы посоветуете для практики NASM и C с низким порогом входа?

    @res2001
    Developer, ex-admin
    Для ваших целей не важно какой дистрибутив - внутри на Си у всех POSIX, а на asm - процессорные инструкции и тот же POSIX.
    Берите широко распространенный, с большим сообществом, у которого регулярно выходят новые версии и есть "нормальная" графическая оболочка из коробки. Например Убунту вполне подойдет.
    Т.к. вы "виндузятник", то в любом случае сначала придется привыкать, поэтому современный поддерживаемый дистрибутив вам поможет преодолеть первый этап вхождения.
    Ответ написан
    Комментировать
  • Strict aliasing - когда/где и у кого шалит оптимизатор?

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

    @res2001
    Developer, ex-admin
    Почитайте про битовые операции.

    пусть x - ваше число, в общем случае выражение установки старших 4 бит в единицу будет таким:
    x | (0xf << (sizeof(x)*8-4) );

    Выражение (0xf << (sizeof(x)*8-4) ) можно заменить на константу, которая зависит от разрядности представления числа х. Например для 32 битного int константа будет 0xf0000000
    Ответ написан
    2 комментария
  • Маленький диапазон char?

    @res2001
    Developer, ex-admin
    Так же могут быть проблемы с кодировкой: например программа скомпилирована с поддержкой Unicode и ждет на входе Unicode символы, а консоль работает в однобайтной кодировке (CP1251 или Cp866) или наоборот.
    Судя по описанию у вас как раз "наоборот", т.е. на вход вы подаете Unicode, а программа работает с однобайтной кодировкой. Правда символы из младшей половины таблицы ASCII в UTF8 так же занимают 1 байт, поэтому с цифрами и английскими буквами проблем быть не должно, а с русскими уже начнутся.
    Ответ написан
    Комментировать
  • Как проверить на ввод числа?

    @res2001
    Developer, ex-admin
    Считывать по символьно с помощью getchar() и анализировать каждый символ.
    Ответ написан
    Комментировать
  • Как на СИ преобразовать вводимое дробное или целое число в внутренний формат(спт/сфт) и вывести его?

    @res2001
    Developer, ex-admin
    Не понял то такое спт/сфт.
    Но в функциях printf есть спецификаторы для вывода в 16-сс.
    Если вручную, то я бы завел массив из 16 элементов char, куда записал шестнадцатиричные цифры, потом берете половину байта как индекс массива и строите строку из элементов массива.
    Ответ написан
    Комментировать
  • Как запустить код в процесс компьютера?

    @res2001
    Developer, ex-admin
    Не ясно зачем вы читали исполняемый файл.
    Запустить процесс можно с помощью CreateProcess, только он запустит файл на диске, а не ваш считанный.
    Ответ написан
  • Как создать хэш таблицу с помощью си?

    @res2001
    Developer, ex-admin
    Проще было бы ваш словарь отсортировать один раз и сохранить в таком виде, искать двоичным поиском, без всяких хэш таблиц и накладных расходов. Работать будет быстрее, чем хэш-таблица.
    Ответ написан
    2 комментария