11

是否可以将 C 数据类型存储在变量中?

像这样的东西:

void* type = (byte*);

这是一个场景,我编写了一个测试用例,并尝试使用某些数据类型打印出一个字节数组,以便在 printf 中使用,具体取决于给定的参数:

void print_byteArray(const void* expected, size_t size, 
        bool asChars, bool asWCharT) {
    int iterations;
    char* format;
    if (asChars) {
        iterations = (size / (sizeof (char)));
        format = "%c";
    } else if (asWCharT) {
        iterations = (size / (sizeof (wchar_t)));
        format = "%lc";
    } else {
        iterations = (size / (sizeof (byte)));
        format = "%x";
    }
    int i;
    for (i = 0; i < iterations; i++) {
        if (asChars) {
            printf(format, ((char*) expected)[i]);
        } else if (asWCharT) {
            printf(format, ((wchar_t*) expected)[i]);
        } else {
            printf(format, ((byte*) expected)[i]);
        }
    }
    fflush(stdout);
}

这看起来像低效的代码。我想人们可以将 for 循环体缩小为一行:

printf(format, ((type) expected)[i]);
4

2 回答 2

15

不,没有这样的类型可以在标准 C 中存储类型。

gcc 提供了一个typeof可能有用的扩展。使用这个关键字的语法看起来像sizeof,但该结构在语义上的行为类似于用 定义的类型名称typedef。详情见这里

更多的使用示例typeof

这用 x 指向的类型声明 y。

typeof (*x) y;

这将 y 声明为此类值的数组。

typeof (*x) y[4];

这将 y 声明为指向字符的指针数组:

typeof (typeof (char *)[4]) y;

它等价于以下传统的 C 声明:

char *y[4];

要查看使用 typeof 的声明的含义,以及为什么它可能是一种有用的编写方式,请使用以下宏重写它:

#define pointer(T)  typeof(T *)
#define array(T, N) typeof(T [N])

现在可以这样重写声明:

array (pointer (char), 4) y;

因此,array (pointer (char), 4)是 4 个指向 char 的指针的数组类型。

于 2013-07-15T00:42:36.700 回答
0

C 是一种静态类型语言,因此您必须构建自己的运行时类型系统。但是,如果只想打印任意数据的值,可以使用printf's%s并使用临时字符串缓冲区。这将在您要打印的数据有界的某些情况下起作用:

#include <stdlib.h> /* EXIT_ */
#include <stdio.h>  /* *printf */

#define PRINT_BUFFERS (4)

struct Foo {
    int key;
    char value[32];
};

/** Assumes {key} is {[0, 99]} to comply with C90, otherwise use {snprintf}. */
static void Foo_to_string(const struct Foo *foo, char (*const a)[12]) {
    sprintf(*a, "%d%.9s", foo->key, foo->value);
}
/** This is more convenient, but lacks generality. */
static const char *Foo_to_static(const struct Foo *foo) {
    static char buffers[PRINT_BUFFERS][12];
    static unsigned n;
    char *const a = buffers[n];
    sprintf(a, "%d%.9s", foo->key, foo->value);
    n = (n + 1) % PRINT_BUFFERS;
    return a;
}

int main(void) {
    const struct Foo foo = { 42, "foo" }, bar = { 96, "bar" },
        baz = { 13, "baz_abcdefg" };
    /* This way is more general. */
    char a[12], b[12], c[12];
    Foo_to_string(&foo, &a);
    Foo_to_string(&bar, &b);
    Foo_to_string(&baz, &c);
    printf ("Foo: %s; Bar: %s; Baz: %s.\n", a, b, c);
    /* This way is convenient, but you have a max number of calls. */
    printf("Foo: %s; Bar: %s; Baz: %s.\n", Foo_to_static(&foo),
        Foo_to_static(&bar), Foo_to_static(&baz));
    return EXIT_SUCCESS;
}
于 2017-10-06T00:11:15.887 回答