我有一个带有qsort的签名的函数:
const char* get_str(int i, const void *base, size_t nmemb, size_t size);
我传递了指向const char*
的指针数组,或者第一个字段是const char*
指针的结构数组。
我需要做什么演员才能在数组元素i
中提取指针?
我已经尝试将base
转换为char本身的数组,因此我可以进入正确的元素:
return *(const char**)(((const char*)base)[i * size]);
但编译器抱怨:警告:从不同大小的整数转换为指针[-Wint-to-pointer-cast]
答案 0 :(得分:1)
看起来你想为结构体实现类型或识别系统,如下所示:
#include <stdlib.h>
#include <stdio.h>
struct a {
const char *id;
int x;
};
struct b {
const char *id;
double d;
};
union any {
struct a a;
struct b b;
};
int main()
{
struct a a[] = {{"one", 1}, {"two", 2}, {"three", 3}};
struct b b[] = {{"pi", 3.1415}, {"e", 2.71}};
union any any[3];
any[0].a = a[0];
any[1].b = b[0];
any[2].a = a[1];
puts(get_str(1, a, 3, sizeof(*a)));
puts(get_str(1, b, 2, sizeof(*b)));
puts(get_str(1, any, 3, sizeof(*any)));
return 0;
}
在这种情况下,以下工作:
const char* get_str(int i, const void *base, size_t nmemb, size_t size)
{
const char *p = base;
const char **pp = (const char**) (p + i * size);
return *pp;
}
这可以写成一行:
const char* get_str(int i, const void *base, size_t nmemb, size_t size)
{
return *(const char**) ((const char *) base + i * size);
}
但我认为通过无效指针绕行是没有必要的。您可以使用类型化数组进行地址计算:
puts(*(const char **) (&a[1]));
puts(*(const char **) (&b[1]));
puts(*(const char **) (&any[1]));
如果你把它包装在一个函数中:
const char *get_str(const void *str)
{
return *(const char **) str;
}
你得到:
puts(get_str(&a[1]));
puts(get_str(&b[1]));
puts(get_str(any + 1));
在我看来,比qsort
ish语法更具可读性。
这样可行,因为您只能访问已知位置的一个元素。但是,函数bsort
和qsort
不能使用这种技术,因为它们必须在多个索引处访问数组,因此必须能够自己进行索引计算。
答案 1 :(得分:0)
编译器是对的。此
*(const char**)(((const char*)base)[i * size]);
将类型编译为类似(语法:expresion -> type
)...
base -> const void*
(const char*)base -> (const char*)const void*
(((const char*)base)[i * size]) -> *(const char*)const void* -> const char // Here's the problem!
(const char**)(((const char*)base)[i * size]) -> (const char**)const char // Now, this is *not* good...
*(const char**)(((const char*)base)[i * size]) -> *(const char**)const char -> const char* // Well, we have now just perfectly dereferenced '~'...
不是很理智,不是吗?*
BTW :您没有向我们提供足够的信息来为您的问题提供完整的解决方案。你谈到的那些struct
是什么?
编辑:这可以帮助您(根据评论撰写)吗?
*(const char**)&(((const unsigned char*)base)[size * i])