C 中的数据类型数组?
An array of data types in C?
我有两种数据类型,它们具有不同大小的同名字段。我正在尝试根据传递给函数的参数来访问这些字段---比如
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;
}
然而,编译器根本不喜欢这样。我尝试了其他几种实现方式——但其中 none 行得通。位域大小的可变性使我无法尝试合并。这可行吗?
或者,如果我填充索引大小以确保它们的大小匹配(但它们的字段位置仍然不匹配)-- 这样可行吗?
在函数内部,您可以将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]++;
}
}
但是指针值本身并不携带它所指向的类型的信息。您需要一种机制来告诉程序它指向哪种类型。通常,这将通过函数参数的声明类型(使函数特定于该类型)来实现,但您可以通过单独的参数来传达它,如上一个示例所示。
我有两种数据类型,它们具有不同大小的同名字段。我正在尝试根据传递给函数的参数来访问这些字段---比如
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;
}
然而,编译器根本不喜欢这样。我尝试了其他几种实现方式——但其中 none 行得通。位域大小的可变性使我无法尝试合并。这可行吗?
或者,如果我填充索引大小以确保它们的大小匹配(但它们的字段位置仍然不匹配)-- 这样可行吗?
在函数内部,您可以将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]++;
}
}
但是指针值本身并不携带它所指向的类型的信息。您需要一种机制来告诉程序它指向哪种类型。通常,这将通过函数参数的声明类型(使函数特定于该类型)来实现,但您可以通过单独的参数来传达它,如上一个示例所示。