这不是“如何将混合数据类型(int、float、char 等)存储在数组中?”问题请仔细阅读! 假设我有以下 void 指针,直到运行时我才知道它的类型:
void* data;
现在,当我知道 data
的类型时,我知道我可以执行以下操作(例如 int
):
int typed_data = *(int*)data;
使用 switch case
语句我可以检查一个变量来确定要执行的转换:
switch(type_id) {
case INT:
int typed_data = *(int*)data;
break;
case FLOAT:
float typed_data = *(float*)data;
break;
// ...
// etc.
}
但是,这样我将无法访问 switch block 之外的 typed_data,请考虑以下功能作为示例;它需要两个void指针,并根据type_id
的值,它会转换 s
和x
更正数据类型,然后使用新定义的类型化数据执行其他操作:
int sequential_seach(int n, void* s, void* x, type_id) {
int location = 0;
switch(type_id) {
case INT:
int *list = s;
int element = *(int*)x;
break;
case FLOAT:
float *list = s;
float element = *(float*)x;
break;
// ...
// etc.
}
while(location < n && list[location] != element) { // <---This will cause a compile error
location++;
if(location > n - 1) {
location = -1;
}
}
return location;
}
在上面的函数中location
和list
无法在 swtich
之外访问 block ,即使 type_id 匹配 case
之一值并且它们被定义,它们仍然超出范围,在 switch
之外 block ,因此当编译器到达 while
行时居住,它提示 location
和list
没有定义。但函数需要这些类型变量。那么如何解决这个问题呢?我应该复制粘贴 while
阻止每个 case
?这看起来不是一个很好的解决方案。如果我有一个较长的代码,需要在 100 个不同的地方使用这些变量怎么办?
最佳答案
听起来您需要泛型:使用编译时类型参数定义函数的能力。
不幸的是,C 本身没有泛型。幸运的是,you can use macros as pseudo-generics使预处理器自动生成代码的多个版本。
改编自链接的答案:
// sequential_search.h
/* Provide some helpers that generate a name of the form of sequential_search_T,
unique for each type argument */
#define TOKENPASTE(x, y) x ## y
#define SEQ_SEARCH(T) TOKENPASTE(sequential_search_, T)
/* Provide the generic type definition of your function */
int SEQ_SEARCH(TYPE) (int n, void* s, void* x) {
int location = 0;
TYPE* list = s;
TYPE element = *(TYPE*)x;
while(location < n && list[location] != element) {
location++;
if(location > n - 1) {
location = -1;
}
}
return location;
}
为您打算传递的每个类型参数实例化一次:
// sequential_search.c
#define TYPE int
#include "sequential_search.h"
#undef TYPE
#define TYPE float
#include "sequential_search.h"
#undef TYPE
// etc.
最后,创建一个(静态可解析的)调用点,它将打开您拥有的类型 ID(运行时信息),然后立即分派(dispatch)到通用版本之一:
int sequential_search(int n, void* s, void* x, type_id) {
switch(type_id) {
case INT: return sequential_search_int(n, s, x);
case FLOAT: return sequential_search_float(n, s, x);
// etc.
}
}
关于c - 如何在 C 运行时以可在其余代码中使用的方式强制转换 void 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34404054/