Каковы самые полезные новые возможности в C99? [закрытый]

C99 был вокруг больше 10 лет, но поддержка его была медленным прибытием, таким образом, большинство разработчиков придерживалось C89. Даже сегодня я иногда мягко удивляюсь, когда я сталкиваюсь с функциями C99 в коде C.

Теперь, когда большинство главных компиляторов поддерживает C99 (MSVC, являющийся существенным исключением и некоторыми встроенными компиляторами, также отставая), я чувствую, что разработчики, которые работают с C, вероятно, должны знать о том, какие функции C99 доступны им. Некоторыми функциями являются просто типичные функции, которые никогда не стандартизировались прежде (snprintf, например), или знакомы от C++ (гибкое размещение объявления переменной или одна строка // комментарии), но некоторые новые возможности были сначала представлены в C99 и незнакомы многим программистам.

Что Вы находите самыми полезными новыми возможностями в C99?

Для ссылки, стандарт C99 (маркированный как проект, но идентичный обновленному стандарту, насколько я знаю), список новых возможностей и состояние реализации GCC C99.

Одна функция на ответ; не стесняйтесь оставлять несколько ответов. Примеры короткого кода, демонстрирующие новые возможности, поощряются.

78
задан 7 revs 18 September 2010 в 22:39
поделиться

15 ответов

Возможность объявления переменных в местах, отличных от начала блока.

41
ответ дан 24 November 2019 в 10:20
поделиться

Поддержка однострочных комментариев, начинающихся с // .

51
ответ дан 24 November 2019 в 10:20
поделиться

Сложные буквы. Установка структур по члену такова, что '89 ;)

Можно также использовать их для получения указателей на объекты с автоматической длительностью хранения без объявления ненужных переменных, например

foo(&(int){ 4 });

insteand

int tmp = 4;
foo(&tmp);
29
ответ дан 24 November 2019 в 10:20
поделиться
121 --- 1371322-

Переменная длина массивов:

int x;
scanf("%d", &x);
int a[x];
for (int i = 0; i < x; ++i)
    a[i] = i * i;
for (int i = 0; i < x; ++i)
    printf("%d\n", a[i]);
51
ответ дан 24 November 2019 в 10:20
поделиться

Поддержка встроенных функций .

18
ответ дан 24 November 2019 в 10:20
поделиться

Лично, мне нравится признание IEC 60559: 1989 (двоичная арифметика с плавающей точкой для микропроцессора Системы) и гораздо лучшая подставка с плавающей точкой.

В аналогичной вене, установке и запросе режима округления с плавающей точкой, проверка нан / бесконечности / субнормальных чисел и т. Д., Здорово иметь.

9
ответ дан 24 November 2019 в 10:20
поделиться

Это очень распространенная проблема при работе с классовым загрузчиком. Это часто наблюдается в приложениях Java EE, когда вы перестраиваете hibernate/cglib. Для получения дополнительной информации проверьте

http://opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won%27t+let+go

-121--2316269-

Кроме однозначной ясности, почему мы должны придерживаться: car.getSpeed () и car.setSpeed (55) когда это также может быть использовано: car.speed () и car.speed (55)

Поскольку во всех языках, с которыми я сталкивался, car.speed () и car.speed (55) одинаковы с точки зрения синтаксиса. Просто глядя на них так, оба могут вернуть значение, что не верно для последнего, если он должен был быть установщиком.

-121--2771376-

Шестнадцатеричные плавающие константы точки ( 0x1.8p0f ) и спецификаторы преобразования (% a , % A ). Если вы часто имеете дело с низкоуровневыми числовыми деталями, это огромное улучшение по сравнению с десятичными литералами и преобразованиями.

Они избавляют вас от беспокойства по поводу округления при задании констант для алгоритма и чрезвычайно полезны для отладки низкоуровневого кода с плавающей запятой.

12
ответ дан 24 November 2019 в 10:20
поделиться

Я думаю, что новые механизмы инициализатора чрезвычайно важны.

struct { int x, y; } a[10] = { [3] = { .y = 12, .x = 1 } };

ОК - не убедительный пример, но нотация является точной. Вы можете инициализировать определенные элементы массива и конкретных членов структуры.

Может быть, лучший пример будет это - хотя я признаю, что это не безумно убедительно:

enum { Iron = 26, Aluminium = 13, Beryllium = 4, ... };

const char *element_names[] =
{
    [Iron]      = "Iron",
    [Aluminium] = "Aluminium",
    [Beryllium] = "Beryllium",
    ...
};
66
ответ дан 24 November 2019 в 10:20
поделиться

Я так используется для ввода

for (int i = 0; i < n; ++i) { ... }

в C ++, что это боль в использовании Компилятор не C99, где я вынужден сказать

int i;
for (i = 0; i < n; ++i ) { ... }
77
ответ дан 24 November 2019 в 10:20
поделиться

Вариадические макросы. Облегчает генерацию кода котельной с неограниченным количеством аргументов.

36
ответ дан 24 November 2019 в 10:20
поделиться

Тип BoOL.

Теперь вы можете сделать что-то в этом роде:

bool v = 5;

printf("v=%u\n", v);

будет печать

1
25
ответ дан 24 November 2019 в 10:20
поделиться

snprintf() - серьезно, это стоит того, чтобы иметь возможность делать безопасные отформатированные строки.

34
ответ дан 24 November 2019 в 10:20
поделиться

Впервые через внешнюю петлю внутренняя петля становится бесконечной петлей. Неважно, что происходит после этого. Там нет «после бесконечности».

-121--3758882-

Диапазон (N) начинается с 0 , а не 1 . 0 * J всегда будет меньше n .

-121--3758881-

Поддержка escape escape Unicode:

printf("It's all \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC to me.\n");

или четные, буквальные символы Unicode:

printf("日本語\n");

(Примечание: может не работать в зависимости от вашего языка; портативная поддержка для разных кодировщиков примет больше, чем это )

15
ответ дан 24 November 2019 в 10:20
поделиться

stdint.h , который определяет int8_t , uint8_t и т. Д. Больше не нужно делать не портативные предположения о том, насколько широки есть ваши целые числа.

uint32_t truth = 0xDECAFBAD;
72
ответ дан 24 November 2019 в 10:20
поделиться

Гибкие члены массива.

6.7.2.1 Структура и союзные специфика

как особый случай, последний элемент структуры с более чем одним названным членом может иметь неполный тип массива; Это называется элементом массива . Благодаря двум исключением элементом массива FL ISPLACE игнорируется. Во-первых, размер структуры должен быть Равно к смещению последнего элемента иначе идентичной структуры, которая заменяет элемент MARAL ARM с массивом невырасных длины) вторым, когда . (или -> ) Оператор имеет левый операнд (указатель на) структуру с элементом MARAL ARMAL и именами правильного операнда, который он ведет себя так, как если бы этот член был заменен самый длинный массив (с тем же типом элемента), который не сделает структуру больше, чем доступ к объекту; Смещение массива должно оставаться таким элементом MARAL MARY, даже если это будет отличаться от уровня замены массива. Если этот массив не будет никаких элементов, он ведет себя так, как будто у него был один элемент, но поведение не является, если какая-либо попытка доступа к этому элементу или для генерации указателя одного прошлого Это.

Пример:

typedef struct {
  int len;
  char buf[];
} buffer;

int bufsize = 100;
buffer *b = malloc(sizeof(buffer) + sizeof(int[bufsize]));
29
ответ дан 24 November 2019 в 10:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: