Задать вопрос
Ответы пользователя по тегу C
  • Что есть структура, а что оператор в 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
    Почему константа π выводится не полностью?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Объясните почему именно так, с умножение переполняется, а при сложении как будто просто отсекаются лишние биты.

    Потому что именно так и есть: для сложения числа приводятся к одному порядку. Порядок FLT_MAX -- 2^127, порядок 1.0 -- 2^0. Т.е. единица сдвигается на 127 разрядов вправо перед сложением с FLT_MAX. Ни в одном стандартном представлении чисел с плавающей точкой столько разрядов не предусмотрено, лишние разряды отсекаются, единица превращается в 0.

    Минимальное число, которое можно прибавить к FLT_MAX и получить бесконечность равно 2 ^ (127 - 24). При нормализации этого числа с FLT_MAX получается единица сдвинутая вправо на 24 разряда, как раз в последний значащий разряд мантиссы float.
    Ответ написан
    Комментировать
  • Почему компилятор выдает ошибку [Error] ld returned 1 exit status?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    undefined reference to `OpenRusEng'

    ld наверно прав: в приведённом коде действительно нет такой функции.
    Ответ написан
    Комментировать
  • Как улучшить код на Си(сделать "красивше")?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char num1[N];
      char num2[N];
      char num3[N];
      char *nums[3] = {num1,num2,num3};

    А чего не nums[3][N]?

    while(c=fgetc(in))

    Когда ты думаешь условие while перестанет выполняться?

    if ( c == '\n' || c == ' ' )

    Я бы добавил проверку на конец файла: if ( c == '\n' || c == ' ' || c == EOF)

    (*(nums+i))[j]

    А чего не nums[i][j]?

    int length(char s[]){

    Есть такая готовая функция strnlen из string.h

    maxNum не обрабатывает случай когда аргументы равны.
    Ответ написан
    8 комментариев
  • Что именно происходит в Ардуино при попытке записи слишком большого числа?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Откуда диапазон значений, тоже понятно. Но что конкретно происходит при попытке выйти за этот диапазон?
    Почему при вычислении степеней двойки в какой-то момент выводится минимальное значение, -32768, а затем - одни нули?

    Точно понятно?

    2^0 == 0b0000000_00000001 == 1 (16 младших разрядов)
    ...
    2^14 == 0b01000000_00000000 == 16384 (16 младших разрядов)
    ...
    2^15 - 1 == 0b01111111_11111111 == 32767 (16 младших разрядов)
    2^15 == 0b100000_00000000 == -32768 (16 младших разрядов)
    2^15 + 1 == 0b100000_00000001 == -32767 (16 младших разрядов)
    ...
    2^16 - 1 == 0b11111111_11111111 == -1 (16 младших разрядов)
    2^16 == 0b1_00000000_00000000 == 0 (16 младших разрядов)
    2^16 + 1 == 0b1_00000000_00000001 == 1 (16 младших разрядов)

    Что происходит при других операциях со слишком большими числами?

    Неопределённое поведение, если тип значения знаковый. Компилятор может наоптимизировать что захочет.
    Если тип значения беззнаковый -- результат обрезается по ширине типа данных результата.
    Ответ написан
    Комментировать
  • C - Как сделать отдельную функцию под ввод массива с клавиатуры и функцию под вывод?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    составить две функции, вызывающиеся в main - функцию ввод массива определенной длины n, и функцию вывод массива в консоль

    1) понять, что эти функции будут принимать и что возвращать
    2) перенести код ввода в первую функцию
    3) написать вторую функцию
    Ответ написан
    Комментировать
  • Как включить в статическую библиотеку все зависимости из других стат.библиотек в CMake проекте?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Проект создаёт статическую библиотеку mylib, но в неё не включена требуемая реализация boost, то есть при линковке приложения с mylib нужно явно указывать, что нужно линковать boost.

    Так обычно библиотеки и делают -- ни одна нормальная библиотека не тащит с собой часть другой.
    А вот для того, чтобы указать, что у библиотеки есть зависимости используют pkg-config. Такая библиотека устанавливает в системе свой архив (*.a), свои заголовочные файлы (*.h) и описание для pkg-config (*.pc). Пользователь библиотеки вызывает pkg-config --libs <имя библиотеки>и получает список ключей для линковки.
    Ответ написан
    Комментировать