C中的数据类型数组?

时间:2017-05-31 17:53:22

标签: c user-defined-data-types

我有两种数据类型,它们具有不同大小的同名字段。我试图根据我传入函数的参数来访问这些字段---比如说

struct smallindex
{
   unsigned char index;
   unsigned int count;
};
struct largeindex
{
   unsigned int index;
   unsigned long count;
};

这可能不是理想的事情 - 但实现这一点的一种方法是让函数将指针视为不同大小的指针。比如说:

void function(int index, void *ptr)
{
   array[] = {struct smallindex, struct largeindex};
   array[index] *pointer = *ptr;
   *pointer[1].index++;
   return;
}

然而,编译器完全不喜欢这个。我尝试了其他几个实现 - 但是没有一个实现。位域大小的可变性使我无法尝试联合。这可行吗?

或者,如果我填充索引大小以确保它们的大小匹配(但它们的字段位置仍然不匹配) - 那么这可行吗?

1 个答案:

答案 0 :(得分:2)

在函数内部,您可以将ptr转换为类型char *int *,或指向结构或联合类型的指针,但每个指针都指向一种类型。如果结果无法与指针类型正确对齐,则此类转换会产生未定义的行为,但在转换为ptr实际指向的对象类型时不会发生这种情况。

此外,您可以通过字符类型指针(char *unsigned char *等)自由访问任何对象表示的字节。但是,如果尝试通过指向不同,不兼容类型的对象的指针来访问对象,则会产生未定义的行为。访问指向对象是将指针转换为不同指针类型的单独考虑因素。

因此,您可以这样做:

void function(int index, void *ptr) {
    // treat `ptr` as pointing to the first element of an array of int
    int *pointer = ptr;
    pointer[index]++;  // UB here if ptr really points to something other than int
}

和此:

void function(int index, void *ptr) {
    // treat `ptr` as pointing to the first element of an array of char
    char *pointer = ptr;
    pointer[index]++;
}

甚至这个:

void function(int index, void *ptr, _Bool is_int_ptr) {
    // Treat ptr as pointing to char or int depending on the value of is_int_ptr
    if (is_int_ptr) {
        int *pointer = ptr;
        pointer[index]++;
    } else {
        char *pointer = ptr;
        pointer[index]++;
    }
}

但指针值本身并不包含它指向哪种类型的信息。您需要一种机制来告诉程序它指向哪种类型。通常,这将通过函数参数的声明类型(使该函数特定于该类型),但您可以通过单独的参数传达它,如上例所示。