枚举C中的基本数据类型,以便于访问大小

Enumerate the basic data types in C so that the sizes can be easily accessed

是否可以使用 for 循环获取 C 中所有基本数据类型的大小?例如,我们可以做这样的事情吗?

#include <datatypes.h> /* or something else which defines get_data_types() */
#include <stdio.h>

int main() {
    for (int x = 0; x < len(get_data_types()); x++) {
        printf("Size of %s is %d", get_data_types()[x], sizeof(get_data_types()[x]));
    }
 }

我可以通过替换 for 循环并为 intlong 等编写单独的语句来枚举所有数据类型。但是,我想知道是否可以使用 for 循环来做同样的事吗?

基本上,我试图避免以下情况:

#include <stdio.h>

int main() {
    printf("Size of int is %d", sizeof(int);
    printf("Size of unsigned int is %d", sizeof(unsigned int);
    printf("Size of long is %d", sizeof(long);
    /* etc. */
    return 0;
}

感兴趣的数据类型 - char, unsigned char, signed char, int, unsigned int, short, unsigned short, long, unsigned long, float, double, long double

澄清:我不一定想要混合类型的数组,但能够枚举类型以便可以轻松访问大小。

不,这不可能。在 C 中无法自动列出所有类型。您必须为每种类型手动执行此操作。

但是,如果您经常使用这些信息,您总是可以提前准备一份清单。有一些方法可以做到这一点。这是一个:

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    int size;
} type;

int main()
{
    type types[3] = { {"int", sizeof (int) },
                      {"char", sizeof (char) },
                      {"double", sizeof (double) } };

    for (int x = 0; x<sizeof(types)/sizeof(types[0]); x++)
        printf("Size of %s is %d\n", types[x].name, types[x].size);
}

(代码根据下面 Paul Ogilvie 的回答进行了简化。)

在对此答案的评论中,您提出了以下问题:我们能否创建一个如下所示的数组:types_array = {"int", "char", "double", "long"} 并在迭代时得到相应的尺寸?我的意思是说使用一些函数 f,我们可以将 types[j].size 分配给 sizeof(f(types_array[j]))

简而言之,没有。这是因为 C 是一种强类型编译语言。在像 Python 和 PHP 这样的语言中,你可以做各种像那样的奇特的事情,但在 C 中不行。并非没有诡计。您示例中的函数 f 必须具有指定的 return 类型,这是 sizeof 将作为参数获取的类型。

绕过它的一种方法是编写自定义 sizeof:

int mysizeof(char * s) {
    if(strcmp(s, "char") == 0)
        return sizeof(char);
    if(strcmp(s, "int") == 0)
        return sizeof(int);
}

如果这个列表很长,你可以使用宏:

#define MYSIZEOF(x) if(strcmp(s, #x) == 0) return sizeof(x)

int mysizeof(char * s) {
    MYSIZEOF(int);
    MYSIZEOF(char);
    MYSIZEOF(double);
}

你的方法是不可能的,各种类型必须以某种方式显式枚举,但你可以制作一个结构数组,使用一个方便的宏来简单地初始化它并编写一个循环来输出所有标准类型尺码。

请注意,您忘记了一些有用的标准类型:

  • 更多整数类型:long longunsigned long longsize_tptrdiff_tintmax_tuintmax_twchar_t ...
  • 指针类型:void *char *int *...
  • 函数指针类型:void(*)(void)

这是一个实现:

#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>

#define TYPEDESC(t)  { #t, sizeof(t) }

static struct type_desc {
    const char *name;
    int size;
} const types[] = {
    TYPEDESC(char), TYPEDESC(unsigned char), TYPEDESC(signed char),
    TYPEDESC(wchar_t),
    TYPEDESC(short), TYPEDESC(unsigned short),
    TYPEDESC(int), TYPEDESC(unsigned int),
    TYPEDESC(long), TYPEDESC(unsigned long),
    TYPEDESC(long long), TYPEDESC(unsigned long long),
    TYPEDESC(float), TYPEDESC(double), TYPEDESC(long double),
    TYPEDESC(size_t), TYPEDESC(ptrdiff_t),
    TYPEDESC(intmax_t), TYPEDESC(uintmax_t),
    TYPEDESC(void *), TYPEDESC(char *), TYPEDESC(int *),
    TYPEDESC(void (*)(void)),
};

int main() {
    size_t i;
    for (i = 0; i < sizeof(types) / sizeof(types[0]); i++)
        printf("sizeof( %s ) = %d\n", types[i].name, types[i].size);
    return 0;
}

我的 64 位 OS/X 系统的输出是这样的:

sizeof( char ) = 1
sizeof( unsigned char ) = 1
sizeof( signed char ) = 1
sizeof( wchar_t ) = 4
sizeof( short ) = 2
sizeof( unsigned short ) = 2
sizeof( int ) = 4
sizeof( unsigned int ) = 4
sizeof( long ) = 8
sizeof( unsigned long ) = 8
sizeof( long long ) = 8
sizeof( unsigned long long ) = 8
sizeof( float ) = 4
sizeof( double ) = 8
sizeof( long double ) = 16
sizeof( size_t ) = 8
sizeof( ptrdiff_t ) = 8
sizeof( intmax_t ) = 8
sizeof( uintmax_t ) = 8
sizeof( void * ) = 8
sizeof( char * ) = 8
sizeof( int * ) = 8
sizeof( void (*)(void) ) = 8

令人惊讶的是 wchar_t 是 32 位,long double 是 16 字节长。这并不意味着 long double 值将所有 128 位用于浮点表示。 Windows 系统上的输出会非常不同。

Klutt 的回答可以稍微简化为:

struct {
    char *name;
    int size;
} types[] = {
    {"int", sizeof(int)},
    {"char", sizeof(char)},
    {"long", sizeof(long)}
    //.. etcetera
};

int main(void) {
    int i;
    for (i=0; i<sizeof(types)/sizeof(types[0]); i++)
        printf("sizeof %s = %d\n",types[i].name, types[i].size);
    return 0;
}