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

    mayton2019
    @mayton2019
    Bigdata Engineer
    Буквально недавно было обсуждение здесь https://qna.habr.com/q/1241266

    Если кратко - то под каждую платформу - надо писать какой-то #ifdef ....#endif. Тоесть ваш код
    будет в объеме умножаться на число платформ которые надо поддержкать. Сколько их щас?

    В чистом виде язык "C" не имеет какого-то стандарта на отображение графики.
    Ответ написан
    Комментировать
  • Кроссплатформенное программирование на C?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Давайте поговорим о шрифтах. В 2012 я перешел с windows7 на Linux. И первая проблема практической работы с десктопом заключалась в том что я начал менять шрифты. Вот не нравились мне не шрифты не алгоритмы их рендеринга. Надо отдать должное МС. Шрифты у них хорошие. Дизайнеры очень долго думали над ними. Вот. Когда вы заняты кросс-платформенным UI возникает проблема. - Где взять шрифты максимально похожие на оригинал. Высота. Кернинг. Все должно быть максимально похожим на оригинальный десктоп где идет разработка иначе дизайн разваливается. В годы развития Linux Suse я пытался устанавливать их десктопы и использовать. И самая большая визуальная проблема что я видел - это полный развал шрифтового оформления. Доходило до смешного. Я просто не мог прочитать кириллический месседж в окне. Текст - сползал куда-то за границу окна. Или текст успешно переносился а баттон сползал за границы окна. Вобщем проблем было масса. Я думаю что одна из главных проблем кросс-платформенного UI - это унификация шрифтов. И дело тут вовсе не в Qt или Gnome/Gtk или KDE. А дело в том что другая платформа понятия не имеет как должен выглядет текстовый месседж.
    Ответ написан
    Комментировать
  • Bsd-socket. Почему бесконечное чтение при http запросе?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Скорее всего отправитель перестал что-то отправлять. Это не ошибка. Это нормальное состояние сокета. Обрабатывайте на прикладном уровне содержимое потока. Если это http-response то там есть хедеры и длина и прочее и содержимое (XML/Json).
    Ответ написан
  • Как не повторять весь код, если после условного оператора меняется сравнение?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Множитель (-1) или (+1) слева и справа от знака равно может перевернуть смысл сравнения.

    int m = choose == 1 ? 1 : -1;
    return m * ptr_array[13][j] > m * ptr_array[13][j + 1]
    Ответ написан
    Комментировать
  • Как транспонировать прямоугольную матрицу?

    mayton2019
    @mayton2019
    Bigdata Engineer
    На входе - матрица размром (l,c) на выходе после транспонирования размеры перевернутся и будет (c,l).

    UPD1: Ты аллоцировал матрицу А. Потом матрицу Б. И в конце удалил память только одной матрицы. Это небрежность?

    UPD2: Как-то так должно быть. Лишние параметры поудалял. Добавил матрицу Б. Где-то перевернул индексы.

    #include "stdio.h"
    #include "stdlib.h"
    
    double **input_matrix(int l, int c) {
        double **A = (double **) malloc(l * sizeof(double *));
        for (int i = 0; i < l; ++i) {
            A[i] = (double *) malloc(c * sizeof(double));
            for (int j = 0; j < c; ++j) {
                double x;
                scanf("%lf", &x);
                A[i][j] = x;
            }
        }
        return A;
    }
    
    double **trans_matrix(double **A, int l, int c) {
        double **B = (double **) malloc(c * sizeof(double *));
        for (int i = 0; i < c; ++i) {
            B[i] = (double *) malloc(l * sizeof(double));
        }
        for (int i = 0; i < c; ++i) {
            for (int j = 0; j < l; ++j) {
                B[i][j] = A[j][i];
            }
        }
        return B;
    }
    
    void print_matrix(double **A, int l, int c) {
        for (int i = 0; i < l; ++i) {
            for (int j = 0; j < c; ++j) {
                printf("%lf ", A[i][j]);
            }
            printf("\n");
        }
    }
    
    void free_matrix(double **A, int l) {
        for (int i = 0; i < l; ++i) {
            free(A[i]);
        }
        free(A);
    }
    
    int main() {
        int l, c;
        printf("Enter the number of lines: ");
        scanf("%d", &l);
        printf("Enter the number of column: ");
        scanf("%d", &c);
        
        double **A = input_matrix(l, c);
        printf("Matrix A\n");
        print_matrix(A, l, c);
    
        double **B = trans_matrix(A, l, c);
        printf("Matrix B\n");
        print_matrix(B, c, l);
    
        free_matrix(A, l);
        free_matrix(B, c);
        return 0;
    }
    Ответ написан
    Комментировать
  • Как считать из файла определенное слово, и посчитать сколько раз оно появляется в файле СИ?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Почему вопрос градуирован как "сложный"? Тебе нужен символьный буфер на 6 символов. Вот и пиши в него
    по кругу. Как только в круге появится ананас - вот и считай плюс один.

    Кстати где твоя попытка хоть написать привет-мир с файлами?
    Ответ написан
    Комментировать
  • Собственная функция возведения в степень Си?

    mayton2019
    @mayton2019
    Bigdata Engineer
    У тебя - рекурсия. Попробуй расчитать какой она глубины.
    Ответ написан
  • Как учить C++ если будешь знать С?

    mayton2019
    @mayton2019
    Bigdata Engineer
    то с какого аспекта или момента учить C++

    Нет такого момента или аспекта. Просто учишь и все. Языки похожи по синтаксису. Но начиная с каких-то 80х
    годов С++ стал отдельным форком и сегодня это два разных языка которые не должны быть под-множествами
    друг друга. Кроме С++ еще придется изучать и библиотеки STL/Boost и это отдельная тема.
    Ответ написан
    Комментировать
  • Как реализовать Алгоритм Брезенхэма?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Брезенхем не использует вещественные числа. В этом его суть. Вещественные появляются просто в ходе доказательства его правильности. Но сама реализация - только на целых числах.
    Ответ написан
    4 комментария
  • Быстро ли мое решение?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Измерение перформанса - это великое искусство. В данном конкретном приложении скорее всего узким местом будет не игры с массивами а конкретно печать на экране
    printf("%d\n", c[i][0]);
    поэтому из быстрых алгоритмов печать надо вышвырнуть. Или заменить ее на агрегацию результата или
    думать об асинхронных и параллельных операциях записи результата в файл если уж он так сильно нужен.

    Очень многие начинающие прокалываются на этом. Еще попробуй отказаться от индекса в массиве и заменить
    его на "подвижный" указатель по массиву. Часто бывает что умные компилляторы умеют распознавать такой шаблон но я-бы предложил написать две реализации и сравнить.

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

    mayton2019
    @mayton2019
    Bigdata Engineer
    Есть ли какая другая команда вывода, которая будет текст выводить только в терминал, без записи в файл?

    Да есть. Ты можешь выводить в STDERR и тогда это будет печататься на экране но в лог файл не попадет по причине такого скрипта
    ./a.out > file.log'
    Чтобы оба потока писались в лог - нужно делать так
    ./a.out 2>&1 > file.log'
    Но кажется что ты борешся не с той проблемой и не так. Для логгирования в файлы - есть специальные библиотеки.
    А работа с STDOUT/STDERR - это просто базовые абстракции любого Unix-процесса.
    Ответ написан
    4 комментария
  • Как найти область двумерного массива?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Серая область? Тут наверное 2 цикла надо.

    Либо обходить левый прямоугольник элементов и уже 2 линиями ограничить. Одна линия
    y = x и вторая - перевернутая y = -x и сдвинутая на вниз на SIZE. Тоесть y = -x + SIZE
    Ответ написан
    Комментировать
  • Как реализовать завершение игры "Жизнь" на Си?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Отвечу на первую часть вопроса
    Одно из условий остановки игры, если поле зацикливается.
    Но как это реализовать? Знаю способ, с запуском "скрытой" игры, которая будет течь в 2 раза быстрее, и сравнивать поле этой игры с полем оригинальной каждый ход. Затем на каком то моменте поля совпадут и с этого момента запустить сравнение по ходам со стартовым первоначальным полем. Когда совпадут, получается зациклилось.
    Но можно ли как-то попроще это реализовать?...


    Я не программировал Convay-s Life т.к. было не особо интересно. Но я наблюдал работу приложения Golly. Там можно было проводить сутки напролет в экспериментах, задавая различные конфигурации клеток и вот к чему я пришел.

    Невозможно докзать завершение игры просто так. Поле, даже небольшого размера может состоять из осцилляторов или ружей и пожирателей которые имеют разные периоды и могут сейчас не взаимодействовать друг с другом но внезапно пересечся через 10 000 эпох. Поэтому чтобы доказать что имеет место устойчивый период надо физически воспроизвести все эпохи.

    Короче клеточный автомат имеет свойства которые невыводимы из начальной конфигурации в общем случае.

    В частных случаях например когда вы знаете что такое глайдер и куда он полетит - то пожалуй можно. Но таких случаев будет мало.

    Нерешенные вопросы:
    1) Поле бесконечное? Как быть с конечными ресурсами оперативной памяти?
    2) Поле конечное? Уничтожаем клетки (глайдеры) которые вылетают за границу поля?
    3) Поле завернутое в тор (бублик)? Будем ли считать линейные трансформации поля - эквивалентными к исходному?

    Данные вопросы вобщем-то тоже влияют на проблему завершения жизни Конвея.

    По поводу идеи автора с удвоением времени. Может не сработать если период повтора не будет кратен двойке.
    По сути надо не сравнивать x и 2x эпоху. А записывать в базу данных все x - 1 эпох и проверять все-с-последней.
    Но такая сверх-задача невыполнима например с растущим бесконечным полем.

    Вторая часть вопроса не так интересна. Ее можно задать отдельным вопросом в habr.
    Ответ написан
    6 комментариев
  • Зачем нужно выравнивание памяти? Точнее, почему процессор обращается 2 раза к невыравниным данным?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Вопрос такой что отвечая на него можно новую книгу написать. Тут даже С не причем. А причем - архитектура процессора x86. Кстати тут еще надо кеш-линии рассмотреть. Это фокус такой. Что если тебе надо 1 байт прочитать
    из произвольного адреса, современная архитектура этого не умеет. Она читает (обычно) кусок памяти шириной в 64 байта. Это обзывается кеш-линия. И уже из нее будет прочитан нужный байт. Отвечающие верно сказали выше. Еще можно добавить такое (условное правило) что тип данных должен лежать в сегменте данных по адресу кратному самому размеру типа. Тоесть int должен лежат на адресах кратных 4, long - 8 байт и так далее. Вот насчет MMX/SSE не знаю.
    Ответ написан
    1 комментарий
  • Как сделать чтобы программа ждала завершения bat-файла?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Функция CreateProcess

    Если ты используешь Windows и С++ то тебе в первую очередь надо изучить какой API предоставляет ОС а уже потом язык.

    Вот пример как вызвать внешний процесс и ожидать завершения.

    https://docs.microsoft.com/en-us/windows/win32/pro...

    Кроме того. Ты должен не просто ждать завершения процесса но и взять код возврата. По нему определяется был ли успех или ошибка. Кроме того процесс возрващает 2 стрима. STDOUT, STDERR для детализации ошибок. Почитаешь сам по этому.

    А вот отсюда ты должен был начать поиски

    https://docs.microsoft.com/en-us/windows/win32/api...

    Насчет system не уверен. Это функция ОС Unix/Linux и ее вызов в Винде скорее всего будет просто обёрткой над CreateProcess. И какой там контроль над параметрами - чорт его знает. Наверное лучше брать native.
    Ответ написан
    1 комментарий
  • Почему inline функция не компилилируется?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Вот так у меня получилось
    #include <stdint.h>
    
    static inline uint32_t
    some_inline_func(uint32_t num) {
    
    }
    Ответ написан
    Комментировать
  • Как рандомизировать адреса функций в ELF-файле?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Так они не подряд идут. У них дистанция для первых двух - 112 байт. Далее 32. Упаковка. А ты что хотел? Чтоб бинарник был дырявый как сыр и имел 1 Гигабайт размером?
    Ответ написан
  • Как задать значение последней переменной?

    mayton2019
    @mayton2019
    Bigdata Engineer
    int64_t a = b/0
    Ответ написан
    Комментировать
  • Почему нет данных в хэш-таблице?

    mayton2019
    @mayton2019
    Bigdata Engineer
    А зачем здесь две звездочки?

    typedef struct hash_table {
      int count;
      int size;
      INFO** array;
    }HTAB;


    Мне кажется что 1 уровня вложенности достаточно (массив).
    Ответ написан
    Комментировать