Ответы пользователя по тегу C
  • Для чего нужен return?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    float del (float a, float b)
    {
        float res;
        ...
        res = ...;
        ....
        return res;
    }
    ....
    float result = del (num1, num2);

    что делает "return res" во втором куске кода? То есть в переменную res записывается деление числа А и Б. А потом оно куда-то там возвращается..

    Это значение, которое вернётся из функции в точку вызова. В примере выше оно будет присвоено переменной result.
    Ответ написан
    Комментировать
  • Почему не работает код на Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    while(s>=0,0001)

    -- тут записан бесконечный цикл. Потому что условие while всегда имеет значение 1. Потому что это не сравнение s с 0.0001, а два выражения связанные оператором "запятая" -- s >= 0 и 0001.
    Ответ написан
    Комментировать
  • Как программно реализовать текстовый протокол SCPI на микроконтроллере?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Подскажите как можно реализовать программно текстовый протокол SCPI?
    Есть синонимы команд, есть не обязательные параметры, параметры могут быть, могут не быть, может быть сразу несколько. Как это всё обрабатывать и проверять не пытается ли пользовать ввести несуществующую команду?

    На мой взгляд, проще всего воспользоваться связкой генератор парсеров + лексический анализатор, bison + flex. Описать грамматику языка на языке bison, описать допустимые лексемы на языке flex, скомпилировать и получить парсер для этого языка на C.
    Ответ написан
    Комментировать
  • Как быстро найти остаток от суммы цифр?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если первым параметром дать большое число, то программа выполняется очень долго.

    А если вместо суммирования чисел воспользоваться формулой суммы арифметической прогрессии n * (n + 1) / 2 ?
    Насколько велико "большое число"?
    Ответ написан
    1 комментарий
  • "Нечитаемый" код?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    for(char* pnew_char = new_char; *pnew_char++ = *--pchar;);

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

    for(; *pchar; ++length, ++pchar);

    Делать так (писать цикл с пустым телом и точкой с запятой на той же строке) не стоит, потому что легко не заметить эту точку с запятой или её отсутствие.

    for(char* pnew_char = new_char; *pnew_char++ = *--pchar;);

    Так делать (писать тело цикла в его поле для условия выхода, равно как и писать его в последнем поле) не стоит, потому что всему своё место, а ошибку в этом цикле ты уже допустил.
    Ответ написан
    7 комментариев
  • Как вывести символ через канал?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В каком месте может быть ошибка?

    man pipe: писать можно только в fd[1], читать -- только из fd[0].
    Канал однонаправленный, т.е. для двунаправленной коммуникации нужно открывать два канала.
    Должно быть так:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h> 
    
    int main(int argc, char **argv) {
    
            int fd0[2], fd1[2], n;
            char c;
            pipe(fd0);
            pipe(fd1);
    
            if (!fork()) {
                    close(fd0[0]);
                    close(fd1[1]);
    
                    write(fd0[1], "c", 1);
    
                    sleep(1);
    
                    if ((n = read(fd1[0], &c, 1)) != 1) {
                            printf("Дочерний процесс. Результат чтения: %d\n", n);
                            exit(0);
                    }
    
                    printf("Дочерний процесс прочитал: %c\n", c);
                    exit(0);
            }
            close(fd1[0]);
            close(fd0[1]);
                                                                                                                                                                                                                                                                              
            write(fd1[1], "p", 1);
            if ((n = read(fd0[0], &c, 1)) != 1) {
                    printf("Родительский процесс. Результат чтения: %d\n", n);
                    exit(0);
            }
    
            printf("Родительский процесс прочитал: %c\n", c);
            exit(0);
    
            return 0;
    }
    Ответ написан
    3 комментария
  • Что есть структура, а что оператор в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В стандарте языка используются термины "expression" (например, printf("something\n"), без точки с запятой -- это expression, а именно вызов функции) и "statement" (например if (expression) statement -- это statement), а иногда expression может быть statement'ом (например, printf("something\n");, с точкой с запятой), это называется "expression statement".

    "expression" обычно переводится как "выражение" и не вызывает трудностей. Со "statement" сложнее. Мне нравятся переводы "конструкция" ("конструкция if", "конструкция switch") или "инструкция" ("инструкция goto", "инструкция return").


    Как называть по-человечески строчки:
    if ( a > b )
      printf("something\n");

    Конструкция if с единственной инструкцией-выражением.

    А такое:

    if(condition) {
      printf("something1\n");
      printf("something2\n");
    }

    Конструкция if с составной инструкцией содержащей две инструкции-выражения.
    Ответ написан
    2 комментария
  • Почему условие if ( a == a) может не выполняться для Embedded-разработки?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    float b;
    ...
    if (b == b)

    Не выполняется тогда и только тогда, когда в b -- NaN.

    Обоснование есть в стандарте: пункт стандарта C99 6.2.6.1:4 говорит:
    Two values (other
    than NaNs) with the same object representation compare equal, but values that compare
    equal may have different object representations.
    .
    Ответ написан
    Комментировать
  • Как выделить память для строки неизвестной длины?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как это усовершенствовать?


    Из man scanf:
    An optional 'm' character. This is used with string conversions (%s, %c, %[), and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buffer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be initialized before the call). The caller should subsequently free(3) this buffer when it is no longer required.

    Т.е.:
    #include <stdio.h>
    
    int main()
    {
      char *chars;
      scanf("%m[^\n]",&chars);
      printf("%s\n", chars);
    }
    Ответ написан
    Комментировать
  • Как разобраться с указателем на указатель на массив?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Что происходит в данном случае
    int ** ptr = &arr;

    Происходит initialization from incompatible pointer type.

    Получается что далее ptr == arr == &arr

    == использованное в смысле "численно равно" действительно имеет место. Но типы этих трёх значений разные: int **/int[4]/int (*)[4]

    Почему нельзя получить указатель на указатель на массив в данном случае?

    Потому что, чтобы получить указатель на указатель, надо этот второй указатель иметь. Массив -- это не указатель.
    Вот так будет работать:
    #include <stdio.h>
    
    int main(void)
    {
      int arr[4] = {1, 2, 3, 4};
      int *pa = arr;
      int ** ptr = &pa;
    
      printf("%d", **ptr); // 1
      return 0;
    }
    Ответ написан
    Комментировать
  • Почему выводится некорректное значение вещественного числа?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему если считывать число как long double, то результат получается нормальным,
    input 2 => output 8.000000 (%lf)

    потому что в scanf %lf -- это не long double, а просто double. %f -- это float, а long double -- это %Lf. См. man scanf.
    float и double обычно отличаются форматом представления, поэтому если вводить число не тем форматом scanf, то и значение получится не то, что ожидалось.
    Ответ написан
    Комментировать
  • Какой стандарт языка Си наиболее распространён для создания программ под настольные ОС?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почитал, что ядро Linux использует стандарт C90,

    c99 в линуксе используется.

    хотелось бы писать на K&R C

    Это пройдёт.

    Какой стандарт наиболее поддерживаемый сейчас и распространён среди программистов под настольные ОС

    в мире gcc и clang уже несколько лет по умолчанию выбран c11, а в виндовый cl вроде до сих пор не завезли c99.
    Ответ написан
    1 комментарий
  • Ошибка подключения заголовочного файла Си (в чем)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    при компиляции файла copy.c вылетают ошибки
    In function `main':
    copy.c:(.text+0x67): undefined reference to `usageErr'
    copy.c:(.text+0xb6): undefined reference to `errExit'
    copy.c:(.text+0x122): undefined reference to `errExit'

    Это ошибки линковки а не компиляции. Файл copy.c скомпилировался нормально.
    Чтобы слинковалось нужно линковать с error_functions.o:
    gcc copy.c error_functions.c -o copy
    Ответ написан
    3 комментария
  • Проблема с кодом на Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Кто может объяснить как исправить если можно развернуто

    5b904eba4b1b1968222548.png
    Ответ написан
    2 комментария
  • Почему в С можно изменить константный символьный массив?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему в С допускают такое?

    То что у вас написано квалифицируется стандартом как Undefined behavior (с99 6.7.3:5):

    If an attempt is made to modify an object defined with a const-qualified type through use
    of an lvalue with non-const-qualified type, the behavior is undefined.


    Почему технически можно так сделать и этот код работает -- потому что массив string имеет автоматическое время жизни и компилятор помещает его на стек. Т.е. память фактически не является константной.

    Почему функция strchr принимает const char *, а возвращает char *? Чтобы показать, что сама она свой аргумент не изменяет, но чтобы не заставлять всех её пользователей делать приведение типа у результата. Я бы сказал, что проблема в этой функции, но она настолько старая, что никто не будет чинить её прототип.

    В С++ можно было бы решить эту проблему предоставив два перегруженных варианта strchr -- char *strchr(char *, char) и const char *strchr(const char *, char), но в С нет перегрузки функций.
    Ответ написан
    5 комментариев
  • Почему данный вызов функции realloc генерирует исключение?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    куда тут копать то можно? что за дичь?

    Вероятно, поломал кучу. Копать в сторону валидации использования памяти -- valgrind, asan, duma, electric fence, итд.
    Ответ написан
    Комментировать
  • Почему имени массива нельзя "присваивать" новое значение?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    arr это же просто указатель.

    Нет, arr -- это имя массива. В языке С указатели и массивы -- разные концепции.

    Почему нельзя сменить его значение что бы он указывал на новый адрес

    Потому что это не предусмотрено языком в таком контексте как у вас. А вот в таком контексте -- можно:
    void f(int arr[])
    {
        arr = arr + 1;
    }


    И почему нельзя создавать массивы (не символьные) в стиле указателей?
    int * arr = {1, 2, 3, 4, 5}; // ne ok


    В с99 и далее -- можно:
    int * arr = (int []){1, 2, 3, 4, 5}; // ok
    Ответ написан
  • В чем ошибка в сортировке выбором?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    при компиляции не пишет ничего...
    int array[n];

    Вот тебе несколько вопросов на подумать:
    - где в этой программе определена переменная n?
    - что делает конструкция int array[n], если n -- это переменная?
    - как связано выделение памяти для int array[n] и ввод значения n через scanf?
    Ответ написан
    1 комментарий
  • Почему константа π выводится не полностью?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему константа π выводится не полностью?

    Иррациональное число же, невозможно вывести полностью при современном уровне технологии.
    Ответ написан