我正在制作数据结构库。我允许用户拨打的一个功能是:
unsigned int index(struct myDataStructure, void* value);
它搜索我的数据结构并返回该值存在于其中的index
位置。
离。
{ 'A', 'D', 'C' }
char val1 = 'A';
unsigned int location = index(s, &val1); // location = 0
char val2 = 'C';
location = index(s, &val2); // location = 2
如果列表中不存在该元素,那么我不知道该返回什么。以下是我目前排除的选项:
Assert
或系统出口或例外来结束运行时。我不认为会有很多用处,因为在调用contains
index()
以确保元素在结构中
long
,以便我可以返回-1
。我不想切换数据类型。**unsigned int
,以便我可以将其指向NULL
(如果不存在)或实际索引值。对于阅读我的API以理解的人来说,这不是用户友好的。我有最好的解决方案:
// Change return type to pointer.
unsigned int* index(struct myDataStructure, void* value)
{
static int val;
if (value exists...)
{
val = correct index value
return &val;
}
else
{
return NULL;
}
}
但我仍觉得这个解决方案很差。
答案 0 :(得分:1)
你是对的,返回指向静态的指针在很多方面都很糟糕。它不是线程安全的,而且 - 更糟糕 - 它邀请用户做类似
之类的事情int *aIndexLoc = index(data, &a);
int *bIndexLoc = index(data, &b);
if (aIndexLoc && bIndexLoc)
printf ("a's loc is %u; b's loc is %u\n", *aIndexLoc, *bIndexLoc);
当然得到了错误的答案。
首先......如果您希望您的库能够面向未来,那么不要为数组索引返回unsigned。返回size_t
。
然后......有几个习惯用于处理错误返回。最常见的是返回int
或枚举错误代码作为函数值,并使用指针arg返回实际返回值。按照惯例,0
表示"好的"非零值是各种错误代码。此外,如果您的数据结构超过几个字节,请不要传递它的完整副本。传递指针
typedef int ERROR;
ERROR index(size_t *result, struct myDataStructure *myStruct, void *valueToFind);
从那以后:
size_t loc[1];
struct myDataStructure someData[1];
int aValue[1];
initialize(someData);
get(aValue);
ERROR error = index(loc, someData, aValue);
if (error) {
fprintf(stderr, "Couldn't find the value. Error code: %d\n", error);
return;
}
1元素数组是一个技巧,它允许您以相同的方式编码,无论对象是在堆栈还是堆上分配。您可以将数组的名称视为指针。例如。 someData->fieldName
和*loc
工作正常。
答案 1 :(得分:1)
几种可能性:
使用
返回错误(unsigned int) -1
unsigned int index(struct myDataStructure, void* value)
使用
返回错误-1
ssize_t index(struct myDataStructure, void* value)
(ssize_t
是POSIX)
传递unsigned int
的地址以指向结果,并在错误时返回-1
,并在成功时返回0
int index(struct myDataStructure, void* value, unsigned int * result)
使用
答案 2 :(得分:0)
您可以将指针传递给相应设置为bool
或true
的{{1}}。
false