Задать вопрос
Ответы пользователя по тегу C
  • На каких правилах основана шестнадцатеричная нотация в printf для вещественных чисел?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Где можно почитать почему так происходит, почему такие разные вариации записи одно числа в шестнадцатеричной системе исчисления?

    Разве что в спецификации использованной библиотеки языка C. Потому что в стандарте явно сказано, что первая цифра в таком представлении -- unspecified:
    A double argument representing a floating-point number is converted in the
    style [−]0xh.hhhh p±d, where there is one hexadecimal digit (which is
    nonzero if the argument is a normalized floating-point number and is
    otherwise unspecified) before the decimal-point character...
    Ответ написан
    Комментировать
  • Почему fgets не работает второй раз?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char str1[5];
      char str2[3];
    
      fgets(str1,5,stdin);
      fgets(str2,3,stdin);

    Я ожидаю, что при запуске введу слово из 5 букв, потом слово из 3

    Чтение man fgets легко отвечает на этот вопрос:
    fgets() reads in at most one less than size characters from stream
    and stores them into the buffer pointed to by s.
    Reading stops after an EOF or a newline.
    If a newline is read, it is stored into the buffer.

    Т.е. чтобы прочитать ровно 5 и ровно 3 символа, нужно вызывать fgets с аргументом размера 6 и 4 соответственно. Кроме того, когда первая строка заканчивается символом конца строки, этот символ тоже должен быть считан. Т.е. 7 и 5.
    Ответ написан
    1 комментарий
  • Почему не выводится матрица?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    void readm(int N, int* X, FILE * dat)
    ... 
      int *X = nullptr;
      readm(N, X, dat);
    ...
      writem(N, X, res);

    Потому что ни N ни X внутри main не меняются, потому что их новое значения не возвращаются из функции readm.
    Минимальное изменение с которым всё заработает:
    void readm(int& N, int*& X, FILE * dat)
    Ответ написан
    2 комментария
  • Как правильно прервать поток в Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Общее правило при работе с потоками, не специфичное для С или pthreads: состояние резделяемое между потоками должно быть или атомарным или должно быть защищено примитивом синхронизации.
    Код функции thread_process никак не гарантирует, что компилятор не выкинет проверку !quit, потому что quit не меняется в этой функции и в функциях вызываемых из неё.

    Учитывая, что атомарность и потоки вошли в стандарт С11 имеет смысл смотреть туда.
    Если С11 недоступен, смотреть в pthread_mutex_*, pthread_cond_*, ...

    Может стоит вынести флаг в параметры потока

    По-хорошему -- да, стоит. Это, однако, ортогонально к синхронизации доступа.

    while(!quit) {
            if(difftime(time(NULL), last_cycle) > 30) {
                last_cycle = time(NULL);
                // Тут мои грязные дела
            }
        }

    Вместо busy wait лучше использовать sleep или что-нибудь типа pthread_mutex_timedlock/pthread_cond_timedwait.

    Я бы оформил код этого примера так:
    #include <sys/time.h>
    #include <pthread.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdio.h>
    
    struct thread1 {
        pthread_mutex_t lock;
        pthread_cond_t cond;
        bool quit;
    };
    
    static void* thread_process(void *p) {
        struct thread1 *arg = p;
    
        for (;;) {
            bool quit;
    
            pthread_mutex_lock(&arg->lock);
            if (!arg->quit) {
                struct timeval now;
                struct timespec ts;
    
                gettimeofday(&now, NULL);
                ts.tv_sec = now.tv_sec + 30;
                ts.tv_nsec = now.tv_usec * 1000;
                pthread_cond_timedwait(&arg->cond, &arg->lock, &ts);
            }
            quit = arg->quit;
            pthread_mutex_unlock(&arg->lock);
            if (quit)
                return NULL;
    
            // Тут мои грязные дела
        }
        return NULL;
    }
    
    int main() {
        pthread_t th;
        struct thread1 arg = {
            .lock = PTHREAD_MUTEX_INITIALIZER,
            .cond = PTHREAD_COND_INITIALIZER,
            .quit = false,
        };
        pthread_create(&th, NULL, thread_process, &arg);
    
        char cmd[16];
        while(true) {
            scanf("%s", cmd);
            if(!strcmp(cmd, "quit")) {
                pthread_mutex_lock(&arg.lock);
                arg.quit = true;
                pthread_cond_broadcast(&arg.cond);
                pthread_mutex_unlock(&arg.lock);
                break;
            }
            // остальные команды
        }
    
        pthread_join(th, NULL);
        return 0;
    }
    Ответ написан
    1 комментарий
  • Если к int добавить в конце точку без буквы f, то к какому типу будет произведено приведение?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    x = float(a) / 4.;

    Этот код не на С а на С++. В С++ тип выражения справа -- double, потому что это деление float на double. См. eelis.net/c++draft/lex.fcon
    Ответ написан
    Комментировать
  • Почему рандомные элементы массива заполняются мусором?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char **array;
    array = malloc(arr_len);
    
    for(unsigned long step = 0; step <= arr_len; step++)
    {
        array[step] =

    Потому что в этом коде две большие ошибки. Первая: памяти для массива указателей из arr_len элементов требуется не arr_len, а arr_len * sizeof(char *). Вторая: цикл выполняет не arr_len, а arr_len + 1 итерацию.
    Ответ написан
    3 комментария
  • Как получить данные от пользователя с пробелами простым способом (С)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    scanf("%[^\n]\n", name);
    man scanf
    Проблема с этим способом: нельзя ввести пустую строку.

    Либо, если нет желания использовать исключительно scanf -- fgets.
    Ответ написан
  • Фрагментированный ввод/вывод: быстрее ли стандартного?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    1. корреткно ли я делал замеры времени? (может есть какая библиотека на Си или прочее?).

    Я подозреваю, что ты замерил в основном время вывода в stdout, если он не был перенаправлен в файл.

    2. Правильно ли я инициализоровал сегменты ? (может есть упрощенная форма)

    Вполне.

    3. Как правильно подобрать размер сегмента?

    Размеры сегментов диктуются структурой читаемых данных. Если у данных нет структуры -- читай всё с помощью read в один большой массив.

    4. В каких случаях лучше использовать фрагментированный ввод/вывод? (любые советы по его использованию)

    Когда данные имеют чётко выраженную структуру и время выполнения системного вызова приближается ко времени требуемому для копирования данных. Переход с read на readv позволяет не заниматься копированием данных в юзерспейсе и сэкономить N-1 системный вызов при одновременном чтении N сегментов.
    Ответ написан
    Комментировать
  • Как создать указатель на функцию main?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    int main(void)
    {
        int (*pmain)(void) = main;
    }


    например int* func;

    Это указатель на int, а не на функцию.
    Ответ написан
    Комментировать
  • Почему код именно так работает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Символы повторяются из-за static?

    Не из-за static, а из-за того, что _itoa всегда возвращает один и тот же адрес. Попробуй так, зацени разницу:
    char *_itoa(int i) {
      static int slot;
      static char buf[10][2];
      slot = (slot + 1) % 10;
      buf[slot][0] = i + '0';
      buf[slot][1] = '\0';
      return buf[slot];
    }
    
    int main() {
    
      printf("%s + %s = %s", _itoa(2), _itoa(2), itoa(4));
      _getch();
    }
    Ответ написан
    Комментировать
  • Почему не срабатывает шеллкод?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    при компиляции флаг из реестра не удаляется. В чем может быть проблема?

    В том, что ты засунул бинарный код в параметр функции, в котором должна быть строка с именем программы для запуска и её параметрами. Непонятно, почему ты ожидаешь, что WinExec бросится выполнять машинный код в этой строке. WinExec имеет код возврата, который недвусмысленно тебе сказал бы в чём ошибка (путь или файл для запуска не найдены), если бы ты его проверил.
    И, кстати, байт с кодом 0 по смещению 0x246 -- это тоже часть шелл-кода, терминатор командной строки.

    Байты из зеленой области, как я понял, это информация линкера golink. Так ли это?

    Это заголовок файла формата PE. Да, его туда записал линкер. Нет, это не информация линкера, это информация в основном для загрузчика ОС, а так же для дизассемблера и прочих binutils.
    Ответ написан
    1 комментарий
  • Как вывести элементы матрицы, которые находятся ниже главной диагонали?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    int **matrix = (int**)malloc(matrix_size * sizeof(int));

    Должно стать
    int **matrix = (int**)malloc(matrix_size * sizeof(int *));

    потому что ты выделяешь массив указателей, а не массив целых чисел, а sizeof(int) вполне может быть не равно sizeof(int *).

    for (int i = 0; i < matrix_size; ++i)
        {
            for (int j = 0; j < matrix_size; ++j)
            {
                if(i > j)
                {
                    arr[i] = matrix[i][j];
                }
            }
        }


    Должно стать
    counter = 0;
        for (int i = 0; i < matrix_size; ++i)
        {
            for (int j = 0; j < matrix_size; ++j)
            {
                if(i > j)
                {
                    arr[counter++] = matrix[i][j];
                }
            }
        }


    потому что иначе все элементы находящиеся в одной строке matrix ты складываешь в один и тот же элемент массива arr.
    Ответ написан
    Комментировать
  • Сколько будут занимать места параметры в данном случае?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ума не приложу, почему размер void _stdcall foo(short a, short b); параметров равен 8

    Потому что аргументы размером меньше 4 байт расширяются до 4 байт. См.

    Как выяснилось, стек растет не только на 4 байта, а на 2.

    То, что в стек физически можно положить 2 байта (а можно ведь и 1, и 3 -- sub $imm, %esp) не означает, что это следует делать. См:
    The stack will always be maintained 16-byte aligned, except within
    the prolog (for example, after the return address is pushed), and except where
    indicated in Function Types for a certain class of frame functions
    Для венды на x86 я такого описания на том же сайте не нашёл, но точно выравнивание должно быть не меньше 4.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти по слову?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я не знаю, можно ли такого уровня детали найти для современных процессоров, а вот для i80386 в спецификации, в разделе 5.3.6 легко можно видеть, что невыравненный доступ к памяти занимает два цикла, вместо одного.
    За пределами мира x86 многие процессоры вообще не поддерживают доступ к невыравненным данным на аппаратном уровне.
    Ответ написан
    Комментировать
  • Какой тип данных будет более правильным?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    есть ли смысл использовать простые чар массивы формата char name[32] или динамические массивы char name[] в замену указателям с последующим выделением им памяти?

    Я думаю, что никто вам обоснованно не ответит на вопрос в такой постановке, поскольку нам ничего неизвестно о природе ваших данных.
    Утечки памяти можно искать valgrind'ом, это в большинстве случаев легко и приятно.
    Ответ написан
    Комментировать
  • Как тестировать драйвера?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Сразу скажу, комп у меня слабенький и ждать 3-4 часа чтоб понять что забыл в конце оператора точку с запятой поставить, это не хорошо?!

    При разработке необязательно использовать конфигурацию ядра со всеми включёнными опциями. Типичный конфиг который я использую при разработке собирается с нуля за 2 минуты.
    Кроме того, ядерный Makefile понимает цели вида *.o. Т.е. можно взять и откомпилировать один файл из дерева исходников ядра. Например: make init/main.o.
    Если ты меняешь что-то в исходниках, перекомпилироваться будет только то, что действительно зависит от того, что ты поменял. Поменяешь .c -- перекомпилируется единственный соответствующий ему файл .o.

    как можно тестировать компоненты ядра

    Это совсем другой вопрос. Под просто тестированием понимают проверку того, что код работает правильно, а не то, что он собрался.
    Ответ написан
    Комментировать
  • Error loading uncompressed kernel without PVH ELF Note ( osdev ) !?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    пытаюсь понять, почему qemu не хочет запускать ядро....


    Потому что это не заголовок multiboot, MAGIC тут взят из старой версии формата, а структура -- из версии 2:

    MAGIC equ 0x1BADB002
    ...
    grubBoot:
      dd MAGIC
      dd FLAGS
    ;	dd 0
      dd (end_grubBoot - grubBoot)
      dd -(MAGIC + FLAGS + (end_grubBoot - grubBoot))
    ;	dd -(MAGIC + 0 + (end_grubBoot - grubBoot))
      
    ;	dw 0
    ;	dw FLAGS
    ;	dd 8
    end_grubBoot:


    QEMU отлично понимает заголовок старого формата:

    MAGIC equ 0x1BADB002
    
      dd MAGIC
      dd FLAGS
      dd -(MAGIC + FLAGS)


    И с этим изменением твой код прекрасно загружается и выполняется:

    trace
    ...
    
    Trace 0: 0x7f2a71e084c0 [00000000/000caa1a/0xb0]
    ----------------
    IN:
    0x00102060:  9b                       wait
    0x00102061:  db e3                    fninit
    0x00102063:  bc 44 23 10 00           movl     $0x102344, %esp
    0x00102068:  53                       pushl    %ebx
    0x00102069:  50                       pushl    %eax
    0x0010206a:  e8 68 00 00 00           calll    0x1020d7
    
    Trace 0: 0x7f2a71e08800 [00000000/00102060/0xb0]
    ----------------
    IN:
    0x001020d7:  55                       pushl    %ebp
    0x001020d8:  89 e5                    movl     %esp, %ebp
    0x001020da:  68 00 10 10 00           pushl    $0x101000
    0x001020df:  e8 8d ff ff ff           calll    0x102071
    
    Linking TBs 0x7f2a71e08800 [00102060] index 0 -> 0x7f2a71e08a40 [001020d7]
    Trace 0: 0x7f2a71e08a40 [00000000/001020d7/0xb0]
    ----------------
    IN:
    0x00102071:  55                       pushl    %ebp
    0x00102072:  89 e5                    movl     %esp, %ebp
    0x00102074:  53                       pushl    %ebx
    0x00102075:  83 ec 10                 subl     $0x10, %esp
    0x00102078:  c7 45 f4 00 80 0b 00     movl     $0xb8000, -0xc(%ebp)
    0x0010207f:  c7 45 f8 00 00 00 00     movl     $0, -8(%ebp)
    0x00102086:  eb 35                    jmp      0x1020bd
    
    Linking TBs 0x7f2a71e08a40 [001020d7] index 0 -> 0x7f2a71e08c80 [00102071]
    Trace 0: 0x7f2a71e08c80 [00000000/00102071/0xb0]
    ----------------
    IN:
    0x001020bd:  8b 55 f8                 movl     -8(%ebp), %edx
    0x001020c0:  8b 45 08                 movl     8(%ebp), %eax
    0x001020c3:  01 d0                    addl     %edx, %eax
    0x001020c5:  0f b6 00                 movzbl   (%eax), %eax
    0x001020c8:  0f be c0                 movsbl   %al, %eax
    0x001020cb:  3b 45 f8                 cmpl     -8(%ebp), %eax
    0x001020ce:  7f b8                    jg       0x102088
    
    Linking TBs 0x7f2a71e08c80 [00102071] index 0 -> 0x7f2a71e08f00 [001020bd]
    Trace 0: 0x7f2a71e08f00 [00000000/001020bd/0xb0]
    ----------------
    IN:
    0x00102088:  8b 45 f8                 movl     -8(%ebp), %eax
    0x0010208b:  8d 14 00                 leal     (%eax, %eax), %edx
    0x0010208e:  8b 45 f4                 movl     -0xc(%ebp), %eax
    0x00102091:  01 d0                    addl     %edx, %eax
    0x00102093:  8b 55 f8                 movl     -8(%ebp), %edx
    0x00102096:  8d 0c 12                 leal     (%edx, %edx), %ecx
    0x00102099:  8b 55 f4                 movl     -0xc(%ebp), %edx
    0x0010209c:  01 ca                    addl     %ecx, %edx
    0x0010209e:  0f b7 12                 movzwl   (%edx), %edx
    0x001020a1:  89 d3                    movl     %edx, %ebx
    0x001020a3:  b3 00                    movb     $0, %bl
    0x001020a5:  8b 4d f8                 movl     -8(%ebp), %ecx
    0x001020a8:  8b 55 08                 movl     8(%ebp), %edx
    0x001020ab:  01 ca                    addl     %ecx, %edx
    0x001020ad:  0f b6 12                 movzbl   (%edx), %edx
    0x001020b0:  66 0f be d2              movsbw   %dl, %dx
    0x001020b4:  09 da                    orl      %ebx, %edx
    0x001020b6:  66 89 10                 movw     %dx, (%eax)
    0x001020b9:  83 45 f8 01              addl     $1, -8(%ebp)
    0x001020bd:  8b 55 f8                 movl     -8(%ebp), %edx
    0x001020c0:  8b 45 08                 movl     8(%ebp), %eax
    0x001020c3:  01 d0                    addl     %edx, %eax
    0x001020c5:  0f b6 00                 movzbl   (%eax), %eax
    0x001020c8:  0f be c0                 movsbl   %al, %eax
    0x001020cb:  3b 45 f8                 cmpl     -8(%ebp), %eax
    0x001020ce:  7f b8                    jg       0x102088
    
    Linking TBs 0x7f2a71e08f00 [001020bd] index 1 -> 0x7f2a71e091c0 [00102088]
    Trace 0: 0x7f2a71e091c0 [00000000/00102088/0xb0]
    Linking TBs 0x7f2a71e091c0 [00102088] index 1 -> 0x7f2a71e091c0 [00102088]
    Trace 0: 0x7f2a71e091c0 [00000000/00102088/0xb0]
    ----------------
    IN:
    0x001020d0:  90                       nop
    0x001020d1:  83 c4 10                 addl     $0x10, %esp
    0x001020d4:  5b                       popl     %ebx
    0x001020d5:  5d                       popl     %ebp
    0x001020d6:  c3                       retl
    
    Linking TBs 0x7f2a71e091c0 [00102088] index 0 -> 0x7f2a71e098c0 [001020d0]
    Trace 0: 0x7f2a71e098c0 [00000000/001020d0/0xb0]
    ----------------
    IN:
    0x001020e4:  83 c4 04                 addl     $4, %esp
    0x001020e7:  eb fe                    jmp      0x1020e7
    
    Trace 0: 0x7f2a71e09b00 [00000000/001020e4/0xb0]
    ----------------
    IN:
    0x001020e7:  eb fe                    jmp      0x1020e7
    
    Linking TBs 0x7f2a71e09b00 [001020e4] index 0 -> 0x7f2a71e09c40 [001020e7]
    Trace 0: 0x7f2a71e09c40 [00000000/001020e7/0xb0]
    Linking TBs 0x7f2a71e09c40 [001020e7] index 0 -> 0x7f2a71e09c40 [001020e7]
    
    ...


    Ещё непонятно, зачем такие игры с форматом kernel, можно было же напрямую:
    LDEMU=-melf_i386
    kernel: $(CSOURCES) $(NASMSOURCES) $(LDFILE)
            $(CC) $(CEMU) -std=c$(CSTD) -c $(CSOURCES) -ffreestanding -nostdlib -nostdinc -fno-pic
            $(ASM) $(NASMSOURCES)
            $(LD) $(LDEMU) --nmagic -T$(LDFILE) -o kernel *.o
    Ответ написан
  • Как отсортировать матрицу?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Мне нужна хотя бы идея как это можно реализовать

    Это можно реализовать функцией qsort. Матрицу хранить по столбцам а не по строкам.
    Ответ написан
    Комментировать
  • Как работать с комплексными числами в си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    VS пишет...

    в С89 нет complex.h, он появился в C99. VS не поддерживает С99. Следовательно complex.h который у тебя есть -- нестандартный. Надо смотреть в него, чтобы понять, как его использовать.
    (Подозреваю, что надо выкинуть слово double из определений переменных).
    Ответ написан
    Комментировать
  • Почему в программе утечка памяти?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Укажите на ошибки в коде

    Можно собрать программу с -g, и valgrind сам тебе укажет с точностью до строчки в исходниках, где была выделена утёкшая память.

    как мне вводить строку с неизвестной длинной?

    char *str = NULL;
    scanf("%m[^\n]", &str);
    Ответ написан
    5 комментариев