Есть ли макрос препроцессора C для распечатки структуры? - PullRequest
1 голос
/ 26 сентября 2011

Насколько я могу судить, в C .

нет способа распечатать значение структуры.

То есть, это не летает:

typedef struct {
    int a;
    double b;
} stype

stype a;

a.a=3;
a.b=3.4;

printf("%z", a);

вместо этого вы должны сказать:

printf("a: %d\n", a.a);
printf("b: %f\n", a.b);

Это похоже на идеальное место, где вы можете использовать макрос, чтобы сэкономить огромное количество печатания для произвольных структур.

Достаточно ли мощный препроцессор C для выполнения этого преобразования?

Ответы [ 6 ]

7 голосов
/ 27 сентября 2011

Я бы сделал два макроса, например:

#define STYPE_FMT "%d %f"
#define STYPE_MEMS(s) (s).a, (s).b

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

printf("hello %s, stype: " STYPE_FMT "\n", "world", STYPE_MEMS(my_s));

Что делает этот подход превосходящим «функцию печати» дляструктура состоит в том, что вы можете использовать макросы с любыми функциями printf -семейства, которые вам нравятся, и комбинировать печать других данных.

Вы можете стать еще интереснее и вместо этого сделать:1012 * и затем вы можете использовать точность по умолчанию или выбрать пользовательскую точность.

4 голосов
/ 26 сентября 2011

Я думаю, что самое простое решение (и, возможно, самое красивое) - это использовать функцию для печати вашей конкретной структуры.

void display_stype(stype *s)
{
    printf("a: %d\n", s->a);
    printf("b: %f\n", s->b);
}

Если ваша структура изменилась, вы можете легко адаптировать свой код в одном месте.

3 голосов
/ 26 сентября 2011

Достаточно ли силен препроцессор C для выполнения этого преобразования?

Да, это так, но тогда вам придется повторить всю декларацию структуры внутри макроса, что побеждает цель. Вы могли бы иметь что-то вроде этого:

STRUCT_PRINTF(
    a
  , ( int, a )
    ( double, b )
);

и тогда вам понадобится довольно сложная реализация такого макроса с большим количеством вспомогательных макросов / функций.

3 голосов
/ 26 сентября 2011

Нет, препроцессор C - это в основном инструмент для замены текстовых макросов. Он не знает о типах и структурах C.

1 голос
/ 26 сентября 2011

Вы не можете перебирать элементы структуры в C, ни динамически, ни статически (ни в C ++).В C. нет отражения.

Таким образом, нет способа заставить препроцессор выполнить это преобразование.

0 голосов
/ 23 мая 2018

Вы можете сделать макрос для этого:

#define PRINT_MEMBER(M) do {printf(#M": %d\n", (int) M;} while(0)

и затем напечатать его так:

PRINT_MEMBER(a.a);
PRINT_MEMBER(b->b);

Вы можете определить несколько из них, чтобы охватить различные типы (например, float,удваивается, печатать как шестнадцатеричное).К сожалению, нет хорошего обходного пути для этого, так как препрекоссор C не имеет представления о том, что такое типы, например, вы не можете использовать что-то вроде switch(typeof(M)) { case int: printf(.."%d"..; break; ...}.

...